@eyepop.ai/eyepop 0.12.0 → 0.13.0
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/README.md +15 -5
- package/dist/eyepop.min.js +1 -1
- package/dist/index.d.mts +30 -19
- package/dist/index.d.ts +30 -19
- package/dist/index.js +416 -274
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +416 -274
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -9054,7 +9054,7 @@ var LoadLiveIngressJob = class extends AbstractJob {
|
|
|
9054
9054
|
"Accept": "application/jsonl",
|
|
9055
9055
|
"Content-Type": "application/json"
|
|
9056
9056
|
};
|
|
9057
|
-
const patchUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=
|
|
9057
|
+
const patchUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=preempt&processing=sync`;
|
|
9058
9058
|
this._requestLogger.debug("before PATCH %s with url %s as source", patchUrl, this._ingressId);
|
|
9059
9059
|
const response = await this._client.fetch(patchUrl, {
|
|
9060
9060
|
headers,
|
|
@@ -9283,17 +9283,91 @@ function v4(options, buf, offset) {
|
|
|
9283
9283
|
}
|
|
9284
9284
|
var v4_default = v4;
|
|
9285
9285
|
|
|
9286
|
-
// src/
|
|
9287
|
-
var
|
|
9288
|
-
constructor(getSession, client, requestLogger) {
|
|
9289
|
-
this._pc = null;
|
|
9286
|
+
// src/webrtc_base.ts
|
|
9287
|
+
var WebrtcBase = class _WebrtcBase {
|
|
9288
|
+
constructor(getSession, client, ingressId, urlBasePath, requestLogger) {
|
|
9290
9289
|
this._getSession = getSession;
|
|
9291
9290
|
this._client = client;
|
|
9292
9291
|
this._requestLogger = requestLogger;
|
|
9292
|
+
this._ingressId = ingressId;
|
|
9293
|
+
this._urlPath = `${urlBasePath}/${this._ingressId}`;
|
|
9294
|
+
this._pc = null;
|
|
9293
9295
|
this._eTag = "";
|
|
9294
9296
|
this._queuedCandidates = [];
|
|
9295
9297
|
this._offerData = null;
|
|
9296
9298
|
}
|
|
9299
|
+
async close() {
|
|
9300
|
+
const pc = this._pc;
|
|
9301
|
+
this._pc = null;
|
|
9302
|
+
if (pc) {
|
|
9303
|
+
return pc.close();
|
|
9304
|
+
}
|
|
9305
|
+
}
|
|
9306
|
+
ingressId() {
|
|
9307
|
+
return this._ingressId;
|
|
9308
|
+
}
|
|
9309
|
+
async onLocalOffer(offer) {
|
|
9310
|
+
if (!this._pc) {
|
|
9311
|
+
throw new Error("onLocalOffer no peer connection");
|
|
9312
|
+
}
|
|
9313
|
+
if (!offer.sdp) {
|
|
9314
|
+
throw new Error("onLocalOffer no sdp");
|
|
9315
|
+
}
|
|
9316
|
+
this._offerData = _WebrtcBase.parseOffer(offer.sdp);
|
|
9317
|
+
await this._pc.setLocalDescription(offer);
|
|
9318
|
+
const session = await this._getSession();
|
|
9319
|
+
const ingressUrl = new URL(this._urlPath, session.baseUrl);
|
|
9320
|
+
this._requestLogger.debug("before POST: %s", ingressUrl);
|
|
9321
|
+
const headers = {
|
|
9322
|
+
"Authorization": `Bearer ${session.accessToken}`,
|
|
9323
|
+
"Content-Type": "application/sdp"
|
|
9324
|
+
};
|
|
9325
|
+
const response = await this._client.fetch(ingressUrl, {
|
|
9326
|
+
headers,
|
|
9327
|
+
method: "POST",
|
|
9328
|
+
body: offer.sdp
|
|
9329
|
+
});
|
|
9330
|
+
if (response.status != 201) {
|
|
9331
|
+
return Promise.reject(`unknown status code for POST '${ingressUrl}': ${response.status} (${response.statusText})`);
|
|
9332
|
+
}
|
|
9333
|
+
this._eTag = response.headers.get("ETag") ?? "";
|
|
9334
|
+
return this.onRemoteAnswer(new RTCSessionDescription({
|
|
9335
|
+
type: "answer",
|
|
9336
|
+
sdp: await response.text()
|
|
9337
|
+
}));
|
|
9338
|
+
}
|
|
9339
|
+
async sendLocalCandidates(candidates) {
|
|
9340
|
+
if (!this._offerData) {
|
|
9341
|
+
throw new Error("sendLocalCandidates no offerData");
|
|
9342
|
+
}
|
|
9343
|
+
const session = await this._getSession();
|
|
9344
|
+
const ingressUrl = new URL(this._urlPath, session.baseUrl);
|
|
9345
|
+
this._requestLogger.debug("before PATCH: %s", ingressUrl);
|
|
9346
|
+
const headers = {
|
|
9347
|
+
"Authorization": `Bearer ${session.accessToken}`,
|
|
9348
|
+
"Content-Type": "application/trickle-ice-sdpfrag",
|
|
9349
|
+
"If-Match": this._eTag
|
|
9350
|
+
};
|
|
9351
|
+
const response = await this._client.fetch(ingressUrl, {
|
|
9352
|
+
headers,
|
|
9353
|
+
method: "PATCH",
|
|
9354
|
+
body: _WebrtcBase.generateSdpFragment(this._offerData, candidates)
|
|
9355
|
+
});
|
|
9356
|
+
if (response.status != 204) {
|
|
9357
|
+
return Promise.reject(`unknown status code for PATCH '${ingressUrl}': ${response.status} (${response.statusText})`);
|
|
9358
|
+
}
|
|
9359
|
+
return this;
|
|
9360
|
+
}
|
|
9361
|
+
async onLocalCandidate(evt) {
|
|
9362
|
+
if (evt.candidate !== null) {
|
|
9363
|
+
if (this._eTag === "") {
|
|
9364
|
+
this._queuedCandidates.push(evt.candidate);
|
|
9365
|
+
} else {
|
|
9366
|
+
await this.sendLocalCandidates([evt.candidate]);
|
|
9367
|
+
}
|
|
9368
|
+
}
|
|
9369
|
+
return this;
|
|
9370
|
+
}
|
|
9297
9371
|
static linkToIceServers(links) {
|
|
9298
9372
|
const servers = links !== null ? links.split(", ").map((link) => {
|
|
9299
9373
|
const m = link.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i);
|
|
@@ -9302,8 +9376,8 @@ var WebRtcBase = class {
|
|
|
9302
9376
|
}
|
|
9303
9377
|
const iceServer = {
|
|
9304
9378
|
urls: [m[1]],
|
|
9305
|
-
username:
|
|
9306
|
-
credential:
|
|
9379
|
+
username: WebrtcWhip.unquoteCredential(m[3]),
|
|
9380
|
+
credential: WebrtcWhip.unquoteCredential(m[4])
|
|
9307
9381
|
// credentialType: m[3]? "password" : undefined
|
|
9308
9382
|
};
|
|
9309
9383
|
return iceServer;
|
|
@@ -9317,9 +9391,9 @@ var WebRtcBase = class {
|
|
|
9317
9391
|
for (let i = 0; i < sections.length; i++) {
|
|
9318
9392
|
const section = sections[i];
|
|
9319
9393
|
if (section.startsWith("video")) {
|
|
9320
|
-
sections[i] =
|
|
9394
|
+
sections[i] = WebrtcWhip.setVideoBitrate(WebrtcWhip.setCodec(section, videoCodec), videoBitrate);
|
|
9321
9395
|
} else if (section.startsWith("audio")) {
|
|
9322
|
-
sections[i] =
|
|
9396
|
+
sections[i] = WebrtcWhip.setAudioBitrate(WebrtcWhip.setCodec(section, audioCodec), audioBitrate, audioVoice);
|
|
9323
9397
|
}
|
|
9324
9398
|
}
|
|
9325
9399
|
return sections.join("m=");
|
|
@@ -9441,22 +9515,15 @@ var WebRtcBase = class {
|
|
|
9441
9515
|
}
|
|
9442
9516
|
};
|
|
9443
9517
|
|
|
9444
|
-
// src/
|
|
9445
|
-
var
|
|
9518
|
+
// src/webrtc_whip.ts
|
|
9519
|
+
var WebrtcWhip = class _WebrtcWhip extends WebrtcBase {
|
|
9446
9520
|
constructor(stream, getSession, client, requestLogger) {
|
|
9447
|
-
super(getSession, client, requestLogger);
|
|
9448
|
-
this._ingressId = v4_default().toString();
|
|
9521
|
+
super(getSession, client, v4_default().toString(), "/liveIngress/whip", requestLogger);
|
|
9449
9522
|
this._stream = stream;
|
|
9450
9523
|
}
|
|
9451
|
-
ingressId() {
|
|
9452
|
-
if (!this._ingressId) {
|
|
9453
|
-
throw new Error("not initialized");
|
|
9454
|
-
}
|
|
9455
|
-
return this._ingressId;
|
|
9456
|
-
}
|
|
9457
9524
|
async start() {
|
|
9458
9525
|
const session = await this._getSession();
|
|
9459
|
-
const ingressUrl = new URL(
|
|
9526
|
+
const ingressUrl = new URL(this._urlPath, session.baseUrl);
|
|
9460
9527
|
this._requestLogger.debug("before GET: %s", ingressUrl);
|
|
9461
9528
|
const headers = {
|
|
9462
9529
|
"Authorization": `Bearer ${session.accessToken}`
|
|
@@ -9470,13 +9537,42 @@ var Whip = class _Whip extends WebRtcBase {
|
|
|
9470
9537
|
}
|
|
9471
9538
|
return this.onIceServers(response);
|
|
9472
9539
|
}
|
|
9540
|
+
async stream() {
|
|
9541
|
+
if (this._stream) {
|
|
9542
|
+
return Promise.resolve(this._stream);
|
|
9543
|
+
} else {
|
|
9544
|
+
return Promise.reject("fetching stream failed");
|
|
9545
|
+
}
|
|
9546
|
+
}
|
|
9547
|
+
async onRemoteAnswer(answer) {
|
|
9548
|
+
if (!this._pc) {
|
|
9549
|
+
throw new Error("onLocalOffer no peer connection");
|
|
9550
|
+
}
|
|
9551
|
+
answer = new RTCSessionDescription({
|
|
9552
|
+
type: "answer",
|
|
9553
|
+
sdp: _WebrtcWhip.editAnswer(
|
|
9554
|
+
answer.sdp,
|
|
9555
|
+
"h264/90000",
|
|
9556
|
+
void 0,
|
|
9557
|
+
5e3,
|
|
9558
|
+
void 0,
|
|
9559
|
+
true
|
|
9560
|
+
)
|
|
9561
|
+
});
|
|
9562
|
+
await this._pc.setRemoteDescription(new RTCSessionDescription(answer));
|
|
9563
|
+
if (this._queuedCandidates.length !== 0) {
|
|
9564
|
+
await this.sendLocalCandidates(this._queuedCandidates);
|
|
9565
|
+
this._queuedCandidates = [];
|
|
9566
|
+
}
|
|
9567
|
+
return this;
|
|
9568
|
+
}
|
|
9473
9569
|
async onIceServers(response) {
|
|
9474
9570
|
if (!this._stream) {
|
|
9475
9571
|
throw new Error("onIceServers no stream");
|
|
9476
9572
|
}
|
|
9477
9573
|
const stream = this._stream;
|
|
9478
9574
|
const pc = new RTCPeerConnection({
|
|
9479
|
-
iceServers:
|
|
9575
|
+
iceServers: WebrtcBase.linkToIceServers(response.headers.get("Link"))
|
|
9480
9576
|
});
|
|
9481
9577
|
this._pc = pc;
|
|
9482
9578
|
pc.onicecandidate = (evt) => this.onLocalCandidate(evt);
|
|
@@ -9503,61 +9599,63 @@ var Whip = class _Whip extends WebRtcBase {
|
|
|
9503
9599
|
await this.onLocalOffer(await pc.createOffer());
|
|
9504
9600
|
});
|
|
9505
9601
|
}
|
|
9506
|
-
async
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9602
|
+
async close() {
|
|
9603
|
+
const stream = this._stream;
|
|
9604
|
+
this._stream = null;
|
|
9605
|
+
if (stream) {
|
|
9606
|
+
const tracks = stream.getTracks();
|
|
9607
|
+
tracks.forEach((track) => {
|
|
9608
|
+
track.stop();
|
|
9609
|
+
});
|
|
9513
9610
|
}
|
|
9514
|
-
return
|
|
9611
|
+
return super.close();
|
|
9515
9612
|
}
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9613
|
+
};
|
|
9614
|
+
|
|
9615
|
+
// src/webrtc_whep.ts
|
|
9616
|
+
var WebrtcWhep = class extends WebrtcBase {
|
|
9617
|
+
constructor(ingressId, getSession, client, requestLogger) {
|
|
9618
|
+
super(getSession, client, ingressId, "/liveIngress/whep", requestLogger);
|
|
9619
|
+
this._stream = null;
|
|
9620
|
+
}
|
|
9621
|
+
async close() {
|
|
9622
|
+
const stream = this._stream;
|
|
9623
|
+
this._stream = null;
|
|
9624
|
+
if (stream) {
|
|
9625
|
+
const tracks = stream.getTracks();
|
|
9626
|
+
tracks.forEach((track) => {
|
|
9627
|
+
track.stop();
|
|
9628
|
+
});
|
|
9519
9629
|
}
|
|
9520
|
-
|
|
9521
|
-
|
|
9630
|
+
return super.close();
|
|
9631
|
+
}
|
|
9632
|
+
async stream() {
|
|
9633
|
+
if (this._stream) {
|
|
9634
|
+
return Promise.resolve(this._stream);
|
|
9635
|
+
} else {
|
|
9636
|
+
return Promise.reject("fetching stream failed");
|
|
9522
9637
|
}
|
|
9523
|
-
|
|
9524
|
-
|
|
9638
|
+
}
|
|
9639
|
+
async start() {
|
|
9525
9640
|
const session = await this._getSession();
|
|
9526
|
-
const
|
|
9527
|
-
this._requestLogger.debug("before GET: %s",
|
|
9641
|
+
const egressUrl = new URL(this._urlPath, session.baseUrl);
|
|
9642
|
+
this._requestLogger.debug("before GET: %s", egressUrl);
|
|
9528
9643
|
const headers = {
|
|
9529
|
-
"Authorization": `Bearer ${session.accessToken}
|
|
9530
|
-
"Content-Type": "application/sdp"
|
|
9644
|
+
"Authorization": `Bearer ${session.accessToken}`
|
|
9531
9645
|
};
|
|
9532
|
-
const response = await this._client.fetch(
|
|
9646
|
+
const response = await this._client.fetch(egressUrl, {
|
|
9533
9647
|
headers,
|
|
9534
|
-
method: "
|
|
9535
|
-
body: offer.sdp
|
|
9648
|
+
method: "GET"
|
|
9536
9649
|
});
|
|
9537
|
-
if (response.status
|
|
9538
|
-
return Promise.reject(`unknown status code for
|
|
9650
|
+
if (response.status >= 300) {
|
|
9651
|
+
return Promise.reject(`unknown status code for GET '${egressUrl}': ${response.status} (${response.statusText})`);
|
|
9539
9652
|
}
|
|
9540
|
-
this.
|
|
9541
|
-
return this.onRemoteAnswer(new RTCSessionDescription({
|
|
9542
|
-
type: "answer",
|
|
9543
|
-
sdp: await response.text()
|
|
9544
|
-
}));
|
|
9653
|
+
return this.onIceServers(response);
|
|
9545
9654
|
}
|
|
9546
9655
|
async onRemoteAnswer(answer) {
|
|
9547
9656
|
if (!this._pc) {
|
|
9548
9657
|
throw new Error("onLocalOffer no peer connection");
|
|
9549
9658
|
}
|
|
9550
|
-
answer = new RTCSessionDescription({
|
|
9551
|
-
type: "answer",
|
|
9552
|
-
sdp: _Whip.editAnswer(
|
|
9553
|
-
answer.sdp,
|
|
9554
|
-
"h264/90000",
|
|
9555
|
-
void 0,
|
|
9556
|
-
5e3,
|
|
9557
|
-
void 0,
|
|
9558
|
-
true
|
|
9559
|
-
)
|
|
9560
|
-
});
|
|
9561
9659
|
await this._pc.setRemoteDescription(new RTCSessionDescription(answer));
|
|
9562
9660
|
if (this._queuedCandidates.length !== 0) {
|
|
9563
9661
|
await this.sendLocalCandidates(this._queuedCandidates);
|
|
@@ -9565,42 +9663,38 @@ var Whip = class _Whip extends WebRtcBase {
|
|
|
9565
9663
|
}
|
|
9566
9664
|
return this;
|
|
9567
9665
|
}
|
|
9568
|
-
async
|
|
9569
|
-
if (
|
|
9570
|
-
throw new Error("
|
|
9666
|
+
async onIceServers(response) {
|
|
9667
|
+
if (this._stream) {
|
|
9668
|
+
throw new Error("onIceServers has stream");
|
|
9571
9669
|
}
|
|
9572
|
-
const
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
const
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9670
|
+
const pc = new RTCPeerConnection({
|
|
9671
|
+
iceServers: WebrtcBase.linkToIceServers(response.headers.get("Link"))
|
|
9672
|
+
});
|
|
9673
|
+
const direction = "sendrecv";
|
|
9674
|
+
pc.addTransceiver("video", { direction });
|
|
9675
|
+
pc.onicecandidate = (evt) => this.onLocalCandidate(evt);
|
|
9676
|
+
this._pc = pc;
|
|
9677
|
+
this._requestLogger.info("before", pc.iceConnectionState);
|
|
9678
|
+
return new Promise(async (resolve, reject) => {
|
|
9679
|
+
pc.ontrack = (evt) => {
|
|
9680
|
+
this._requestLogger.debug("new track:", evt.track.kind);
|
|
9681
|
+
this._stream = evt.streams[0];
|
|
9682
|
+
resolve(this);
|
|
9683
|
+
};
|
|
9684
|
+
pc.oniceconnectionstatechange = () => {
|
|
9685
|
+
switch (pc.iceConnectionState) {
|
|
9686
|
+
case "failed":
|
|
9687
|
+
case "disconnected":
|
|
9688
|
+
this._requestLogger.debug("disconnected");
|
|
9689
|
+
reject(`peer connection: ${pc.iceConnectionState}`);
|
|
9690
|
+
break;
|
|
9691
|
+
case "connected":
|
|
9692
|
+
this._requestLogger.debug("connected");
|
|
9693
|
+
break;
|
|
9694
|
+
}
|
|
9695
|
+
};
|
|
9696
|
+
await this.onLocalOffer(await pc.createOffer());
|
|
9584
9697
|
});
|
|
9585
|
-
if (response.status != 204) {
|
|
9586
|
-
return Promise.reject(`unknown status code for PATCH '${ingressUrl}': ${response.status} (${response.statusText})`);
|
|
9587
|
-
}
|
|
9588
|
-
return this;
|
|
9589
|
-
}
|
|
9590
|
-
async close() {
|
|
9591
|
-
const pc = this._pc;
|
|
9592
|
-
const stream = this._stream;
|
|
9593
|
-
this._stream = null;
|
|
9594
|
-
this._pc = null;
|
|
9595
|
-
if (stream) {
|
|
9596
|
-
const tracks = stream.getTracks();
|
|
9597
|
-
tracks.forEach((track) => {
|
|
9598
|
-
track.stop();
|
|
9599
|
-
});
|
|
9600
|
-
}
|
|
9601
|
-
if (pc) {
|
|
9602
|
-
return pc.close();
|
|
9603
|
-
}
|
|
9604
9698
|
}
|
|
9605
9699
|
};
|
|
9606
9700
|
|
|
@@ -9626,6 +9720,43 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
|
9626
9720
|
|
|
9627
9721
|
// src/endpoint.ts
|
|
9628
9722
|
import { pino } from "pino";
|
|
9723
|
+
|
|
9724
|
+
// src/shims/browser_session.ts
|
|
9725
|
+
import { createAuth0Client } from "@auth0/auth0-spa-js";
|
|
9726
|
+
var authenticateBrowserSession;
|
|
9727
|
+
if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
9728
|
+
authenticateBrowserSession = async (auth0, eyepopUrl, popId) => {
|
|
9729
|
+
const options = {
|
|
9730
|
+
clientId: auth0.clientId,
|
|
9731
|
+
domain: auth0.domain,
|
|
9732
|
+
authorizationParams: {
|
|
9733
|
+
scope: auth0.scope,
|
|
9734
|
+
audience: auth0.audience
|
|
9735
|
+
}
|
|
9736
|
+
};
|
|
9737
|
+
const auth0Client = await createAuth0Client(options);
|
|
9738
|
+
if (!await auth0Client.isAuthenticated()) {
|
|
9739
|
+
await auth0Client.loginWithPopup();
|
|
9740
|
+
}
|
|
9741
|
+
const accessToken = await auth0Client.getTokenSilently();
|
|
9742
|
+
if (!accessToken) {
|
|
9743
|
+
return Promise.reject("auth0 login failed");
|
|
9744
|
+
}
|
|
9745
|
+
const session = {
|
|
9746
|
+
eyepopUrl,
|
|
9747
|
+
popId,
|
|
9748
|
+
accessToken,
|
|
9749
|
+
validUntil: Date.now() + 60 * 60 * 1e3
|
|
9750
|
+
};
|
|
9751
|
+
return session;
|
|
9752
|
+
};
|
|
9753
|
+
} else {
|
|
9754
|
+
authenticateBrowserSession = (auth0, eyepopUrl, popId) => {
|
|
9755
|
+
return Promise.reject("auth0 login not supported server-side");
|
|
9756
|
+
};
|
|
9757
|
+
}
|
|
9758
|
+
|
|
9759
|
+
// src/endpoint.ts
|
|
9629
9760
|
var Endpoint = class {
|
|
9630
9761
|
constructor(options) {
|
|
9631
9762
|
this._options = options;
|
|
@@ -9649,55 +9780,13 @@ var Endpoint = class {
|
|
|
9649
9780
|
this._logger = rootLogger.child({ module: "eyepop" });
|
|
9650
9781
|
this._requestLogger = this._logger.child({ module: "requests" });
|
|
9651
9782
|
}
|
|
9652
|
-
|
|
9653
|
-
this.
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
if (this._ingressEventWs || !this._baseUrl || !this._client) {
|
|
9658
|
-
return;
|
|
9659
|
-
}
|
|
9660
|
-
try {
|
|
9661
|
-
const getTokenUrl = `${this._baseUrl}/liveIngress/events/token`;
|
|
9662
|
-
const headers = {
|
|
9663
|
-
"Authorization": await this.authorizationHeader()
|
|
9664
|
-
};
|
|
9665
|
-
this._requestLogger.debug("before GET %s", getTokenUrl);
|
|
9666
|
-
let response = await this._client.fetch(getTokenUrl, { headers });
|
|
9667
|
-
if (response.status == 401) {
|
|
9668
|
-
this._requestLogger.debug("after GET %s: 401, about to retry with fresh access token", getTokenUrl);
|
|
9669
|
-
this._token = null;
|
|
9670
|
-
const headers2 = {
|
|
9671
|
-
"Authorization": await this.authorizationHeader()
|
|
9672
|
-
};
|
|
9673
|
-
this.updateState("FetchConfig" /* FetchConfig */);
|
|
9674
|
-
response = await this._client.fetch(getTokenUrl, { headers: headers2 });
|
|
9675
|
-
}
|
|
9676
|
-
if (response.status != 200) {
|
|
9677
|
-
const message = await response.text();
|
|
9678
|
-
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
9679
|
-
}
|
|
9680
|
-
const wsAuthToken = await response.json();
|
|
9681
|
-
const wsUrl = this._baseUrl.startsWith("https://") ? `${this._baseUrl.replace("https://", "wss://")}/liveIngress/events/${wsAuthToken.token}` : `${this._baseUrl.replace("http://", "ws://")}/liveIngress/events/${wsAuthToken.token}`;
|
|
9682
|
-
this._ingressEventWs = new WebSocket(wsUrl);
|
|
9683
|
-
this._ingressEventWs.addEventListener("message", (event) => {
|
|
9684
|
-
const ingressEvent = JSON.parse(event.data);
|
|
9685
|
-
if (this._ingressEventHandler) {
|
|
9686
|
-
this._ingressEventHandler(ingressEvent);
|
|
9687
|
-
}
|
|
9688
|
-
});
|
|
9689
|
-
} finally {
|
|
9690
|
-
this.updateState();
|
|
9783
|
+
eyepopUrl() {
|
|
9784
|
+
if (this._options.eyepopUrl) {
|
|
9785
|
+
return this._options.eyepopUrl.replace(/\/+$/, "");
|
|
9786
|
+
} else {
|
|
9787
|
+
return "https://api.eyepop.ai";
|
|
9691
9788
|
}
|
|
9692
9789
|
}
|
|
9693
|
-
onIngressEvent(handler) {
|
|
9694
|
-
this._ingressEventHandler = handler;
|
|
9695
|
-
this.startIngressWs().then(() => {
|
|
9696
|
-
}).catch((reason) => {
|
|
9697
|
-
this._logger.warn("unexpected error starting the ingress event handler: %s", reason);
|
|
9698
|
-
});
|
|
9699
|
-
return this;
|
|
9700
|
-
}
|
|
9701
9790
|
state() {
|
|
9702
9791
|
return this._state;
|
|
9703
9792
|
}
|
|
@@ -9710,6 +9799,80 @@ var Endpoint = class {
|
|
|
9710
9799
|
popId() {
|
|
9711
9800
|
return this._options.popId || null;
|
|
9712
9801
|
}
|
|
9802
|
+
onStateChanged(handler) {
|
|
9803
|
+
this._stateChangeHandler = handler;
|
|
9804
|
+
return this;
|
|
9805
|
+
}
|
|
9806
|
+
onIngressEvent(handler) {
|
|
9807
|
+
this._ingressEventHandler = handler;
|
|
9808
|
+
this.startIngressWs().then(() => {
|
|
9809
|
+
}).catch((reason) => {
|
|
9810
|
+
this._logger.warn("unexpected error starting the ingress event handler: %s", reason);
|
|
9811
|
+
});
|
|
9812
|
+
return this;
|
|
9813
|
+
}
|
|
9814
|
+
async connect() {
|
|
9815
|
+
if (this._client) {
|
|
9816
|
+
this._logger.warn("endpoint already connected");
|
|
9817
|
+
return this;
|
|
9818
|
+
}
|
|
9819
|
+
if (!this._options.eyepopUrl) {
|
|
9820
|
+
return Promise.reject("option eyepopUrl or environment variable EYEPOP_URL is required");
|
|
9821
|
+
}
|
|
9822
|
+
if (!this._options.popId) {
|
|
9823
|
+
return Promise.reject("option popId or environment variable EYEPOP_POP_ID is required");
|
|
9824
|
+
}
|
|
9825
|
+
if (this._options.auth === void 0) {
|
|
9826
|
+
return Promise.reject("cannot connect without defined auth option");
|
|
9827
|
+
}
|
|
9828
|
+
if (this._options.auth.session !== void 0) {
|
|
9829
|
+
this._token = this._options.auth.session.accessToken;
|
|
9830
|
+
this._expire_token_time = this._options.auth.session.validUntil / 1e3;
|
|
9831
|
+
} else if (this._options.auth.oAuth2 !== void 0) {
|
|
9832
|
+
} else if (this._options.auth.secretKey !== void 0) {
|
|
9833
|
+
} else {
|
|
9834
|
+
return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
|
|
9835
|
+
}
|
|
9836
|
+
this._client = await createHttpClient();
|
|
9837
|
+
let result = await this.reconnect();
|
|
9838
|
+
if (this._baseUrl && this._options.stopJobs) {
|
|
9839
|
+
const stop_url = `${this._baseUrl}/pipelines/${this._pipelineId}/source?mode=preempt&processing=sync`;
|
|
9840
|
+
const body = { "sourceType": "NONE" };
|
|
9841
|
+
const headers = {
|
|
9842
|
+
"Authorization": await this.authorizationHeader(),
|
|
9843
|
+
"Content-Type": "application/json"
|
|
9844
|
+
};
|
|
9845
|
+
this._requestLogger.debug("before PATCH %s", stop_url);
|
|
9846
|
+
let response = await this._client.fetch(stop_url, {
|
|
9847
|
+
method: "PATCH",
|
|
9848
|
+
headers,
|
|
9849
|
+
body: JSON.stringify(body)
|
|
9850
|
+
});
|
|
9851
|
+
if (response.status >= 300) {
|
|
9852
|
+
const message = await response.text();
|
|
9853
|
+
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
9854
|
+
}
|
|
9855
|
+
this._requestLogger.debug("after PATCH %s", stop_url);
|
|
9856
|
+
}
|
|
9857
|
+
if (!this._ingressEventWs && this._ingressEventHandler) {
|
|
9858
|
+
await this.startIngressWs();
|
|
9859
|
+
}
|
|
9860
|
+
return result;
|
|
9861
|
+
}
|
|
9862
|
+
async disconnect(wait = true) {
|
|
9863
|
+
if (wait && this._limit) {
|
|
9864
|
+
for (let j = 0; j < this._options.jobQueueLength; j++) {
|
|
9865
|
+
await this._limit.acquire();
|
|
9866
|
+
}
|
|
9867
|
+
}
|
|
9868
|
+
this._limit = new Semaphore(this._options.jobQueueLength ?? 1024);
|
|
9869
|
+
if (this._client) {
|
|
9870
|
+
await this._client.close();
|
|
9871
|
+
this._client = null;
|
|
9872
|
+
}
|
|
9873
|
+
this._baseUrl = null;
|
|
9874
|
+
this._pipelineId = null;
|
|
9875
|
+
}
|
|
9713
9876
|
async session() {
|
|
9714
9877
|
await this.currentAccessToken();
|
|
9715
9878
|
if (this._token == null || this._expire_token_time == null) {
|
|
@@ -9734,11 +9897,20 @@ var Endpoint = class {
|
|
|
9734
9897
|
if (!this._baseUrl || !this._client) {
|
|
9735
9898
|
return Promise.reject("endpoint not connected, use connect() before ingress()");
|
|
9736
9899
|
}
|
|
9737
|
-
const whip = new
|
|
9900
|
+
const whip = new WebrtcWhip(stream, async () => {
|
|
9738
9901
|
return this.session();
|
|
9739
9902
|
}, this._client, this._requestLogger);
|
|
9740
9903
|
return whip.start();
|
|
9741
9904
|
}
|
|
9905
|
+
async liveEgress(ingressId) {
|
|
9906
|
+
if (!this._baseUrl || !this._client) {
|
|
9907
|
+
return Promise.reject("endpoint not connected, use connect() before ingress()");
|
|
9908
|
+
}
|
|
9909
|
+
const whep = new WebrtcWhep(ingressId, async () => {
|
|
9910
|
+
return this.session();
|
|
9911
|
+
}, this._client, this._requestLogger);
|
|
9912
|
+
return whep.start();
|
|
9913
|
+
}
|
|
9742
9914
|
async process(source) {
|
|
9743
9915
|
if (source.file !== void 0) {
|
|
9744
9916
|
return this.uploadFile(source);
|
|
@@ -9754,6 +9926,43 @@ var Endpoint = class {
|
|
|
9754
9926
|
return Promise.reject("unknown source type");
|
|
9755
9927
|
}
|
|
9756
9928
|
}
|
|
9929
|
+
async startIngressWs() {
|
|
9930
|
+
if (this._ingressEventWs || !this._baseUrl || !this._client) {
|
|
9931
|
+
return;
|
|
9932
|
+
}
|
|
9933
|
+
try {
|
|
9934
|
+
const getTokenUrl = `${this._baseUrl}/liveIngress/events/token`;
|
|
9935
|
+
const headers = {
|
|
9936
|
+
"Authorization": await this.authorizationHeader()
|
|
9937
|
+
};
|
|
9938
|
+
this._requestLogger.debug("before GET %s", getTokenUrl);
|
|
9939
|
+
let response = await this._client.fetch(getTokenUrl, { headers });
|
|
9940
|
+
if (response.status == 401) {
|
|
9941
|
+
this._requestLogger.debug("after GET %s: 401, about to retry with fresh access token", getTokenUrl);
|
|
9942
|
+
this._token = null;
|
|
9943
|
+
const headers2 = {
|
|
9944
|
+
"Authorization": await this.authorizationHeader()
|
|
9945
|
+
};
|
|
9946
|
+
this.updateState("FetchConfig" /* FetchConfig */);
|
|
9947
|
+
response = await this._client.fetch(getTokenUrl, { headers: headers2 });
|
|
9948
|
+
}
|
|
9949
|
+
if (response.status != 200) {
|
|
9950
|
+
const message = await response.text();
|
|
9951
|
+
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
9952
|
+
}
|
|
9953
|
+
const wsAuthToken = await response.json();
|
|
9954
|
+
const wsUrl = this._baseUrl.startsWith("https://") ? `${this._baseUrl.replace("https://", "wss://")}/liveIngress/events/${wsAuthToken.token}` : `${this._baseUrl.replace("http://", "ws://")}/liveIngress/events/${wsAuthToken.token}`;
|
|
9955
|
+
this._ingressEventWs = new WebSocket(wsUrl);
|
|
9956
|
+
this._ingressEventWs.addEventListener("message", (event) => {
|
|
9957
|
+
const ingressEvent = JSON.parse(event.data);
|
|
9958
|
+
if (this._ingressEventHandler) {
|
|
9959
|
+
this._ingressEventHandler(ingressEvent);
|
|
9960
|
+
}
|
|
9961
|
+
});
|
|
9962
|
+
} finally {
|
|
9963
|
+
this.updateState();
|
|
9964
|
+
}
|
|
9965
|
+
}
|
|
9757
9966
|
async uploadFile(source) {
|
|
9758
9967
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
9759
9968
|
return Promise.reject("endpoint not connected, use connect() before upload()");
|
|
@@ -9855,48 +10064,6 @@ var Endpoint = class {
|
|
|
9855
10064
|
throw e;
|
|
9856
10065
|
}
|
|
9857
10066
|
}
|
|
9858
|
-
// noinspection TypeScriptValidateTypes
|
|
9859
|
-
async connect() {
|
|
9860
|
-
if (this._client) {
|
|
9861
|
-
console.info("endpoint already connected");
|
|
9862
|
-
return this;
|
|
9863
|
-
}
|
|
9864
|
-
if (!this._options.eyepopUrl) {
|
|
9865
|
-
return Promise.reject("option eyepopUrl or environment variable EYEPOP_URL is required");
|
|
9866
|
-
}
|
|
9867
|
-
if (!this._options.popId) {
|
|
9868
|
-
return Promise.reject("option popId or environment variable EYEPOP_POP_ID is required");
|
|
9869
|
-
}
|
|
9870
|
-
if (this._options.auth && this._options.auth.session) {
|
|
9871
|
-
this._token = this._options.auth.session.accessToken;
|
|
9872
|
-
this._expire_token_time = this._options.auth.session.validUntil / 1e3;
|
|
9873
|
-
} else {
|
|
9874
|
-
if (!this._options.auth || !this._options.auth.secretKey) {
|
|
9875
|
-
return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
|
|
9876
|
-
}
|
|
9877
|
-
}
|
|
9878
|
-
this._client = await createHttpClient();
|
|
9879
|
-
let result = await this.reconnect();
|
|
9880
|
-
if (this._baseUrl && this._options.stopJobs) {
|
|
9881
|
-
const stop_url = `${this._baseUrl}/pipelines/${this._pipelineId}/source?mode=preempt&processing=sync`;
|
|
9882
|
-
const body = { "sourceType": "NONE" };
|
|
9883
|
-
const headers = {
|
|
9884
|
-
"Authorization": await this.authorizationHeader(),
|
|
9885
|
-
"Content-Type": "application/json"
|
|
9886
|
-
};
|
|
9887
|
-
this._requestLogger.debug("before PATCH %s", stop_url);
|
|
9888
|
-
let response = await this._client.fetch(stop_url, { method: "PATCH", headers, body: JSON.stringify(body) });
|
|
9889
|
-
if (response.status >= 300) {
|
|
9890
|
-
const message = await response.text();
|
|
9891
|
-
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
9892
|
-
}
|
|
9893
|
-
this._requestLogger.debug("after PATCH %s", stop_url);
|
|
9894
|
-
}
|
|
9895
|
-
if (!this._ingressEventWs && this._ingressEventHandler) {
|
|
9896
|
-
await this.startIngressWs();
|
|
9897
|
-
}
|
|
9898
|
-
return result;
|
|
9899
|
-
}
|
|
9900
10067
|
jobDone(job) {
|
|
9901
10068
|
this._limit?.release();
|
|
9902
10069
|
this.updateState();
|
|
@@ -9983,20 +10150,6 @@ var Endpoint = class {
|
|
|
9983
10150
|
return Promise.resolve(this);
|
|
9984
10151
|
}
|
|
9985
10152
|
}
|
|
9986
|
-
async disconnect(wait = true) {
|
|
9987
|
-
if (wait && this._limit) {
|
|
9988
|
-
for (let j = 0; j < this._options.jobQueueLength; j++) {
|
|
9989
|
-
await this._limit.acquire();
|
|
9990
|
-
}
|
|
9991
|
-
}
|
|
9992
|
-
this._limit = new Semaphore(this._options.jobQueueLength ?? 1024);
|
|
9993
|
-
if (this._client) {
|
|
9994
|
-
await this._client.close();
|
|
9995
|
-
this._client = null;
|
|
9996
|
-
}
|
|
9997
|
-
this._baseUrl = null;
|
|
9998
|
-
this._pipelineId = null;
|
|
9999
|
-
}
|
|
10000
10153
|
async authorizationHeader() {
|
|
10001
10154
|
return `Bearer ${await this.currentAccessToken()}`;
|
|
10002
10155
|
}
|
|
@@ -10004,41 +10157,49 @@ var Endpoint = class {
|
|
|
10004
10157
|
const now = Date.now() / 1e3;
|
|
10005
10158
|
if (!this._token || this._expire_token_time < now) {
|
|
10006
10159
|
this.updateState("Authenticating" /* Authenticating */);
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10160
|
+
try {
|
|
10161
|
+
if (!this._client) {
|
|
10162
|
+
return Promise.reject("endpoint not connected");
|
|
10163
|
+
} else if (this._options.auth.session !== void 0) {
|
|
10164
|
+
return Promise.reject("temporary access token expired");
|
|
10165
|
+
} else if (this._options.auth.oAuth2 !== void 0 && this._options.eyepopUrl && this._options.popId) {
|
|
10166
|
+
const session = await authenticateBrowserSession(
|
|
10167
|
+
this._options.auth.oAuth2,
|
|
10168
|
+
this._options.eyepopUrl,
|
|
10169
|
+
this._options.popId
|
|
10170
|
+
);
|
|
10171
|
+
this._token = session.accessToken;
|
|
10172
|
+
this._expire_token_time = session.validUntil / 1e3;
|
|
10173
|
+
} else if (this._options.auth.secretKey !== void 0 && this._options.eyepopUrl) {
|
|
10174
|
+
const secretKeyAuth = this._options.auth;
|
|
10175
|
+
const body = { "secret_key": secretKeyAuth.secretKey };
|
|
10176
|
+
const headers = { "Content-Type": "application/json" };
|
|
10177
|
+
const post_url = `${this.eyepopUrl()}/authentication/token`;
|
|
10178
|
+
this._requestLogger.debug("before POST %s", post_url);
|
|
10179
|
+
const response = await this._client.fetch(post_url, {
|
|
10180
|
+
method: "POST",
|
|
10181
|
+
headers,
|
|
10182
|
+
body: JSON.stringify(body)
|
|
10183
|
+
});
|
|
10184
|
+
if (response.status != 200) {
|
|
10185
|
+
const message = await response.text();
|
|
10186
|
+
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
10187
|
+
}
|
|
10188
|
+
this._requestLogger.debug("after POST %s", post_url);
|
|
10189
|
+
const data = await response.json();
|
|
10190
|
+
const token = data;
|
|
10191
|
+
this._token = token.access_token;
|
|
10192
|
+
this._expire_token_time = now + token.expires_in - 60;
|
|
10193
|
+
} else {
|
|
10194
|
+
return Promise.reject("no valid auth option");
|
|
10195
|
+
}
|
|
10196
|
+
} finally {
|
|
10197
|
+
this.updateState();
|
|
10024
10198
|
}
|
|
10025
|
-
this._requestLogger.debug("after POST %s", post_url);
|
|
10026
|
-
const data = await response.json();
|
|
10027
|
-
const token = data;
|
|
10028
|
-
this._token = token.access_token;
|
|
10029
|
-
this._expire_token_time = now + token.expires_in - 60;
|
|
10030
|
-
this.updateState();
|
|
10031
10199
|
}
|
|
10032
10200
|
this._logger.debug("using access token, valid for at least %d seconds", this._expire_token_time - now);
|
|
10033
10201
|
return this._token;
|
|
10034
10202
|
}
|
|
10035
|
-
eyepopUrl() {
|
|
10036
|
-
if (this._options.eyepopUrl) {
|
|
10037
|
-
return this._options.eyepopUrl.replace(/\/+$/, "");
|
|
10038
|
-
} else {
|
|
10039
|
-
return "https://api.eyepop.ai";
|
|
10040
|
-
}
|
|
10041
|
-
}
|
|
10042
10203
|
};
|
|
10043
10204
|
|
|
10044
10205
|
// src/visualize.ts
|
|
@@ -10154,40 +10315,6 @@ _EyePopPlot.colors = {
|
|
|
10154
10315
|
};
|
|
10155
10316
|
var EyePopPlot = _EyePopPlot;
|
|
10156
10317
|
|
|
10157
|
-
// src/shims/browser_session.ts
|
|
10158
|
-
var authenticateBrowserSession;
|
|
10159
|
-
if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
10160
|
-
authenticateBrowserSession = (oauthUrl, eyepopUrl, popId) => {
|
|
10161
|
-
const queryString = window.location.search;
|
|
10162
|
-
const urlParams = new URLSearchParams(queryString);
|
|
10163
|
-
let token = urlParams.get("pop_token");
|
|
10164
|
-
if (token) {
|
|
10165
|
-
urlParams.delete("pop_token");
|
|
10166
|
-
const url = `${window.location.pathname}?${urlParams}`;
|
|
10167
|
-
window.history.replaceState({}, document.title, url);
|
|
10168
|
-
return {
|
|
10169
|
-
eyepopUrl,
|
|
10170
|
-
popId,
|
|
10171
|
-
accessToken: token,
|
|
10172
|
-
validUntil: Date.now() + 60 * 60 * 1e3
|
|
10173
|
-
};
|
|
10174
|
-
} else {
|
|
10175
|
-
const url = `${oauthUrl}?url=${encodeURIComponent(window.location.href)}`;
|
|
10176
|
-
window.location.replace(url);
|
|
10177
|
-
return {
|
|
10178
|
-
eyepopUrl,
|
|
10179
|
-
popId,
|
|
10180
|
-
accessToken: "in-progress",
|
|
10181
|
-
validUntil: 0
|
|
10182
|
-
};
|
|
10183
|
-
}
|
|
10184
|
-
};
|
|
10185
|
-
} else {
|
|
10186
|
-
authenticateBrowserSession = (oauthUrl, eyepopUrl, popId) => {
|
|
10187
|
-
return null;
|
|
10188
|
-
};
|
|
10189
|
-
}
|
|
10190
|
-
|
|
10191
10318
|
// src/index.ts
|
|
10192
10319
|
var readEnv = (env) => {
|
|
10193
10320
|
if (typeof process !== "undefined") {
|
|
@@ -10195,7 +10322,7 @@ var readEnv = (env) => {
|
|
|
10195
10322
|
}
|
|
10196
10323
|
return void 0;
|
|
10197
10324
|
};
|
|
10198
|
-
var
|
|
10325
|
+
var _EyePopSdk = class _EyePopSdk {
|
|
10199
10326
|
static endpoint({
|
|
10200
10327
|
auth = this.defaultAuth,
|
|
10201
10328
|
popId = readEnv("EYEPOP_POP_ID"),
|
|
@@ -10206,17 +10333,30 @@ var EyePopSdk = class {
|
|
|
10206
10333
|
logger,
|
|
10207
10334
|
...opts
|
|
10208
10335
|
} = {}) {
|
|
10209
|
-
if (auth.
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10336
|
+
if (auth.oAuth2 !== void 0 && popId) {
|
|
10337
|
+
if (typeof auth.oAuth2 === "boolean") {
|
|
10338
|
+
auth = {
|
|
10339
|
+
oAuth2: {
|
|
10340
|
+
domain: "eyepop.us.auth0.com",
|
|
10341
|
+
clientId: "Lb9ubA9Hf3jlaqWLUx8XgA0zvotgViCl",
|
|
10342
|
+
audience: "https://api.eyepop.ai",
|
|
10343
|
+
scope: "admin:clouds"
|
|
10344
|
+
}
|
|
10345
|
+
};
|
|
10346
|
+
}
|
|
10347
|
+
}
|
|
10348
|
+
if (auth.session !== void 0) {
|
|
10349
|
+
if (auth.session.popId) {
|
|
10350
|
+
popId = auth.session.popId;
|
|
10351
|
+
}
|
|
10352
|
+
if (auth.session.eyepopUrl) {
|
|
10353
|
+
eyepopUrl = auth.session.eyepopUrl;
|
|
10213
10354
|
}
|
|
10214
|
-
auth.session = authenticateBrowserSession(oauthUrl, eyepopUrl ?? "https://api.eyepop.ai", popId) ?? void 0;
|
|
10215
10355
|
}
|
|
10216
10356
|
const options = {
|
|
10217
10357
|
auth,
|
|
10218
|
-
popId
|
|
10219
|
-
eyepopUrl:
|
|
10358
|
+
popId,
|
|
10359
|
+
eyepopUrl: eyepopUrl ?? "https://api.eyepop.ai",
|
|
10220
10360
|
autoStart,
|
|
10221
10361
|
stopJobs,
|
|
10222
10362
|
jobQueueLength,
|
|
@@ -10229,9 +10369,11 @@ var EyePopSdk = class {
|
|
|
10229
10369
|
return new EyePopPlot(context);
|
|
10230
10370
|
}
|
|
10231
10371
|
};
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10372
|
+
_EyePopSdk.envSecretKey = readEnv("EYEPOP_SECRET_KEY");
|
|
10373
|
+
_EyePopSdk.defaultAuth = _EyePopSdk.envSecretKey ? {
|
|
10374
|
+
secretKey: _EyePopSdk.envSecretKey
|
|
10375
|
+
} : void 0;
|
|
10376
|
+
var EyePopSdk = _EyePopSdk;
|
|
10235
10377
|
var src_default = EyePopSdk;
|
|
10236
10378
|
export {
|
|
10237
10379
|
EndpointState,
|