@klever-one/web-sdk
Version:
Web SDK for integrating real-time room management and streaming functionality into web applications
1,115 lines • 436 kB
JavaScript
"use client";
var Fn = Object.defineProperty;
var Bt = (i) => {
throw TypeError(i);
};
var _n = (i, e, t) => e in i ? Fn(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
var c = (i, e, t) => _n(i, typeof e != "symbol" ? e + "" : e, t), zt = (i, e, t) => e.has(i) || Bt("Cannot " + t);
var x = (i, e, t) => (zt(i, e, "read from private field"), t ? t.call(i) : e.get(i)), st = (i, e, t) => e.has(i) ? Bt("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(i) : e.set(i, t), ve = (i, e, t, s) => (zt(i, e, "write to private field"), s ? s.call(i, t) : e.set(i, t), t);
const Ht = "initialData", Wt = "azureSttOpenai", Fe = "openai", Un = "occupyingResource";
const Gt = "openai", Bn = "X-Nlp-Api-Key", zn = "Pending", Hn = "Failed";
const Wn = {
1: "av_2",
// 차누
2: "av_5",
// 유리
3: "av_3",
// 크리스
4: "av_4",
// 마이클
5: "av_1"
// 제니
}, Gn = {
"en-US": "Introduce yourself in exactly 2–3 sentences. Do not exceed 3 sentences. Be concise and clear about your main role and how you can help.",
"ko-KR": "자신을 반드시 2~3문장으로만 간단히 소개해주세요. 3문장을 넘기지 말고, 주요 역할과 어떻게 도울 수 있는지만 간결하게 설명해주세요."
}, Vn = new Proxy(Gn, {
get(i, e) {
return typeof e == "string" && e in i ? i[e] : i["ko-KR"];
}
}), $n = 60 * 1e3;
var nt = { exports: {} }, Vt;
function Qn() {
return Vt || (Vt = 1, (function(i) {
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, r) => (r > 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 r = 8; r < s.length; r += 2)
switch (s[r]) {
case "raddr":
n.relatedAddress = s[r + 1];
break;
case "rport":
n.relatedPort = parseInt(s[r + 1], 10);
break;
case "tcptype":
n.tcpType = s[r + 1];
break;
case "ufrag":
n.ufrag = s[r + 1], n.usernameFragment = s[r + 1];
break;
default:
n[s[r]] === void 0 && (n[s[r]] = s[r + 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 r = t.type;
return s.push("typ"), s.push(r), r !== "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 r = t.substring(t.indexOf(" ") + 1).split(";");
for (let a = 0; a < r.length; a++)
n = r[a].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 r = [];
Object.keys(t.parameters).forEach((a) => {
t.parameters[a] !== void 0 ? r.push(a + "=" + t.parameters[a]) : r.push(a);
}), s += "a=fmtp:" + n + " " + r.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((r) => {
s += "a=rtcp-fb:" + n + " " + r.type + (r.parameter && r.parameter.length ? " " + r.parameter : "") + `\r
`;
}), s;
}, e.parseSsrcMedia = function(t) {
const s = t.indexOf(" "), n = {
ssrc: parseInt(t.substring(7, s), 10)
}, r = t.indexOf(":", s);
return r > -1 ? (n.attribute = t.substring(s + 1, r), n.value = t.substring(r + 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((r) => {
n += "a=fingerprint:" + r.algorithm + " " + r.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], r = e.matchPrefix(
t + s,
"a=ice-pwd:"
)[0];
return n && r ? {
usernameFragment: n.substring(12),
password: r.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: []
}, r = e.splitLines(t)[0].split(" ");
s.profile = r[2];
for (let l = 3; l < r.length; l++) {
const d = r[l], u = e.matchPrefix(
t,
"a=rtpmap:" + d + " "
)[0];
if (u) {
const m = e.parseRtpMap(u), p = e.matchPrefix(
t,
"a=fmtp:" + d + " "
);
switch (m.parameters = p.length ? e.parseFmtp(p[0]) : {}, m.rtcpFeedback = e.matchPrefix(
t,
"a=rtcp-fb:" + d + " "
).map(e.parseRtcpFb), s.codecs.push(m), m.name.toUpperCase()) {
case "RED":
case "ULPFEC":
s.fecMechanisms.push(m.name.toUpperCase());
break;
}
}
}
e.matchPrefix(t, "a=extmap:").forEach((l) => {
s.headerExtensions.push(e.parseExtmap(l));
});
const a = e.matchPrefix(t, "a=rtcp-fb:* ").map(e.parseRtcpFb);
return s.codecs.forEach((l) => {
a.forEach((d) => {
l.rtcpFeedback.find((m) => m.type === d.type && m.parameter === d.parameter) || l.rtcpFeedback.push(d);
});
}), 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((a) => a.preferredPayloadType !== void 0 ? a.preferredPayloadType : a.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((a) => {
n += e.writeRtpMap(a), n += e.writeFmtp(a), n += e.writeRtcpFb(a);
});
let r = 0;
return s.codecs.forEach((a) => {
a.maxptime > r && (r = a.maxptime);
}), r > 0 && (n += "a=maxptime:" + r + `\r
`), s.headerExtensions && s.headerExtensions.forEach((a) => {
n += e.writeExtmap(a);
}), n;
}, e.parseRtpEncodingParameters = function(t) {
const s = [], n = e.parseRtpParameters(t), r = n.fecMechanisms.indexOf("RED") !== -1, a = n.fecMechanisms.indexOf("ULPFEC") !== -1, l = e.matchPrefix(t, "a=ssrc:").map((S) => e.parseSsrcMedia(S)).filter((S) => S.attribute === "cname"), d = l.length > 0 && l[0].ssrc;
let u;
const m = e.matchPrefix(t, "a=ssrc-group:FID").map((S) => S.substring(17).split(" ").map((b) => parseInt(b, 10)));
m.length > 0 && m[0].length > 1 && m[0][0] === d && (u = m[0][1]), n.codecs.forEach((S) => {
if (S.name.toUpperCase() === "RTX" && S.parameters.apt) {
let C = {
ssrc: d,
codecPayloadType: parseInt(S.parameters.apt, 10)
};
d && u && (C.rtx = { ssrc: u }), s.push(C), r && (C = JSON.parse(JSON.stringify(C)), C.fec = {
ssrc: d,
mechanism: a ? "red+ulpfec" : "red"
}, s.push(C));
}
}), s.length === 0 && d && s.push({
ssrc: d
});
let p = e.matchPrefix(t, "b=");
return p.length && (p[0].indexOf("b=TIAS:") === 0 ? p = parseInt(p[0].substring(7), 10) : p[0].indexOf("b=AS:") === 0 ? p = parseInt(p[0].substring(5), 10) * 1e3 * 0.95 - 2e3 * 8 : p = void 0, s.forEach((S) => {
S.maxBitrate = p;
})), s;
}, e.parseRtcpParameters = function(t) {
const s = {}, n = e.matchPrefix(t, "a=ssrc:").map((l) => e.parseSsrcMedia(l)).filter((l) => l.attribute === "cname")[0];
n && (s.cname = n.value, s.ssrc = n.ssrc);
const r = e.matchPrefix(t, "a=rtcp-rsize");
s.reducedSize = r.length > 0, s.compound = r.length === 0;
const a = e.matchPrefix(t, "a=rtcp-mux");
return s.mux = a.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 r = e.matchPrefix(t, "a=ssrc:").map((a) => e.parseSsrcMedia(a)).filter((a) => a.attribute === "msid");
if (r.length > 0)
return s = r[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 r;
n.length > 0 && (r = parseInt(n[0].substring(19), 10)), isNaN(r) && (r = 65536);
const a = e.matchPrefix(t, "a=sctp-port:");
if (a.length > 0)
return {
port: parseInt(a[0].substring(12), 10),
protocol: s.fmt,
maxMessageSize: r
};
const l = e.matchPrefix(t, "a=sctpmap:");
if (l.length > 0) {
const d = l[0].substring(10).split(" ");
return {
port: parseInt(d[0], 10),
protocol: d[1],
maxMessageSize: r
};
}
}, 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 r;
const a = s !== void 0 ? s : 2;
return t ? r = t : r = e.generateSessionId(), `v=0\r
o=` + (n || "thisisadapterortc") + " " + r + " " + a + ` 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 r = 0; r < n.length; r++)
switch (n[r]) {
case "a=sendrecv":
case "a=sendonly":
case "a=recvonly":
case "a=inactive":
return n[r].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;
}, i.exports = e;
})(nt)), nt.exports;
}
var $t = /* @__PURE__ */ Qn(), H, I, Ve = { d: (i, e) => {
for (var t in e) Ve.o(e, t) && !Ve.o(i, t) && Object.defineProperty(i, t, { enumerable: !0, get: e[t] });
}, o: (i, e) => Object.prototype.hasOwnProperty.call(i, e) }, W = {};
Ve.d(W, { Dz: () => sn, g$: () => Rs, Lt: () => Ts, Q9: () => ws, qf: () => ft, hV: () => ln, z$: () => Bi, J0: () => vt, De: () => ui, $C: () => de, al: () => Ds, _W: () => Ns, Gv: () => qs, m: () => Xs, tz: () => Os, Nu: () => an, zg: () => hn, vp: () => tn, vU: () => h, wF: () => Vs, rv: () => nn, Nh: () => rn, ss: () => dn, qW: () => Js, QL: () => js, cf: () => mn, eM: () => Gs, Yd: () => o, Tk: () => f, iM: () => Cs, qy: () => j, ce: () => si, sK: () => g, Ok: () => w, q5: () => on, g: () => Ui, xl: () => Hs, I: () => Ws, bx: () => St, dD: () => Zs, Ib: () => Oe, Az: () => k, Iw: () => G, qY: () => pt, db: () => bs, mR: () => Ee, Tn: () => gt, rV: () => $s, gh: () => _s, Mi: () => Us, j: () => Bs, YB: () => zs, Yt: () => Ks, i5: () => Qs, x_: () => Q, Am: () => yt, eR: () => Ms, r8: () => Fs, u3: () => un, vd: () => Is, iV: () => As, jZ: () => Ps, SW: () => xs, ZH: () => Ls, Ni: () => gn, lh: () => ks, ZP: () => en, bq: () => Es, $f: () => pn, eu: () => Ys, Ax: () => oi, Mc: () => ai });
class o {
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}`;
}
}
o.verboseLogLevel = 5, (function(i) {
i.LIST_STREAMERS = "listStreamers", i.SUBSCRIBE = "subscribe", i.UNSUBSCRIBE = "unsubscribe", i.ICE_CANDIDATE = "iceCandidate", i.OFFER = "offer", i.ANSWER = "answer", i.DATACHANNELREQUEST = "dataChannelRequest", i.SFURECVDATACHANNELREADY = "peerDataChannelsReady", i.PONG = "pong";
})(H || (H = {}));
let j = class {
sendFilter(e, t) {
return t;
}
payload() {
return o.Log(o.GetStackTrace(), `Sending =>
` + JSON.stringify(this, this.sendFilter, 4), 6), JSON.stringify(this, this.sendFilter);
}
}, Kn = class extends j {
constructor() {
super(), this.type = H.LIST_STREAMERS;
}
}, jn = class extends j {
constructor(e) {
super(), this.type = H.SUBSCRIBE, this.streamerId = e;
}
}, qn = class extends j {
constructor() {
super(), this.type = H.UNSUBSCRIBE;
}
}, Xn = class extends j {
constructor(e) {
super(), this.type = H.PONG, this.time = e;
}
}, Jn = class extends j {
constructor(e, t) {
super(), this.type = H.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;
}
}, Yn = class extends j {
constructor(e, t) {
super(), this.type = H.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;
}
}, Zn = class extends j {
constructor() {
super(), this.type = H.DATACHANNELREQUEST;
}
}, ei = class extends j {
constructor() {
super(), this.type = H.SFURECVDATACHANNELREADY;
}
}, ti = class {
constructor(e) {
this.type = H.ICE_CANDIDATE, this.candidate = e;
}
payload() {
return o.Log(o.GetStackTrace(), `Sending =>
` + JSON.stringify(this, void 0, 4), 6), JSON.stringify(this);
}
};
(function(i) {
i.CONFIG = "config", i.STREAMER_LIST = "streamerList", i.STREAMER_ID_CHANGED = "streamerIDChanged", i.PLAYER_COUNT = "playerCount", i.OFFER = "offer", i.ANSWER = "answer", i.ICE_CANDIDATE = "iceCandidate", i.PEER_DATA_CHANNELS = "peerDataChannels", i.PING = "ping", i.WARNING = "warning";
})(I || (I = {}));
let Cs = class {
}, si = class extends Cs {
}, gt = 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) : o.Error(o.GetStackTrace(), `Message type of ${e} does not have a message handler registered on the frontend - ignoring message.`);
}
static setupDefaultHandlers(e) {
e.signallingProtocol.addMessageHandler(I.PING, ((t) => {
const s = new Xn((/* @__PURE__ */ new Date()).getTime()).payload();
o.Log(o.GetStackTrace(), I.PING + ": " + t, 6), e.webSocket.send(s);
})), e.signallingProtocol.addMessageHandler(I.CONFIG, ((t) => {
o.Log(o.GetStackTrace(), I.CONFIG, 6);
const s = JSON.parse(t);
e.onConfig(s);
})), e.signallingProtocol.addMessageHandler(I.STREAMER_LIST, ((t) => {
o.Log(o.GetStackTrace(), I.STREAMER_LIST, 6);
const s = JSON.parse(t);
e.onStreamerList(s);
})), e.signallingProtocol.addMessageHandler(I.STREAMER_ID_CHANGED, ((t) => {
o.Log(o.GetStackTrace(), I.STREAMER_ID_CHANGED, 6);
const s = JSON.parse(t);
e.onStreamerIDChanged(s);
})), e.signallingProtocol.addMessageHandler(I.PLAYER_COUNT, ((t) => {
o.Log(o.GetStackTrace(), I.PLAYER_COUNT, 6);
const s = JSON.parse(t);
o.Log(o.GetStackTrace(), "Player Count: " + s.count, 6), e.onPlayerCount(s);
})), e.signallingProtocol.addMessageHandler(I.ANSWER, ((t) => {
o.Log(o.GetStackTrace(), I.ANSWER, 6);
const s = JSON.parse(t);
e.onWebRtcAnswer(s);
})), e.signallingProtocol.addMessageHandler(I.OFFER, ((t) => {
o.Log(o.GetStackTrace(), I.OFFER, 6);
const s = JSON.parse(t);
e.onWebRtcOffer(s);
})), e.signallingProtocol.addMessageHandler(I.ICE_CANDIDATE, ((t) => {
o.Log(o.GetStackTrace(), I.ICE_CANDIDATE, 6);
const s = JSON.parse(t);
e.onIceCandidate(s.candidate);
})), e.signallingProtocol.addMessageHandler(I.WARNING, ((t) => {
o.Warning(o.GetStackTrace(), `Warning received: ${t}`);
})), e.signallingProtocol.addMessageHandler(I.PEER_DATA_CHANNELS, ((t) => {
o.Log(o.GetStackTrace(), I.PEER_DATA_CHANNELS, 6);
const s = JSON.parse(t);
e.onWebRtcPeerDataChannels(s);
}));
}
}, Es = class {
constructor() {
this.WS_OPEN_STATE = 1, this.onOpen = new EventTarget(), this.onClose = new EventTarget(), this.signallingProtocol = new gt(), gt.setupDefaultHandlers(this);
}
connect(e) {
o.Log(o.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 o.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) => {
o.Error(o.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);
o.Log(o.GetStackTrace(), `received =>
` + JSON.stringify(JSON.parse(e.data), void 0, 4), 6), this.signallingProtocol.handleMessage(t.type, e.data);
}
handleOnOpen(e) {
o.Log(o.GetStackTrace(), "Connected to the signalling server via WebSocket", 6), this.onOpen.dispatchEvent(new Event("open"));
}
handleOnError() {
o.Error(o.GetStackTrace(), "WebSocket error");
}
handleOnClose(e) {
o.Log(o.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 Kn();
this.webSocket.send(e.payload());
}
sendSubscribe(e) {
const t = new jn(e);
this.webSocket.send(t.payload());
}
sendUnsubscribe() {
const e = new qn();
this.webSocket.send(e.payload());
}
sendWebRtcOffer(e, t) {
const s = new Jn(e, t);
this.webSocket.send(s.payload());
}
sendWebRtcAnswer(e, t) {
const s = new Yn(e, t);
this.webSocket.send(s.payload());
}
sendWebRtcDatachannelRequest() {
const e = new Zn();
this.webSocket.send(e.payload());
}
sendSFURecvDataChannelReady() {
const e = new ei();
this.webSocket.send(e.payload());
}
sendIceCandidate(e) {
if (o.Log(o.GetStackTrace(), "Sending Ice Candidate"), this.webSocket && this.webSocket.readyState === this.WS_OPEN_STATE) {
const t = new ti(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) {
}
}, ni = class {
constructor(e) {
this.videoElementProvider = e, this.audioElement = document.createElement("Audio"), this.videoElementProvider.setAudioElement(this.audioElement);
}
handleOnTrack(e) {
if (o.Log(o.GetStackTrace(), "handleOnTrack " + JSON.stringify(e.streams), 6), e.track.id == "probator") return;
const t = this.videoElementProvider.getVideoElement();
if (e.track && o.Log(o.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 o.Log(o.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, o.Log(o.GetStackTrace(), "Created new audio element to play separate audio stream."));
}
}, ii = class {
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 r = this.rootDiv.clientWidth / this.rootDiv.clientHeight, a = this.freezeFrameWidth / this.freezeFrameHeight;
r < a ? (e = this.rootDiv.clientWidth, t = Math.floor(this.rootDiv.clientWidth / a), s = Math.floor(0.5 * (this.rootDiv.clientHeight - t)), n = 0) : (e = Math.floor(this.rootDiv.clientHeight * a), 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";
}
}
}, ri = class {
constructor(e) {
this.receiving = !1, this.size = 0, this.jpeg = void 0, this.valid = !1, this.freezeFrameDelay = 50, this.freezeFrame = new ii(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, o.Log(o.GetStackTrace(), `received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`, 6);
this.jpeg.length === this.size ? (this.receiving = !1, this.valid = !0, o.Log(o.GetStackTrace(), `received complete freeze frame ${this.size}`, 6), this.updateFreezeFrameAndShow(this.jpeg, t)) : this.jpeg.length > this.size && (o.Error(o.GetStackTrace(), `received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`), this.jpeg = void 0, this.receiving = !1);
}
}, Oe = class {
constructor(e, t, s, n, r = (() => {
})) {
this.onChange = r, 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);
}
}, k = class extends Oe {
constructor(e, t, s, n, r, a = (() => {
})) {
super(e, t, s, n, a);
const l = new URLSearchParams(window.location.search);
if (r && l.has(this.id)) {
const d = this.getUrlParamFlag();
this.flag = d;
} else this.flag = n;
this.useUrlParams = r;
}
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;
}
}, G = class extends Oe {
constructor(e, t, s, n, r, a, l, d = (() => {
})) {
super(e, t, s, a, d), this._min = n, this._max = r;
const u = new URLSearchParams(window.location.search);
if (l && u.has(this.id)) {
const m = Number.parseFloat(u.get(this.id));
this.number = Number.isNaN(m) ? a : m;
} else this.number = a;
this.useUrlParams = l;
}
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;
}
}, bs = class extends Oe {
constructor(e, t, s, n, r, a = (() => {
})) {
super(e, t, s, n, a);
const l = new URLSearchParams(window.location.search);
if (r && l.has(this.id)) {
const d = this.getUrlParamText();
this.text = d;
} else this.text = n;
this.useUrlParams = r;
}
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;
}
}, pt = class extends Oe {
constructor(e, t, s, n, r, a, l = (() => {
})) {
super(e, t, s, n, l), this.options = r;
const d = new URLSearchParams(window.location.search), u = a && d.has(this.id) ? this.getUrlParamText() : n;
this.selected = u, this.useUrlParams = a;
}
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]));
}
}, Ts = class extends Event {
constructor(e) {
super("afkWarningActivate"), this.data = e;
}
}, ft = class extends Event {
constructor(e) {
super("afkWarningUpdate"), this.data = e;
}
}, ws = class extends Event {
constructor() {
super("afkWarningDeactivate");
}
}, Rs = class extends Event {
constructor() {
super("afkTimedOut");
}
}, Ms = class extends Event {
constructor(e) {
super("videoEncoderAvgQP"), this.data = e;
}
}, ks = class extends Event {
constructor() {
super("webRtcSdp");
}
}, Is = class extends Event {
constructor() {
super("webRtcAutoConnect");
}
}, Ps = class extends Event {
constructor() {
super("webRtcConnecting");
}
}, As = class extends Event {
constructor() {
super("webRtcConnected");
}
};
class Ls extends Event {
constructor() {
super("webRtcFailed");
}
}
let xs = class extends Event {
constructor(e) {
super("webRtcDisconnected"), this.data = e;
}
}, Os = class extends Event {
constructor(e) {
super("dataChannelOpen"), this.data = e;
}
}, Ds = class extends Event {
constructor(e) {
super("dataChannelClose"), this.data = e;
}
};
class Ns extends Event {
constructor(e) {
super("dataChannelError"), this.data = e;
}
}
let Fs = class extends Event {
constructor() {
super("videoInitialized");
}
}, _s = class extends Event {
constructor() {
super("streamLoading");
}
}, Us = class extends Event {
constructor() {
super("streamConnect");
}
};
class Bs extends Event {
constructor() {
super("streamDisconnect");
}
}
let zs = class extends Event {
constructor() {
super("streamReconnect");
}
}, Hs = class extends Event {
constructor(e) {
super("playStreamError"), this.data = e;
}
};
class Ws extends Event {
constructor() {
super("playStream");
}
}
let St = class extends Event {
constructor(e) {
super("playStreamRejected"), this.data = e;
}
}, Gs = class extends Event {
constructor(e) {
super("loadFreezeFrame"), this.data = e;
}
}, Vs = class extends Event {
constructor() {
super("hideFreezeFrame");
}
};
class $s extends Event {
constructor(e) {
super("statsReceived"), this.data = e;
}
}
let Qs = class extends Event {
constructor(e) {
super("streamerListMessage"), this.data = e;
}
};
class Ks extends Event {
constructor(e) {
super("StreamerIDChangedMessage"), this.data = e;
}
}
class js extends Event {
constructor(e) {
super("latencyTestResult"), this.data = e;
}
}
class qs extends Event {
constructor(e) {
super("dataChannelLatencyTestResponse"), this.data = e;
}
}
class Xs extends Event {
constructor(e) {
super("dataChannelLatencyTestResult"), this.data = e;
}
}
class Js extends Event {
constructor(e) {
super("initialSettings"), this.data = e;
}
}
class Ee extends Event {
constructor(e) {
super("settingsChanged"), this.data = e;
}
}
class ai extends Event {
constructor() {
super("xrSessionStarted");
}
}
class oi extends Event {
constructor() {
super("xrSessionEnded");
}
}
class Ys extends Event {
constructor(e) {
super("xrFrame"), this.data = e;
}
}
class Zs extends Event {
constructor(e) {
super("playerCount"), this.data = e;
}
}
class en extends Event {
constructor() {
super("webRtcTCPRelayDetected");
}
}
class tn extends EventTarget {
dispatchEvent(e) {
return super.dispatchEvent(e);
}
addEventListener(e, t) {
super.addEventListener(e, t);
}
removeEventListener(e, t) {
super.removeEventListener(e, t);
}
}
class h {
}
h.AutoConnect = "AutoConnect", h.AutoPlayVideo = "AutoPlayVideo", h.AFKDetection = "TimeoutIfIdle", h.BrowserSendOffer = "OfferToReceive", h.HoveringMouseMode = "HoveringMouse", h.ForceMonoAudio = "ForceMonoAudio", h.ForceTURN = "ForceTURN", h.FakeMouseWithTouches = "FakeMouseWithTouches", h.IsQualityController = "ControlsQuality", h.MatchViewportResolution = "MatchViewportRes", h.StartVideoMuted = "StartVideoMuted", h.SuppressBrowserKeys = "SuppressBrowserKeys", h.UseMic = "UseMic", h.KeyboardInput = "KeyboardInput", h.MouseInput = "MouseInput", h.TouchInput = "TouchInput", h.GamepadInput = "GamepadInput", h.XRControllerInput = "XRControllerInput", h.WaitForStreamer = "WaitForStreamer", h.HideUI = "HideUI";
const li = (i) => Object.getOwnPropertyNames(h).some(((e) => h[e] === i));
class g {
}
g.AFKTimeoutSecs = "AFKTimeout", g.AFKCountdownSecs = "AFKCountdown", g.MinQP = "MinQP", g.MaxQP = "MaxQP", g.WebRTCFPS = "WebRTCFPS", g.WebRTCMinBitrate = "WebRTCMinBitrate", g.WebRTCMaxBitrate = "WebRTCMaxBitrate", g.MaxReconnectAttempts = "MaxReconnectAttempts", g.StreamerAutoJoinInterval = "StreamerAutoJoinInterval";
const ci = (i) => Object.getOwnPropertyNames(g).some(((e) => g[e] === i));
class Q {
}
Q.SignallingServerUrl = "ss";
const di = (i) => Object.getOwnPropertyNames(Q).some(((e) => Q[e] === i));
class w {
}
w.PreferredCodec = "PreferredCodec", w.StreamerId = "StreamerId";
const hi = (i) => Object.getOwnPropertyNames(w).some(((e) => w[e] === i));
class ui {
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(Q.SignallingServerUrl, new bs(Q.SignallingServerUrl, "Signalling url", "Url of the signalling server", t && t.hasOwnProperty(Q.SignallingServerUrl) ? t[Q.SignallingServerUrl] : (location.protocol === "https:" ? "wss://" : "ws://") + window.location.hostname + (window.location.port === "80" || window.location.port === "" ? "" : `:${window.location.port}`), e)), this.optionParameters.set(w.StreamerId, new pt(w.StreamerId, "Streamer ID", "The ID of the streamer to stream.", t && t.hasOwnProperty(w.StreamerId) ? t[w.StreamerId] : "", [], e)), this.optionParameters.set(w.PreferredCodec, new pt(w.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(w.PreferredCodec) ? [t[w.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(((r) => {
const a = r.mimeType.split("/")[1] + " " + (r.sdpFmtpLine || "");
n.exec(a) !== null && s.push(a);
})), s;
})(), e)), this.flags.set(h.AutoConnect, new k(h.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(h.AutoConnect)) && t[h.AutoConnect], e)), this.flags.set(h.AutoPlayVideo, new k(h.AutoPlayVideo, "Auto play video", "When video is ready automatically start playing it as opposed to showing a play button.", !t || !t.hasOwnProperty(h.AutoPlayVideo) || t[h.AutoPlayVideo], e)), this.flags.set(h.BrowserSendOffer, new k(h.BrowserSendOffer, "Browser send offer", "Browser will initiate the WebRTC handshake by sending the offer to the streamer", !(!t || !t.hasOwnProperty(h.BrowserSendOffer)) && t[h.BrowserSendOffer], e)), this.flags.set(h.UseMic, new k(h.UseMic, "Use microphone", "Make browser request microphone access and open an input audio track.", !(!t || !t.hasOwnProperty(h.UseMic)) && t[h.UseMic], e)), this.flags.set(h.StartVideoMuted, new k(h.StartVideoMuted, "Start video muted", "Video will start muted if true.", !(!t || !t.hasOwnProperty(h.StartVideoMuted)) && t[h.StartVideoMuted], e)), this.flags.set(h.SuppressBrowserKeys, new k(h.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(h.SuppressBrowserKeys) || t[h.SuppressBrowserKeys], e)), this.flags.set(h.IsQualityController, new k(h.IsQualityController, "Is quality controller?", "True if this peer controls stream quality", !t || !t.hasOwnProperty(h.IsQualityController) || t[h.IsQualityController], e)), this.flags.set(h.ForceMonoAudio, new k(h.ForceMonoAudio, "Force mono audio", "Force browser to request mono audio in the SDP", !(!t || !t.hasOwnProperty(h.ForceMonoAudio)) && t[h.ForceMonoAudio], e)), this.flags.set(h.ForceTURN, new k(h.ForceTURN, "Force TURN", "Only generate TURN/Relayed ICE candidates.", !(!t || !t.hasOwnProperty(h.ForceTURN)) && t[h.ForceTURN], e)), this.flags.set(h.AFKDetection, new k(h.AFKDetection, "AFK if idle", "Timeout the experience if user is AFK for a period.", !(!t || !t.hasOwnProperty(h.AFKDetection)) && t[h.AFKDetection], e)), this.flags.set(h.MatchViewportResolution, new k(h.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(h.MatchViewportResolution)) && t[h.MatchViewportResolution], e)), this.flags.set(h.HoveringMouseMode, new k(h.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(h.HoveringMouseMode)) && t[h.HoveringMouseMode], e, ((s, n) => {
n.label = `Control Scheme: ${s ? "Hovering" : "Locked"} Mouse`;
}))), this.flags.set(h.FakeMouseWithTouches, new k(h.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(h.FakeMouseWithTouches)) && t[h.FakeMouseWithTouches], e)), this.flags.set(h.KeyboardInput, new k(h.KeyboardInput, "Keyboard input", "If enabled, send keyboard events to streamer", !t || !t.hasOwnProperty(h.KeyboardInput) || t[h.KeyboardInput], e)), this.flags.set(h.MouseInput, new k(h.MouseInput, "Mouse input", "If enabled, send mouse events to streamer", !t || !t.hasOwnProperty(h.MouseInput) || t[h.MouseInput], e)), this.flags.set(h.TouchInput, new k(h.TouchInput, "Touch input", "If enabled, send touch events to streamer", !t || !t.hasOwnProperty(h.TouchInput) || t[h.TouchInput], e)), this.flags.set(h.GamepadInput, new k(h.GamepadInput, "Gamepad input", "If enabled, send gamepad events to streamer", !t || !t.hasOwnProperty(h.GamepadInput) || t[h.GamepadInput], e)), this.flags.set(h.XRControllerInput, new k(h.XRControllerInput, "XR controller input", "If enabled, send XR controller events to streamer", !t || !t.hasOwnProperty(h.XRControllerInput) || t[h.XRControllerInput], e)), this.flags.set(h.WaitForStreamer, new k(h.WaitForStreamer, "Wait for streamer", "Will continue trying to connect to the first streamer available.", !t || !t.hasOwnProperty(h.WaitForStreamer) || t[h.WaitForStreamer], e)), this.flags.set(h.HideUI, new k(h.HideUI, "Hide the UI overlay", "Will hide all UI overlay details", !(!t || !t.hasOwnProperty(h.HideUI)) && t[h.HideUI], e)), this.numericParameters.set(g.AFKTimeoutSecs, new G(g.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(g.AFKTimeoutSecs) ? t[g.AFKTimeoutSecs] : 120, e)), this.numericParameters.set(g.AFKCountdownSecs, new G(g.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(g.MaxReconnectAttempts, new G(g.MaxReconnectAttempts, "Max Reconnects", "Maximum number of reconnects the application will attempt when a streamer disconnects.", 0, 999, t && t.hasOwnProperty(g.MaxReconnectAttempts) ? t[g.MaxReconnectAttempts] : 3, e)), this.numericParameters.set(g.MinQP, new G(g.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(g.MinQP) ? t[g.MinQP] : 0, e)), this.numericParameters.set(g.MaxQP, new G(g.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(g.MaxQP) ? t[g.MaxQP] : 51, e)), this.numericParameters.set(g.WebRTCFPS, new G(g.WebRTCFPS, "Max FPS", "The maximum FPS that WebRTC will try to transmit frames at.", 1, 999, t && t.hasOwnProperty(g.WebRTCFPS) ? t[g.WebRTCFPS] : 60, e)), this.numericParameters.set(g.WebRTCMinBitrate, new G(g.WebRTCMinBitrate, "Min Bitrate (kbps)", "The minimum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(g.WebRTCMinBitrate) ? t[g.WebRTCMinBitrate] : 0, e)), this.numericParameters.set(g.WebRTCMaxBitrate, new G(g.WebRTCMaxBitrate, "Max Bitrate (kbps)", "The maximum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(g.WebRTCMaxBitrate) ? t[g.WebRTCMaxBitrate] : 0, e)), this.numericParameters.set(g.StreamerAutoJoinInterval, new G(g.StreamerAutoJoinInterval, "Streamer Auto Join Interval (ms)", "Delay between retries when waiting for an available streamer.", 500, 9e5, t && t.hasOwnProperty(g.StreamerAutoJoinInterval) ? t[g.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 : o.Warning(o.GetStackTrace(), `Cannot toggle flag called ${e} -