@3dsource/angular-unreal-module 0.0.157 → 0.0.159
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.
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, DestroyRef, ChangeDetectionStrategy, Component, Injectable, signal, effect, untracked, computed,
|
|
2
|
+
import { InjectionToken, inject, DestroyRef, ChangeDetectionStrategy, Component, Injectable, signal, effect, untracked, computed, input, ElementRef, viewChild, afterNextRender, HostListener, SecurityContext, Pipe, output, makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';
|
|
3
3
|
import { SourceButtonComponent, SourceLoadingComponent } from '@3dsource/source-ui-native';
|
|
4
|
-
import { Subject, skip, share, merge, map, scan, timestamp, startWith, pairwise, concatMap, of, animationFrameScheduler, interval, Observable, timer, take, defer, switchMap, from, throwError, EMPTY, retry, timeout as timeout$1, repeat, BehaviorSubject, takeUntil as takeUntil$1, fromEvent, tap as tap$1, throttleTime, delay, concat, debounceTime, mergeMap, NEVER, ignoreElements, shareReplay, asyncScheduler, filter as filter$1, withLatestFrom as withLatestFrom$1, Subscription, bufferTime, combineLatestWith
|
|
4
|
+
import { Subject, skip, share, merge, map, scan, timestamp, startWith, pairwise, concatMap, of, animationFrameScheduler, interval, Observable, timer, take, defer, switchMap, from, throwError, EMPTY, retry, timeout as timeout$1, repeat, BehaviorSubject, takeUntil as takeUntil$1, fromEvent, tap as tap$1, throttleTime, delay, concat, debounceTime, mergeMap, NEVER, ignoreElements, shareReplay, asyncScheduler, filter as filter$1, withLatestFrom as withLatestFrom$1, Subscription, bufferTime, combineLatestWith } from 'rxjs';
|
|
5
5
|
import { createAction, props, createReducer, on, createFeature, Store, createSelector, provideState } from '@ngrx/store';
|
|
6
|
-
import { whereNot, Falsy, Logger,
|
|
6
|
+
import { whereNot, Falsy, Logger, clampf, lerp, getCanvasCached, getSnapshot, fitIntoRectangle, generateUuid, Truthy, tapLog, Semaphore, COLOR_CODES, where, KeyboardNumericCode, InvertedKeyMap, HEXtoRGB, RGBtoHSV, inverseLerp, HSVtoRGB, RGBtoHEX, fpIsASameAsB } from '@3dsource/utils';
|
|
7
7
|
import { filter, map as map$1, distinctUntilChanged, takeWhile, takeUntil, catchError, tap, timeout, finalize, first, switchMap as switchMap$1, withLatestFrom, exhaustMap, debounceTime as debounceTime$1, take as take$1, startWith as startWith$1 } from 'rxjs/operators';
|
|
8
8
|
import { Actions, ofType, createEffect, provideEffects } from '@ngrx/effects';
|
|
9
9
|
import { DialogRef, DIALOG_DATA, Dialog } from '@angular/cdk/dialog';
|
|
@@ -11,11 +11,8 @@ import { HttpClient } from '@angular/common/http';
|
|
|
11
11
|
import { ScrollStrategyOptions } from '@angular/cdk/overlay';
|
|
12
12
|
import { MetaBoxCommand, EPayloadVersion } from '@3dsource/types-unreal';
|
|
13
13
|
import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
14
|
-
import { v4 } from 'uuid';
|
|
15
|
-
import { DomSanitizer } from '@angular/platform-browser';
|
|
16
14
|
import { NgOptimizedImage, JsonPipe } from '@angular/common';
|
|
17
|
-
import
|
|
18
|
-
import { FormsModule } from '@angular/forms';
|
|
15
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
19
16
|
|
|
20
17
|
const SpecialKeyCodes = {
|
|
21
18
|
BackSpace: 8,
|
|
@@ -872,85 +869,6 @@ function decodeData(anyData) {
|
|
|
872
869
|
}
|
|
873
870
|
}
|
|
874
871
|
|
|
875
|
-
class DataFlowMonitor {
|
|
876
|
-
/**
|
|
877
|
-
* Initializes the DataFlowMonitor monitor.
|
|
878
|
-
* @param yellowFlagThresholdPercentage - The percentage drop to trigger a YELLOW warning (default: 15%).
|
|
879
|
-
* @param redFlagThresholdPercentage - The percentage drop to trigger a RED warning (default: 30%).
|
|
880
|
-
* @param historyBufferLength - buffer length (default: 100).
|
|
881
|
-
* @param splitPoint - The point at which to split the history buffer into two halves (default: 0.5).
|
|
882
|
-
*/
|
|
883
|
-
constructor(yellowFlagThresholdPercentage = 15, redFlagThresholdPercentage = 30, historyBufferLength = 100, splitPoint = 0.5) {
|
|
884
|
-
this.yellowFlagThresholdPercentage = yellowFlagThresholdPercentage;
|
|
885
|
-
this.redFlagThresholdPercentage = redFlagThresholdPercentage;
|
|
886
|
-
this.historyBufferLength = historyBufferLength;
|
|
887
|
-
this.splitPoint = splitPoint;
|
|
888
|
-
this.dataHistory = [];
|
|
889
|
-
}
|
|
890
|
-
reset() {
|
|
891
|
-
this.dataHistory.length = 0;
|
|
892
|
-
}
|
|
893
|
-
config(data) {
|
|
894
|
-
this.reset();
|
|
895
|
-
this.yellowFlagThresholdPercentage = data.yellowFlag;
|
|
896
|
-
this.redFlagThresholdPercentage = data.redFlag;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Adds a new bitrate measurement and checks for significant drops.
|
|
900
|
-
* @param currentValue - The current bitrate in kbps.
|
|
901
|
-
* @returns BitrateCheckResult indicating if a drop was detected.
|
|
902
|
-
*/
|
|
903
|
-
addValue(currentValue) {
|
|
904
|
-
if (isNaN(currentValue) || currentValue < 1) {
|
|
905
|
-
return {};
|
|
906
|
-
}
|
|
907
|
-
const historyLength = this.dataHistory.length;
|
|
908
|
-
if (historyLength > this.historyBufferLength) {
|
|
909
|
-
this.dataHistory.shift();
|
|
910
|
-
}
|
|
911
|
-
this.dataHistory.push(currentValue);
|
|
912
|
-
if (historyLength < this.historyBufferLength) {
|
|
913
|
-
this.dataHistory.length = this.historyBufferLength;
|
|
914
|
-
this.dataHistory.fill(currentValue, 0, this.historyBufferLength);
|
|
915
|
-
}
|
|
916
|
-
const splitIndex = Math.floor(historyLength * this.splitPoint);
|
|
917
|
-
const firstHalf = this.dataHistory.slice(0, splitIndex);
|
|
918
|
-
const secondHalf = this.dataHistory.slice(splitIndex);
|
|
919
|
-
const firstHalfMedian = calculateMedian(firstHalf);
|
|
920
|
-
const secondHalfMedian = calculateMedian(secondHalf);
|
|
921
|
-
const dropPercentage = clampf(0, 100, ((firstHalfMedian - secondHalfMedian) / firstHalfMedian) * 100);
|
|
922
|
-
const isRedFlag = dropPercentage >= this.redFlagThresholdPercentage;
|
|
923
|
-
if (dropPercentage >= this.yellowFlagThresholdPercentage) {
|
|
924
|
-
return {
|
|
925
|
-
config: {
|
|
926
|
-
yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,
|
|
927
|
-
redFlagThresholdPercentage: this.redFlagThresholdPercentage,
|
|
928
|
-
historyBufferLength: this.historyBufferLength,
|
|
929
|
-
splitPoint: this.splitPoint,
|
|
930
|
-
},
|
|
931
|
-
isDropDetected: true,
|
|
932
|
-
dropPercentage,
|
|
933
|
-
activeMedian: secondHalfMedian,
|
|
934
|
-
quality: isRedFlag ? 'red' : 'orange',
|
|
935
|
-
message: `Significant flow drop detected: ${dropPercentage.toFixed(2)}% (from ${firstHalfMedian} to ${secondHalfMedian})`,
|
|
936
|
-
};
|
|
937
|
-
}
|
|
938
|
-
return {
|
|
939
|
-
config: {
|
|
940
|
-
yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,
|
|
941
|
-
redFlagThresholdPercentage: this.redFlagThresholdPercentage,
|
|
942
|
-
historyBufferLength: this.historyBufferLength,
|
|
943
|
-
splitPoint: this.splitPoint,
|
|
944
|
-
},
|
|
945
|
-
isDropDetected: false,
|
|
946
|
-
dropPercentage,
|
|
947
|
-
activeMedian: secondHalfMedian,
|
|
948
|
-
quality: 'lime',
|
|
949
|
-
message: 'Stable flow',
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
}
|
|
953
|
-
|
|
954
872
|
const dispatchResize = () => {
|
|
955
873
|
window.dispatchEvent(new Event('resize'));
|
|
956
874
|
};
|
|
@@ -1033,51 +951,6 @@ function* getActiveUrl(urls) {
|
|
|
1033
951
|
}
|
|
1034
952
|
}
|
|
1035
953
|
|
|
1036
|
-
class KalmanFilter1D {
|
|
1037
|
-
/**
|
|
1038
|
-
* @param initialEstimate Initial guess of the state.
|
|
1039
|
-
* @param initialUncertainty Initial uncertainty in the guess.
|
|
1040
|
-
* @param processNoise Process variance (Q) representing model uncertainty.
|
|
1041
|
-
* @param measurementNoise Measurement variance (R) representing noise in measurements.
|
|
1042
|
-
*/
|
|
1043
|
-
constructor(initialEstimate, initialUncertainty, processNoise, measurementNoise) {
|
|
1044
|
-
this.estimate = initialEstimate;
|
|
1045
|
-
this.uncertainty = initialUncertainty;
|
|
1046
|
-
this.processNoise = processNoise;
|
|
1047
|
-
this.measurementNoise = measurementNoise;
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Incorporates a new measurement and returns the updated estimate.
|
|
1051
|
-
* @param measurement The new measurement value.
|
|
1052
|
-
*/
|
|
1053
|
-
update(measurement) {
|
|
1054
|
-
// === Prediction Step ===
|
|
1055
|
-
// For a constant model, the predicted state is the previous estimate.
|
|
1056
|
-
const predictedEstimate = this.estimate;
|
|
1057
|
-
// Increase the uncertainty by the process noise.
|
|
1058
|
-
const predictedUncertainty = this.uncertainty + this.processNoise;
|
|
1059
|
-
// === Update Step ===
|
|
1060
|
-
// Compute the innovation or measurement residual.
|
|
1061
|
-
const innovation = measurement - predictedEstimate;
|
|
1062
|
-
// Compute the innovation covariance.
|
|
1063
|
-
const innovationCovariance = predictedUncertainty + this.measurementNoise;
|
|
1064
|
-
// Compute the Kalman Gain.
|
|
1065
|
-
const kalmanGain = predictedUncertainty / innovationCovariance;
|
|
1066
|
-
// Update the estimate with the measurement, weighted by the Kalman Gain.
|
|
1067
|
-
this.estimate = predictedEstimate + kalmanGain * innovation;
|
|
1068
|
-
// Update the uncertainty.
|
|
1069
|
-
this.uncertainty = (1 - kalmanGain) * predictedUncertainty;
|
|
1070
|
-
return this.estimate;
|
|
1071
|
-
}
|
|
1072
|
-
config(data) {
|
|
1073
|
-
const { initialBitrateEstimate, initialErrorCovariance, processNoise, measurementNoise, } = data;
|
|
1074
|
-
this.estimate = initialBitrateEstimate;
|
|
1075
|
-
this.uncertainty = initialErrorCovariance;
|
|
1076
|
-
this.processNoise = processNoise;
|
|
1077
|
-
this.measurementNoise = measurementNoise;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
954
|
class LatencyTimings {
|
|
1082
955
|
constructor() {
|
|
1083
956
|
this.TestStartTimeMs = null;
|
|
@@ -2565,30 +2438,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2565
2438
|
args: [{ providedIn: 'root' }]
|
|
2566
2439
|
}], ctorParameters: () => [] });
|
|
2567
2440
|
|
|
2568
|
-
/**
|
|
2569
|
-
* Default LBM Filter Parameters
|
|
2570
|
-
*/
|
|
2571
|
-
const DefaultFilterModel = {
|
|
2572
|
-
minimumBitrate: 1600,
|
|
2573
|
-
yellowFlag: 30,
|
|
2574
|
-
redFlag: 50,
|
|
2575
|
-
minimumFps: 5,
|
|
2576
|
-
monitoringDelayTime: 5000,
|
|
2577
|
-
initialBitrateEstimate: 1600,
|
|
2578
|
-
initialErrorCovariance: 1,
|
|
2579
|
-
processNoise: 3,
|
|
2580
|
-
measurementNoise: 500,
|
|
2581
|
-
panelOpen: false,
|
|
2582
|
-
};
|
|
2583
|
-
/**
|
|
2584
|
-
* Global LBM Filter Parameters
|
|
2585
|
-
*/
|
|
2586
|
-
const FilterModel = { ...DefaultFilterModel };
|
|
2587
|
-
/**
|
|
2588
|
-
* Bitrate Monitor Static Class
|
|
2589
|
-
*/
|
|
2590
|
-
const BITRATE_MONITOR = new DataFlowMonitor(FilterModel.yellowFlag, FilterModel.redFlag, 20);
|
|
2591
|
-
|
|
2592
2441
|
class VideoService extends SubService {
|
|
2593
2442
|
constructor() {
|
|
2594
2443
|
super();
|
|
@@ -2606,15 +2455,13 @@ class VideoService extends SubService {
|
|
|
2606
2455
|
this.videoTrack$ = new BehaviorSubject(null);
|
|
2607
2456
|
this.VideoEncoderQP = 0;
|
|
2608
2457
|
this.aggregatedStats = {};
|
|
2609
|
-
this.kalmanFilter1D = new KalmanFilter1D(FilterModel.initialBitrateEstimate, FilterModel.initialErrorCovariance, FilterModel.processNoise, FilterModel.measurementNoise);
|
|
2610
2458
|
/**
|
|
2611
2459
|
* Aggregate video stats and emit it as videoStats$
|
|
2612
2460
|
*/
|
|
2613
2461
|
this.videoStats$ = this.videoTrack$.pipe(
|
|
2614
2462
|
// If videoTrack$ emits null, switch to EMPTY → the current interval is canceled.
|
|
2615
2463
|
switchMap$1((track) => track
|
|
2616
|
-
?
|
|
2617
|
-
interval(250).pipe(map(() => track.pcClient), switchMap$1((pcClient) => from(this.getStats(pcClient))), filter(Truthy))
|
|
2464
|
+
? interval(250).pipe(map(() => track.pcClient), switchMap$1((pcClient) => from(this.getStats(pcClient))), filter(Truthy))
|
|
2618
2465
|
: of(null)), filter(Truthy), share());
|
|
2619
2466
|
this.destroyAbort = new AbortController();
|
|
2620
2467
|
this.destroyRef.onDestroy(() => this.destroy());
|
|
@@ -2843,9 +2690,6 @@ class VideoService extends SubService {
|
|
|
2843
2690
|
}
|
|
2844
2691
|
// Calculate duration of run
|
|
2845
2692
|
newStat.runTime = Math.floor((newStat.timestamp - newStat.timestampStart) / 1000);
|
|
2846
|
-
newStat.kalmanBitrate = Math.floor(this.kalmanFilter1D.update(newStat.bitrate || FilterModel.initialBitrateEstimate));
|
|
2847
|
-
newStat.dataFlowCheckResult = BITRATE_MONITOR.addValue(newStat.kalmanBitrate);
|
|
2848
|
-
newStat.bitrateDrop = Math.floor(newStat.dataFlowCheckResult.dropPercentage);
|
|
2849
2693
|
this.aggregatedStats = newStat;
|
|
2850
2694
|
return this.onAggregatedStats(newStat);
|
|
2851
2695
|
}
|
|
@@ -2882,8 +2726,6 @@ class VideoService extends SubService {
|
|
|
2882
2726
|
// Reset stat state to prevent stale deltas on next session
|
|
2883
2727
|
this.aggregatedStats = {};
|
|
2884
2728
|
this.VideoEncoderQP = 0;
|
|
2885
|
-
this.kalmanFilter1D = new KalmanFilter1D(FilterModel.initialBitrateEstimate, FilterModel.initialErrorCovariance, FilterModel.processNoise, FilterModel.measurementNoise);
|
|
2886
|
-
BITRATE_MONITOR.reset();
|
|
2887
2729
|
while (this.container?.firstChild) {
|
|
2888
2730
|
this.container.removeChild(this.container.firstChild);
|
|
2889
2731
|
}
|
|
@@ -5900,14 +5742,14 @@ class StreamStatusTelemetryService2 {
|
|
|
5900
5742
|
const existing = localStorage.getItem(USER_ID_STORAGE_KEY);
|
|
5901
5743
|
if (existing && existing.length > 0)
|
|
5902
5744
|
return existing;
|
|
5903
|
-
const fresh =
|
|
5745
|
+
const fresh = generateUuid();
|
|
5904
5746
|
localStorage.setItem(USER_ID_STORAGE_KEY, fresh);
|
|
5905
5747
|
return fresh;
|
|
5906
5748
|
}
|
|
5907
5749
|
catch {
|
|
5908
5750
|
// localStorage disabled (private-mode restrictions, quota, etc.)
|
|
5909
5751
|
// Fall back to a per-tab ephemeral id so telemetry keeps working.
|
|
5910
|
-
return
|
|
5752
|
+
return generateUuid();
|
|
5911
5753
|
}
|
|
5912
5754
|
}
|
|
5913
5755
|
init() {
|
|
@@ -5960,7 +5802,7 @@ class StreamStatusTelemetryService2 {
|
|
|
5960
5802
|
startSession() {
|
|
5961
5803
|
// If a previous session is still active, close it first.
|
|
5962
5804
|
this.endSession('restart');
|
|
5963
|
-
const id =
|
|
5805
|
+
const id = generateUuid();
|
|
5964
5806
|
const startedAt = Date.now();
|
|
5965
5807
|
const startedAtPerf = performance.now();
|
|
5966
5808
|
const sub = new Subscription();
|
|
@@ -7166,11 +7008,11 @@ class AfkTimeoutModalComponent {
|
|
|
7166
7008
|
this.#afkService.reset();
|
|
7167
7009
|
}
|
|
7168
7010
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfkTimeoutModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7169
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AfkTimeoutModalComponent, isStandalone: true, selector: "app-afk-timeout-modal", ngImport: i0, template: "@if (isShowAfkPopup()) {\r\n <div
|
|
7011
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AfkTimeoutModalComponent, isStandalone: true, selector: "app-afk-timeout-modal", ngImport: i0, template: "@if (isShowAfkPopup()) {\r\n <div (click)=\"resetAfk()\" class=\"clickableState\" id=\"videoPlayOverlay\">\r\n <div class=\"resume-box\">\r\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\r\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\r\n </div>\r\n <div class=\"resume-box__text\">\r\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\r\n <p>\r\n No activity detected. Press 'Continue' if you wish to keep your\r\n session active\r\n </p>\r\n </div>\r\n <src-button\r\n [isFullWidth]=\"true\"\r\n [data-testid]=\"'continue-session'\"\r\n weight=\"primary\"\r\n size=\"lg\"\r\n >\r\n Continue\r\n </src-button>\r\n </div>\r\n </div>\r\n}\r\n", styles: ["#videoPlayOverlay{position:absolute;z-index:30;top:0;width:100%;height:100%;font-size:1.8em;font-family:var(--src-font-family-body);background-color:#646464b3}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-surface-container-main, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.resume-box .resume-box__pic .text-number{color:var(--src-colors-text-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--src-font-family-body);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--src-text-body-secondary, #6b7280)}.resume-box__text .resume-box__heading{color:var(--src-text-body-main, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"], dependencies: [{ kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "weight", "size", "context", "customClass", "isFullWidth", "isPressed", "isDisabled", "isLoading", "isInverted", "srcButtonConfig", "formID", "data-testid", "ariaLabel"], outputs: ["onClick", "onSubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7170
7012
|
}
|
|
7171
7013
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfkTimeoutModalComponent, decorators: [{
|
|
7172
7014
|
type: Component,
|
|
7173
|
-
args: [{ selector: 'app-afk-timeout-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceButtonComponent], template: "@if (isShowAfkPopup()) {\r\n <div
|
|
7015
|
+
args: [{ selector: 'app-afk-timeout-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceButtonComponent], template: "@if (isShowAfkPopup()) {\r\n <div (click)=\"resetAfk()\" class=\"clickableState\" id=\"videoPlayOverlay\">\r\n <div class=\"resume-box\">\r\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\r\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\r\n </div>\r\n <div class=\"resume-box__text\">\r\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\r\n <p>\r\n No activity detected. Press 'Continue' if you wish to keep your\r\n session active\r\n </p>\r\n </div>\r\n <src-button\r\n [isFullWidth]=\"true\"\r\n [data-testid]=\"'continue-session'\"\r\n weight=\"primary\"\r\n size=\"lg\"\r\n >\r\n Continue\r\n </src-button>\r\n </div>\r\n </div>\r\n}\r\n", styles: ["#videoPlayOverlay{position:absolute;z-index:30;top:0;width:100%;height:100%;font-size:1.8em;font-family:var(--src-font-family-body);background-color:#646464b3}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-surface-container-main, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.resume-box .resume-box__pic .text-number{color:var(--src-colors-text-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--src-font-family-body);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--src-text-body-secondary, #6b7280)}.resume-box__text .resume-box__heading{color:var(--src-text-body-main, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"] }]
|
|
7174
7016
|
}] });
|
|
7175
7017
|
|
|
7176
7018
|
class FreezeFrameComponent {
|
|
@@ -7188,57 +7030,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7188
7030
|
args: [{ selector: 'app-freeze-frame', changeDetection: ChangeDetectionStrategy.OnPush, template: "@let image = combinedFreeze();\r\n@let progress = freezeFrameProgressMessageFromVideo();\r\n\r\n<div class=\"freeze-images\">\r\n @if (image) {\r\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\r\n }\r\n\r\n @if (progress) {\r\n <div class=\"progress-status\">\r\n {{ progress }}\r\n </div>\r\n }\r\n</div>\r\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"] }]
|
|
7189
7031
|
}] });
|
|
7190
7032
|
|
|
7191
|
-
class SafePipe {
|
|
7192
|
-
constructor() {
|
|
7193
|
-
this.sanitizer = inject(DomSanitizer);
|
|
7194
|
-
}
|
|
7195
|
-
transform(value, type) {
|
|
7196
|
-
if (!value) {
|
|
7197
|
-
return value;
|
|
7198
|
-
}
|
|
7199
|
-
const context = (() => {
|
|
7200
|
-
switch (type) {
|
|
7201
|
-
case 'html':
|
|
7202
|
-
return SecurityContext.HTML;
|
|
7203
|
-
case 'style':
|
|
7204
|
-
return SecurityContext.STYLE;
|
|
7205
|
-
case 'script':
|
|
7206
|
-
return SecurityContext.SCRIPT;
|
|
7207
|
-
case 'url':
|
|
7208
|
-
return SecurityContext.URL;
|
|
7209
|
-
case 'resourceUrl':
|
|
7210
|
-
return SecurityContext.RESOURCE_URL;
|
|
7211
|
-
default:
|
|
7212
|
-
throw new Error(`Invalid safe type specified: ${type}`);
|
|
7213
|
-
}
|
|
7214
|
-
})();
|
|
7215
|
-
// Preserve the published return type while returning Angular-sanitized
|
|
7216
|
-
// content instead of disabling framework security checks.
|
|
7217
|
-
return (this.sanitizer.sanitize(context, value) ?? '');
|
|
7218
|
-
}
|
|
7219
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
7220
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" }); }
|
|
7221
|
-
}
|
|
7222
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, decorators: [{
|
|
7223
|
-
type: Pipe,
|
|
7224
|
-
args: [{
|
|
7225
|
-
name: 'safe',
|
|
7226
|
-
}]
|
|
7227
|
-
}] });
|
|
7228
|
-
|
|
7229
|
-
class LowBandwidthModalComponent {
|
|
7230
|
-
#dialogRef = inject(DialogRef);
|
|
7231
|
-
close(value) {
|
|
7232
|
-
this.#dialogRef.close(value || false);
|
|
7233
|
-
}
|
|
7234
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7235
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: LowBandwidthModalComponent, isStandalone: true, selector: "app-low-bandwidth-modal", ngImport: i0, template: "<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\r\n <header class=\"src-modal__header\">\r\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\r\n Unstable Connection\r\n </h6>\r\n </header>\r\n <section class=\"src-modal__body\">\r\n <div\r\n [innerHtml]=\"\r\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\r\n | safe: 'html'\r\n \"\r\n class=\"src-modal__scroll-box\"\r\n ></div>\r\n </section>\r\n <footer class=\"src-modal__footer\">\r\n <div class=\"src-modal__buttons\">\r\n <src-button\r\n (onClick)=\"close(true)\"\r\n [data-testid]=\"'switch-to-interactive-mode'\"\r\n >\r\n Switch\r\n </src-button>\r\n\r\n <src-button\r\n (onClick)=\"close()\"\r\n [data-testid]=\"'close-lbm-modal'\"\r\n weight=\"primary\"\r\n >\r\n Ok\r\n </src-button>\r\n </div>\r\n </footer>\r\n</div>\r\n", styles: [".src-modal--lbm{width:360px}.src-modal--lbm .src-modal__body{font-size:14px;line-height:24px}.src-modal--lbm .src-modal__buttons{display:flex;gap:8px}\n"], dependencies: [{ kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "weight", "size", "context", "customClass", "isFullWidth", "isPressed", "isDisabled", "isLoading", "isInverted", "srcButtonConfig", "formID", "data-testid", "ariaLabel"], outputs: ["onClick", "onSubmit"] }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7236
|
-
}
|
|
7237
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthModalComponent, decorators: [{
|
|
7238
|
-
type: Component,
|
|
7239
|
-
args: [{ selector: 'app-low-bandwidth-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SafePipe, SourceButtonComponent], template: "<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\r\n <header class=\"src-modal__header\">\r\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\r\n Unstable Connection\r\n </h6>\r\n </header>\r\n <section class=\"src-modal__body\">\r\n <div\r\n [innerHtml]=\"\r\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\r\n | safe: 'html'\r\n \"\r\n class=\"src-modal__scroll-box\"\r\n ></div>\r\n </section>\r\n <footer class=\"src-modal__footer\">\r\n <div class=\"src-modal__buttons\">\r\n <src-button\r\n (onClick)=\"close(true)\"\r\n [data-testid]=\"'switch-to-interactive-mode'\"\r\n >\r\n Switch\r\n </src-button>\r\n\r\n <src-button\r\n (onClick)=\"close()\"\r\n [data-testid]=\"'close-lbm-modal'\"\r\n weight=\"primary\"\r\n >\r\n Ok\r\n </src-button>\r\n </div>\r\n </footer>\r\n</div>\r\n", styles: [".src-modal--lbm{width:360px}.src-modal--lbm .src-modal__body{font-size:14px;line-height:24px}.src-modal--lbm .src-modal__buttons{display:flex;gap:8px}\n"] }]
|
|
7240
|
-
}] });
|
|
7241
|
-
|
|
7242
7033
|
class ImageLoadingSrcComponent {
|
|
7243
7034
|
constructor() {
|
|
7244
7035
|
this.#store = inject(Store);
|
|
@@ -7367,6 +7158,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7367
7158
|
args: [{ selector: 'app-unreal-status', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceLoadingComponent], template: "@if (isShowLoadingPercentsPopup()) {\r\n @let _awsInstance = awsInstance();\r\n <div class=\"status-box\">\r\n @if (_awsInstance?.message) {\r\n <p>{{ _awsInstance?.message }}</p>\r\n } @else {\r\n <div class=\"status-box__message\">\r\n <src-loading\r\n [size]=\"30\"\r\n [backgroundStrokeColor]=\"'#E5E7EB'\"\r\n [progressStrokeColor]=\"'#1F2937'\"\r\n />\r\n {{ smoothPercents() }}%\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: ["app-stat-graph{height:30px;width:100%}.status-box{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:5;display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--src-surface-container-main, #fff);border:none;border-radius:var(--src-border-rounded-full, 9999px);box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814;pointer-events:none}.status-box p{padding:10px 15px;margin:0;text-align:center}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--src-text-body-main, #1f2937);font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message src-loading{margin-right:12px}\n"] }]
|
|
7368
7159
|
}] });
|
|
7369
7160
|
|
|
7161
|
+
class SafePipe {
|
|
7162
|
+
constructor() {
|
|
7163
|
+
this.sanitizer = inject(DomSanitizer);
|
|
7164
|
+
}
|
|
7165
|
+
transform(value, type) {
|
|
7166
|
+
if (!value) {
|
|
7167
|
+
return value;
|
|
7168
|
+
}
|
|
7169
|
+
const context = (() => {
|
|
7170
|
+
switch (type) {
|
|
7171
|
+
case 'html':
|
|
7172
|
+
return SecurityContext.HTML;
|
|
7173
|
+
case 'style':
|
|
7174
|
+
return SecurityContext.STYLE;
|
|
7175
|
+
case 'script':
|
|
7176
|
+
return SecurityContext.SCRIPT;
|
|
7177
|
+
case 'url':
|
|
7178
|
+
return SecurityContext.URL;
|
|
7179
|
+
case 'resourceUrl':
|
|
7180
|
+
return SecurityContext.RESOURCE_URL;
|
|
7181
|
+
default:
|
|
7182
|
+
throw new Error(`Invalid safe type specified: ${type}`);
|
|
7183
|
+
}
|
|
7184
|
+
})();
|
|
7185
|
+
// Preserve the published return type while returning Angular-sanitized
|
|
7186
|
+
// content instead of disabling framework security checks.
|
|
7187
|
+
return (this.sanitizer.sanitize(context, value) ?? '');
|
|
7188
|
+
}
|
|
7189
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
7190
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" }); }
|
|
7191
|
+
}
|
|
7192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SafePipe, decorators: [{
|
|
7193
|
+
type: Pipe,
|
|
7194
|
+
args: [{
|
|
7195
|
+
name: 'safe',
|
|
7196
|
+
}]
|
|
7197
|
+
}] });
|
|
7198
|
+
|
|
7370
7199
|
class VideoStatsComponent {
|
|
7371
7200
|
constructor() {
|
|
7372
7201
|
this.collapsed = signal(false, /* @ts-ignore */
|
|
@@ -7404,8 +7233,6 @@ class VideoStatsComponent {
|
|
|
7404
7233
|
}, /* @ts-ignore */
|
|
7405
7234
|
...(ngDevMode ? [{ debugName: "videoStatus" }] : /* istanbul ignore next */ []));
|
|
7406
7235
|
this.fields = [
|
|
7407
|
-
'kalmanBitrate',
|
|
7408
|
-
'bitrateDrop',
|
|
7409
7236
|
'runTime',
|
|
7410
7237
|
'pixelRatio',
|
|
7411
7238
|
'frameHeight',
|
|
@@ -7476,11 +7303,11 @@ class VideoStatsComponent {
|
|
|
7476
7303
|
}));
|
|
7477
7304
|
}
|
|
7478
7305
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: VideoStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7479
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: VideoStatsComponent, isStandalone: true, selector: "app-video-stats", ngImport: i0, template: "@if (videoStatus() && viewportReady()) {\r\n <div class=\"settings-container\">\r\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\r\n <div
|
|
7306
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: VideoStatsComponent, isStandalone: true, selector: "app-video-stats", ngImport: i0, template: "@if (videoStatus() && viewportReady()) {\r\n <div class=\"settings-container\">\r\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\r\n <div (click)=\"toggle()\" [class.min]=\"collapsed()\" id=\"aggregatedStats\">\r\n <div class=\"forNerds\">\r\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"fpsTick()!\"\r\n label=\"FPS (higher is better)\"\r\n />\r\n </li>\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"videoQP()!\"\r\n label=\"QP (lower is better)\"\r\n color=\"#D5ff07\"\r\n />\r\n </li>\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"bitrateTick()!\"\r\n label=\"Bitrate\"\r\n color=\"#D57F07\"\r\n />\r\n </li>\r\n </div>\r\n <div>\r\n @for (graph of graphList(); track graph.key) {\r\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\r\n <app-stat-graph\r\n [label]=\"graph.key\"\r\n [stat]=\"graph.stat()\"\r\n [color]=\"graph.color\"\r\n />\r\n </li>\r\n }\r\n </div>\r\n </div>\r\n\r\n @for (el of videoStatus(); track el.key + $index) {\r\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\r\n <span>{{ el.key }}: </span>{{ el.value | json }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n @if (!collapsed()) {\r\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\r\n }\r\n}\r\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .stat,#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"], dependencies: [{ kind: "component", type: StatGraphComponent, selector: "app-stat-graph", inputs: ["label", "stat", "color", "tickStep"] }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7480
7307
|
}
|
|
7481
7308
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: VideoStatsComponent, decorators: [{
|
|
7482
7309
|
type: Component,
|
|
7483
|
-
args: [{ selector: 'app-video-stats', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StatGraphComponent, JsonPipe, SafePipe], template: "@if (videoStatus() && viewportReady()) {\r\n <div class=\"settings-container\">\r\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\r\n <div
|
|
7310
|
+
args: [{ selector: 'app-video-stats', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StatGraphComponent, JsonPipe, SafePipe], template: "@if (videoStatus() && viewportReady()) {\r\n <div class=\"settings-container\">\r\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\r\n <div (click)=\"toggle()\" [class.min]=\"collapsed()\" id=\"aggregatedStats\">\r\n <div class=\"forNerds\">\r\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"fpsTick()!\"\r\n label=\"FPS (higher is better)\"\r\n />\r\n </li>\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"videoQP()!\"\r\n label=\"QP (lower is better)\"\r\n color=\"#D5ff07\"\r\n />\r\n </li>\r\n <li>\r\n <app-stat-graph\r\n [stat]=\"bitrateTick()!\"\r\n label=\"Bitrate\"\r\n color=\"#D57F07\"\r\n />\r\n </li>\r\n </div>\r\n <div>\r\n @for (graph of graphList(); track graph.key) {\r\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\r\n <app-stat-graph\r\n [label]=\"graph.key\"\r\n [stat]=\"graph.stat()\"\r\n [color]=\"graph.color\"\r\n />\r\n </li>\r\n }\r\n </div>\r\n </div>\r\n\r\n @for (el of videoStatus(); track el.key + $index) {\r\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\r\n <span>{{ el.key }}: </span>{{ el.value | json }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n @if (!collapsed()) {\r\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\r\n }\r\n}\r\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .stat,#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"] }]
|
|
7484
7311
|
}], ctorParameters: () => [] });
|
|
7485
7312
|
|
|
7486
7313
|
class ResumeStreamButtonComponent {
|
|
@@ -7835,185 +7662,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7835
7662
|
args: ['contextmenu', ['$event']]
|
|
7836
7663
|
}] } });
|
|
7837
7664
|
|
|
7838
|
-
class FilterSettingsComponent {
|
|
7839
|
-
constructor() {
|
|
7840
|
-
this.storageKey = 'LBMFilterSettings';
|
|
7841
|
-
this.defaultFilterModel = { ...DefaultFilterModel };
|
|
7842
|
-
this.settings = { ...DefaultFilterModel };
|
|
7843
|
-
}
|
|
7844
|
-
ngOnInit() {
|
|
7845
|
-
const savedSettings = localStorage.getItem(this.storageKey);
|
|
7846
|
-
if (savedSettings) {
|
|
7847
|
-
this.dispatch(JSON.parse(savedSettings));
|
|
7848
|
-
}
|
|
7849
|
-
}
|
|
7850
|
-
togglePanel() {
|
|
7851
|
-
this.settings.panelOpen = !this.settings.panelOpen;
|
|
7852
|
-
this.saveSettings();
|
|
7853
|
-
}
|
|
7854
|
-
saveSettings() {
|
|
7855
|
-
const valid = Object.entries(this.settings).reduce((acc, [key, value]) => {
|
|
7856
|
-
return Truthy(value) ? { ...acc, [key]: value } : acc;
|
|
7857
|
-
}, {});
|
|
7858
|
-
this.dispatch({ ...DefaultFilterModel, ...valid });
|
|
7859
|
-
}
|
|
7860
|
-
dispatch(settings) {
|
|
7861
|
-
try {
|
|
7862
|
-
localStorage.setItem(this.storageKey, JSON.stringify(settings));
|
|
7863
|
-
}
|
|
7864
|
-
catch (e) {
|
|
7865
|
-
Logger.error('Storage not available, Error saving filter settings:', e);
|
|
7866
|
-
}
|
|
7867
|
-
Object.assign(this.settings, settings);
|
|
7868
|
-
Object.assign(FilterModel, settings);
|
|
7869
|
-
}
|
|
7870
|
-
reset() {
|
|
7871
|
-
this.dispatch({
|
|
7872
|
-
...DefaultFilterModel,
|
|
7873
|
-
panelOpen: this.settings.panelOpen,
|
|
7874
|
-
});
|
|
7875
|
-
}
|
|
7876
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FilterSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7877
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FilterSettingsComponent, isStandalone: true, selector: "app-filter-settings", ngImport: i0, template: "<div class=\"settings-container\">\r\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\r\n @if (settings.panelOpen) {\r\n <div class=\"settings-panel\">\r\n <h3>LBM Trigger Settings</h3>\r\n <h5>Data Flow Monitor</h5>\r\n <form>\r\n <label>\r\n Monitoring delay:\r\n <input\r\n [(ngModel)]=\"settings.monitoringDelayTime\"\r\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\r\n type=\"number\"\r\n name=\"monitoringDelayTime\"\r\n />\r\n </label>\r\n\r\n <label>\r\n Minimum Bitrate (kbit/s):\r\n <input\r\n [(ngModel)]=\"settings.minimumBitrate\"\r\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\r\n type=\"number\"\r\n name=\"minimumBitrate\"\r\n />\r\n </label>\r\n <label>\r\n Yellow Flag (%):\r\n <input\r\n [(ngModel)]=\"settings.yellowFlag\"\r\n [placeholder]=\"defaultFilterModel.yellowFlag\"\r\n type=\"number\"\r\n name=\"yellowFlag\"\r\n />\r\n </label>\r\n <label>\r\n Red Flag (%):\r\n <input\r\n [(ngModel)]=\"settings.redFlag\"\r\n [placeholder]=\"defaultFilterModel.redFlag\"\r\n type=\"number\"\r\n name=\"redFlag\"\r\n />\r\n </label>\r\n <label>\r\n Minimum FPS:\r\n <input\r\n [(ngModel)]=\"settings.minimumFps\"\r\n [placeholder]=\"defaultFilterModel.minimumFps\"\r\n type=\"number\"\r\n name=\"minimumFps\"\r\n />\r\n </label>\r\n <hr />\r\n <h5>Kalman Filter</h5>\r\n <label>\r\n Initial Bitrate Estimate (kbit/s):\r\n <input\r\n [(ngModel)]=\"settings.initialBitrateEstimate\"\r\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\r\n type=\"number\"\r\n name=\"initialBitrateEstimate\"\r\n />\r\n </label>\r\n <label>\r\n Initial Error Covariance:\r\n <input\r\n [(ngModel)]=\"settings.initialErrorCovariance\"\r\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\r\n type=\"number\"\r\n name=\"initialErrorCovariance\"\r\n />\r\n </label>\r\n <label>\r\n Process Noise (Q):\r\n <input\r\n [(ngModel)]=\"settings.processNoise\"\r\n [placeholder]=\"defaultFilterModel.processNoise\"\r\n type=\"number\"\r\n name=\"processNoise\"\r\n />\r\n </label>\r\n <label>\r\n Measurement Noise (R):\r\n <input\r\n [(ngModel)]=\"settings.measurementNoise\"\r\n [placeholder]=\"defaultFilterModel.measurementNoise\"\r\n type=\"number\"\r\n name=\"measurementNoise\"\r\n />\r\n </label>\r\n </form>\r\n <br />\r\n <br />\r\n <div class=\"apply-button-container\">\r\n <button (click)=\"reset()\">Reset</button>\r\n <button (click)=\"saveSettings()\">Apply</button>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".settings-container{position:absolute;top:65px;right:10px;z-index:1000}.gear-button{right:0;width:50px;position:absolute;cursor:pointer;font-size:10px;background:none;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#e6f419;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}.settings-panel{font-size:13px;background:#fff;border:1px solid #ccc;padding:15px;margin-top:25px;border-radius:4px;box-shadow:0 2px 8px #0003}.settings-panel h3{margin-top:0}.settings-panel form{display:flex;flex-direction:column}.settings-panel label{margin-bottom:10px;display:flex;flex-direction:column}.settings-panel input{padding:4px;margin-top:4px;border:1px solid #ccc;border-radius:2px}.apply-button-container{position:absolute;bottom:15px;right:15px}.apply-button-container button{padding:6px 12px;border:none;background-color:#1976d2;color:#fff;border-radius:4px;cursor:pointer;margin:2px}.apply-button-container button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number]:not([ngNoCva])[formControlName],input[type=number]:not([ngNoCva])[formControl],input[type=number]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7878
|
-
}
|
|
7879
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FilterSettingsComponent, decorators: [{
|
|
7880
|
-
type: Component,
|
|
7881
|
-
args: [{ selector: 'app-filter-settings', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"settings-container\">\r\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\r\n @if (settings.panelOpen) {\r\n <div class=\"settings-panel\">\r\n <h3>LBM Trigger Settings</h3>\r\n <h5>Data Flow Monitor</h5>\r\n <form>\r\n <label>\r\n Monitoring delay:\r\n <input\r\n [(ngModel)]=\"settings.monitoringDelayTime\"\r\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\r\n type=\"number\"\r\n name=\"monitoringDelayTime\"\r\n />\r\n </label>\r\n\r\n <label>\r\n Minimum Bitrate (kbit/s):\r\n <input\r\n [(ngModel)]=\"settings.minimumBitrate\"\r\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\r\n type=\"number\"\r\n name=\"minimumBitrate\"\r\n />\r\n </label>\r\n <label>\r\n Yellow Flag (%):\r\n <input\r\n [(ngModel)]=\"settings.yellowFlag\"\r\n [placeholder]=\"defaultFilterModel.yellowFlag\"\r\n type=\"number\"\r\n name=\"yellowFlag\"\r\n />\r\n </label>\r\n <label>\r\n Red Flag (%):\r\n <input\r\n [(ngModel)]=\"settings.redFlag\"\r\n [placeholder]=\"defaultFilterModel.redFlag\"\r\n type=\"number\"\r\n name=\"redFlag\"\r\n />\r\n </label>\r\n <label>\r\n Minimum FPS:\r\n <input\r\n [(ngModel)]=\"settings.minimumFps\"\r\n [placeholder]=\"defaultFilterModel.minimumFps\"\r\n type=\"number\"\r\n name=\"minimumFps\"\r\n />\r\n </label>\r\n <hr />\r\n <h5>Kalman Filter</h5>\r\n <label>\r\n Initial Bitrate Estimate (kbit/s):\r\n <input\r\n [(ngModel)]=\"settings.initialBitrateEstimate\"\r\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\r\n type=\"number\"\r\n name=\"initialBitrateEstimate\"\r\n />\r\n </label>\r\n <label>\r\n Initial Error Covariance:\r\n <input\r\n [(ngModel)]=\"settings.initialErrorCovariance\"\r\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\r\n type=\"number\"\r\n name=\"initialErrorCovariance\"\r\n />\r\n </label>\r\n <label>\r\n Process Noise (Q):\r\n <input\r\n [(ngModel)]=\"settings.processNoise\"\r\n [placeholder]=\"defaultFilterModel.processNoise\"\r\n type=\"number\"\r\n name=\"processNoise\"\r\n />\r\n </label>\r\n <label>\r\n Measurement Noise (R):\r\n <input\r\n [(ngModel)]=\"settings.measurementNoise\"\r\n [placeholder]=\"defaultFilterModel.measurementNoise\"\r\n type=\"number\"\r\n name=\"measurementNoise\"\r\n />\r\n </label>\r\n </form>\r\n <br />\r\n <br />\r\n <div class=\"apply-button-container\">\r\n <button (click)=\"reset()\">Reset</button>\r\n <button (click)=\"saveSettings()\">Apply</button>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".settings-container{position:absolute;top:65px;right:10px;z-index:1000}.gear-button{right:0;width:50px;position:absolute;cursor:pointer;font-size:10px;background:none;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#e6f419;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}.settings-panel{font-size:13px;background:#fff;border:1px solid #ccc;padding:15px;margin-top:25px;border-radius:4px;box-shadow:0 2px 8px #0003}.settings-panel h3{margin-top:0}.settings-panel form{display:flex;flex-direction:column}.settings-panel label{margin-bottom:10px;display:flex;flex-direction:column}.settings-panel input{padding:4px;margin-top:4px;border:1px solid #ccc;border-radius:2px}.apply-button-container{position:absolute;bottom:15px;right:15px}.apply-button-container button{padding:6px 12px;border:none;background-color:#1976d2;color:#fff;border-radius:4px;cursor:pointer;margin:2px}.apply-button-container button:hover{background-color:#1565c0}\n"] }]
|
|
7882
|
-
}] });
|
|
7883
|
-
|
|
7884
|
-
class LowBandwidthStateService {
|
|
7885
|
-
constructor() {
|
|
7886
|
-
this.#isLowBandwidth = signal(false, /* @ts-ignore */
|
|
7887
|
-
...(ngDevMode ? [{ debugName: "#isLowBandwidth" }] : /* istanbul ignore next */ []));
|
|
7888
|
-
this.isLowBandwidth = this.#isLowBandwidth.asReadonly();
|
|
7889
|
-
this.isLowBandwidth$ = toObservable(this.isLowBandwidth);
|
|
7890
|
-
}
|
|
7891
|
-
#isLowBandwidth;
|
|
7892
|
-
enterLowBandwidthMode() {
|
|
7893
|
-
this.#isLowBandwidth.set(true);
|
|
7894
|
-
}
|
|
7895
|
-
exitLowBandwidthMode() {
|
|
7896
|
-
this.#isLowBandwidth.set(false);
|
|
7897
|
-
}
|
|
7898
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
7899
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthStateService, providedIn: 'root' }); }
|
|
7900
|
-
}
|
|
7901
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthStateService, decorators: [{
|
|
7902
|
-
type: Injectable,
|
|
7903
|
-
args: [{ providedIn: 'root' }]
|
|
7904
|
-
}] });
|
|
7905
|
-
|
|
7906
|
-
class LowBandwidthDetectorComponent {
|
|
7907
|
-
constructor() {
|
|
7908
|
-
this.#store = inject(Store);
|
|
7909
|
-
this.dialog = inject(Dialog);
|
|
7910
|
-
this.destroyRef = inject(DestroyRef);
|
|
7911
|
-
this.videoService = inject(VideoService);
|
|
7912
|
-
this.lowBandwidthState = inject(LowBandwidthStateService);
|
|
7913
|
-
this.isDevMode = inject(DevModeService).isDevMode;
|
|
7914
|
-
this.viewportReady$ = this.#store.select(unrealFeature.selectViewportReady);
|
|
7915
|
-
this.isLowBandwidth$ = this.lowBandwidthState.isLowBandwidth$;
|
|
7916
|
-
this.lowBandwidthTrigger$ = this.isLowBandwidth$.pipe(distinctUntilChanged$1(), filter(Truthy));
|
|
7917
|
-
this.highBandwidthTrigger$ = this.isLowBandwidth$.pipe(distinctUntilChanged$1(), filter(Falsy));
|
|
7918
|
-
this.viewPortDestroyedTrigger$ = this.viewportReady$.pipe(distinctUntilChanged$1(), filter(Falsy));
|
|
7919
|
-
this.aggregatedStats$ = this.videoService.videoStats$.pipe(map((data) => data.aggregatedStats), share());
|
|
7920
|
-
this.nativeQuality$ = this.videoService.videoStats$.pipe(map((data) => data.quality));
|
|
7921
|
-
this.monitoringTrigger$ = this.viewportReady$
|
|
7922
|
-
.pipe(combineLatestWith(this.isLowBandwidth$), map(([viewPortReady, isLowBandwidth]) => viewPortReady && !isLowBandwidth))
|
|
7923
|
-
.pipe(share());
|
|
7924
|
-
this.reTrigger$ = this.monitoringTrigger$.pipe(map(() => ({ quality: 'lime' })));
|
|
7925
|
-
this.canSwitchToLowBand$ = this.monitoringTrigger$.pipe(debounceTime(100), switchMap((canSwitch) => concat(of(false), timer(FilterModel.monitoringDelayTime).pipe(map(() => canSwitch))).pipe(take(2), takeUntil$1(this.monitoringTrigger$))), distinctUntilChanged$1(), share());
|
|
7926
|
-
this.videoQuality$ = merge(this.nativeQuality$, this.reTrigger$).pipe(share(), takeUntil$1(this.viewPortDestroyedTrigger$));
|
|
7927
|
-
this.fps$ = this.aggregatedStats$.pipe(map((data) => data.framesPerSecond || 0));
|
|
7928
|
-
this.bitrateDrop$ = this.aggregatedStats$.pipe(map((data) => data.dataFlowCheckResult), filter((br) => br.isDropDetected), takeUntil$1(merge(this.viewPortDestroyedTrigger$, this.reTrigger$)));
|
|
7929
|
-
this.fps = toSignal(this.fps$, { initialValue: 0 });
|
|
7930
|
-
this.nativeQuality = toSignal(this.nativeQuality$);
|
|
7931
|
-
this.isLowBandwidth = this.lowBandwidthState.isLowBandwidth;
|
|
7932
|
-
this.aggregatedStats = toSignal(this.aggregatedStats$);
|
|
7933
|
-
this.isReducedQuality = signal(false, /* @ts-ignore */
|
|
7934
|
-
...(ngDevMode ? [{ debugName: "isReducedQuality" }] : /* istanbul ignore next */ []));
|
|
7935
|
-
this.isIndicatorExpanded = signal(false, /* @ts-ignore */
|
|
7936
|
-
...(ngDevMode ? [{ debugName: "isIndicatorExpanded" }] : /* istanbul ignore next */ []));
|
|
7937
|
-
this.isIndicatorExpandedTrigger$ = toObservable(this.isIndicatorExpanded).pipe(skip(1), distinctUntilChanged$1(), filter(Falsy));
|
|
7938
|
-
}
|
|
7939
|
-
#store;
|
|
7940
|
-
ngOnInit() {
|
|
7941
|
-
this.lowBandwidthTrigger$
|
|
7942
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
7943
|
-
.subscribe(() => this.toggleIndicator(true));
|
|
7944
|
-
merge(this.viewPortDestroyedTrigger$, this.highBandwidthTrigger$)
|
|
7945
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
7946
|
-
.subscribe(() => this.isReducedQuality.set(false));
|
|
7947
|
-
this.canSwitchToLowBand$
|
|
7948
|
-
.pipe(filter(Truthy), tap(() => {
|
|
7949
|
-
BITRATE_MONITOR.reset();
|
|
7950
|
-
this.isReducedQuality.set(false);
|
|
7951
|
-
}), switchMap(() => this.bitrateDrop$), tap(this.trySetLowBandwidth.bind(this)), map((dataFlowResult) => dataFlowResult?.isDropDetected), distinctUntilChanged$1(), tap(() => {
|
|
7952
|
-
this.isReducedQuality.set(true);
|
|
7953
|
-
}), switchMap(() => this.videoQuality$), filter((quality) => quality === 'lime'), tap(() => this.isReducedQuality.set(false)), takeUntilDestroyed(this.destroyRef))
|
|
7954
|
-
.subscribe();
|
|
7955
|
-
}
|
|
7956
|
-
trySetLowBandwidth(dataFlowResult) {
|
|
7957
|
-
// Evaluate FPS and native quality
|
|
7958
|
-
const isFpsLow = this.fps() < FilterModel.minimumFps;
|
|
7959
|
-
const isNativeQualityRed = this.nativeQuality() === 'red';
|
|
7960
|
-
const shouldSwitch = isNativeQualityRed || isFpsLow;
|
|
7961
|
-
// Exit if conditions are not met or already in low bandwidth
|
|
7962
|
-
if (!shouldSwitch || this.isLowBandwidth())
|
|
7963
|
-
return;
|
|
7964
|
-
const { quality, activeMedian } = dataFlowResult;
|
|
7965
|
-
const isQualityRed = quality === 'red';
|
|
7966
|
-
const isLowBitrate = activeMedian < FilterModel.minimumBitrate;
|
|
7967
|
-
// Final check for a red drop or low bitrate, or low FPS
|
|
7968
|
-
if (isQualityRed || isLowBitrate || isFpsLow) {
|
|
7969
|
-
let reason;
|
|
7970
|
-
if (isFpsLow) {
|
|
7971
|
-
reason = `FPS < ${FilterModel.minimumFps}`;
|
|
7972
|
-
}
|
|
7973
|
-
else if (quality === 'red') {
|
|
7974
|
-
reason = `Drop > ${FilterModel.redFlag}%`;
|
|
7975
|
-
}
|
|
7976
|
-
else {
|
|
7977
|
-
reason = `Speed < ${FilterModel.minimumBitrate}`;
|
|
7978
|
-
}
|
|
7979
|
-
Logger.info(`LBM DETECTED: ${reason}, switching to low bandwidth; `, dataFlowResult.message, {
|
|
7980
|
-
stats: {
|
|
7981
|
-
dataFlowResult,
|
|
7982
|
-
reason,
|
|
7983
|
-
triggerTime: this.aggregatedStats()?.runTime ?? 0,
|
|
7984
|
-
},
|
|
7985
|
-
});
|
|
7986
|
-
this.lowBandwidthState.enterLowBandwidthMode();
|
|
7987
|
-
}
|
|
7988
|
-
}
|
|
7989
|
-
toggleIndicator(value) {
|
|
7990
|
-
this.isIndicatorExpanded.set(value);
|
|
7991
|
-
if (value) {
|
|
7992
|
-
this.hideIndicatorAfterDelay();
|
|
7993
|
-
}
|
|
7994
|
-
}
|
|
7995
|
-
hideIndicatorAfterDelay() {
|
|
7996
|
-
timer(3000)
|
|
7997
|
-
.pipe(take(1), takeUntil$1(this.isIndicatorExpandedTrigger$))
|
|
7998
|
-
.subscribe(() => this.toggleIndicator(false));
|
|
7999
|
-
}
|
|
8000
|
-
openLBMDialog() {
|
|
8001
|
-
this.dialog
|
|
8002
|
-
.open(LowBandwidthModalComponent)
|
|
8003
|
-
.closed.pipe(filter(Truthy))
|
|
8004
|
-
.subscribe(() => {
|
|
8005
|
-
this.lowBandwidthState.exitLowBandwidthMode();
|
|
8006
|
-
this.toggleIndicator(false);
|
|
8007
|
-
});
|
|
8008
|
-
}
|
|
8009
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthDetectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8010
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: LowBandwidthDetectorComponent, isStandalone: true, selector: "app-low-bandwidth-detector", ngImport: i0, template: "@if (isReducedQuality() || isLowBandwidth()) {\r\n <div\r\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\r\n class=\"lbm-indicator freeze-loader\"\r\n >\r\n <button (click)=\"toggleIndicator(true)\" class=\"lbm-icon\" type=\"button\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\r\n <path\r\n fill=\"#85888E\"\r\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\r\n />\r\n <path\r\n fill=\"#fff\"\r\n fill-rule=\"evenodd\"\r\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\r\n clip-rule=\"evenodd\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div\r\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\r\n class=\"lbm-message\"\r\n >\r\n <p class=\"lbm-description\">\r\n Fluid Interactivity Modes were disabled due to an unstable connection.\r\n\r\n <button\r\n (click)=\"openLBMDialog()\"\r\n [attr.data-testid]=\"'learn-more-lbm'\"\r\n type=\"button\"\r\n class=\"lbm-learn-more\"\r\n >\r\n Learn more\r\n </button>\r\n </p>\r\n <button\r\n (click)=\"toggleIndicator(false)\"\r\n [attr.data-testid]=\"'close-lbm-indicator'\"\r\n type=\"button\"\r\n class=\"lbm-close\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 20 20\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n}\r\n\r\n@if (isDevMode) {\r\n <app-filter-settings />\r\n}\r\n", styles: [".freeze-loader,.lbm-indicator{--lbmPositionTop: 18px;--lbmPositionLeft: 18px;--lbmPositionRight: 18px;--lbmIndicatorSize: 36px;--lbmIndicatorBorderRadius: 8px;--lbmIndicatorCloseSize: 20px;--lbmPadding: 10px;--lbmTextSize: 13px;--lbmLineHeight: 20px;--lbmTextColor: #ffffff;--lbmBackgroundColor: rgba(17, 24, 39, .7);position:absolute;top:var(--lbmPositionTop);left:var(--lbmPositionLeft);z-index:10;display:flex;justify-content:center;align-items:flex-start;min-width:var(--lbmIndicatorSize);min-height:var(--lbmIndicatorSize);overflow:hidden}.freeze-loader.expanded,.lbm-indicator.expanded{--lbmPositionTop: 8px;--lbmPositionLeft: 8px;--lbmPositionRight: 8px;width:auto;max-width:calc(100% - var(--lbmPositionLeft) - var(--lbmPositionRight));padding:var(--lbmPadding);background:var(--lbmBackgroundColor);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:var(--lbmIndicatorBorderRadius);gap:12px}.freeze-loader .lbm-icon,.lbm-indicator .lbm-icon{display:flex;width:var(--lbmIndicatorSize);height:var(--lbmIndicatorSize);padding:8px;color:#fff;background-color:var(--lbmBackgroundColor);border-radius:50%;flex-shrink:0;cursor:pointer}.freeze-loader .lbm-icon svg,.freeze-loader .lbm-icon img,.lbm-indicator .lbm-icon svg,.lbm-indicator .lbm-icon img{width:100%;height:100%}.freeze-loader .lbm-close,.lbm-indicator .lbm-close{position:absolute;top:0;right:0;width:var(--lbmIndicatorCloseSize);height:var(--lbmIndicatorCloseSize);background-color:transparent;border:none;padding:0;cursor:pointer}.freeze-loader .lbm-message,.lbm-indicator .lbm-message{position:relative;opacity:0;height:0;max-width:0;padding-right:24px;pointer-events:none;visibility:hidden;animation:closeMessage .3s forwards}.freeze-loader .lbm-message--open,.lbm-indicator .lbm-message--open{position:relative;visibility:visible;display:flex;align-items:center;align-self:center;pointer-events:all;gap:12px;max-width:fit-content;height:auto;opacity:1;animation:openMessage .3s forwards}.freeze-loader .lbm-description,.lbm-indicator .lbm-description{margin:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor)}.freeze-loader .lbm-learn-more,.lbm-indicator .lbm-learn-more{display:inline-flex;padding:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor);text-decoration-line:underline;background-color:transparent;border:none;cursor:pointer}.freeze-loader .lbm-learn-more:hover,.lbm-indicator .lbm-learn-more:hover{text-decoration:none}@keyframes openMessage{0%{opacity:0;max-width:0;height:0}10%{height:auto;max-width:fit-content}to{opacity:1;height:auto;max-width:fit-content}}@keyframes closeMessage{0%{opacity:1;max-width:fit-content}to{opacity:0;max-width:0}}\n"], dependencies: [{ kind: "component", type: FilterSettingsComponent, selector: "app-filter-settings" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8011
|
-
}
|
|
8012
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LowBandwidthDetectorComponent, decorators: [{
|
|
8013
|
-
type: Component,
|
|
8014
|
-
args: [{ selector: 'app-low-bandwidth-detector', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FilterSettingsComponent], template: "@if (isReducedQuality() || isLowBandwidth()) {\r\n <div\r\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\r\n class=\"lbm-indicator freeze-loader\"\r\n >\r\n <button (click)=\"toggleIndicator(true)\" class=\"lbm-icon\" type=\"button\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\r\n <path\r\n fill=\"#85888E\"\r\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\r\n />\r\n <path\r\n fill=\"#fff\"\r\n fill-rule=\"evenodd\"\r\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\r\n clip-rule=\"evenodd\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div\r\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\r\n class=\"lbm-message\"\r\n >\r\n <p class=\"lbm-description\">\r\n Fluid Interactivity Modes were disabled due to an unstable connection.\r\n\r\n <button\r\n (click)=\"openLBMDialog()\"\r\n [attr.data-testid]=\"'learn-more-lbm'\"\r\n type=\"button\"\r\n class=\"lbm-learn-more\"\r\n >\r\n Learn more\r\n </button>\r\n </p>\r\n <button\r\n (click)=\"toggleIndicator(false)\"\r\n [attr.data-testid]=\"'close-lbm-indicator'\"\r\n type=\"button\"\r\n class=\"lbm-close\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 20 20\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n}\r\n\r\n@if (isDevMode) {\r\n <app-filter-settings />\r\n}\r\n", styles: [".freeze-loader,.lbm-indicator{--lbmPositionTop: 18px;--lbmPositionLeft: 18px;--lbmPositionRight: 18px;--lbmIndicatorSize: 36px;--lbmIndicatorBorderRadius: 8px;--lbmIndicatorCloseSize: 20px;--lbmPadding: 10px;--lbmTextSize: 13px;--lbmLineHeight: 20px;--lbmTextColor: #ffffff;--lbmBackgroundColor: rgba(17, 24, 39, .7);position:absolute;top:var(--lbmPositionTop);left:var(--lbmPositionLeft);z-index:10;display:flex;justify-content:center;align-items:flex-start;min-width:var(--lbmIndicatorSize);min-height:var(--lbmIndicatorSize);overflow:hidden}.freeze-loader.expanded,.lbm-indicator.expanded{--lbmPositionTop: 8px;--lbmPositionLeft: 8px;--lbmPositionRight: 8px;width:auto;max-width:calc(100% - var(--lbmPositionLeft) - var(--lbmPositionRight));padding:var(--lbmPadding);background:var(--lbmBackgroundColor);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:var(--lbmIndicatorBorderRadius);gap:12px}.freeze-loader .lbm-icon,.lbm-indicator .lbm-icon{display:flex;width:var(--lbmIndicatorSize);height:var(--lbmIndicatorSize);padding:8px;color:#fff;background-color:var(--lbmBackgroundColor);border-radius:50%;flex-shrink:0;cursor:pointer}.freeze-loader .lbm-icon svg,.freeze-loader .lbm-icon img,.lbm-indicator .lbm-icon svg,.lbm-indicator .lbm-icon img{width:100%;height:100%}.freeze-loader .lbm-close,.lbm-indicator .lbm-close{position:absolute;top:0;right:0;width:var(--lbmIndicatorCloseSize);height:var(--lbmIndicatorCloseSize);background-color:transparent;border:none;padding:0;cursor:pointer}.freeze-loader .lbm-message,.lbm-indicator .lbm-message{position:relative;opacity:0;height:0;max-width:0;padding-right:24px;pointer-events:none;visibility:hidden;animation:closeMessage .3s forwards}.freeze-loader .lbm-message--open,.lbm-indicator .lbm-message--open{position:relative;visibility:visible;display:flex;align-items:center;align-self:center;pointer-events:all;gap:12px;max-width:fit-content;height:auto;opacity:1;animation:openMessage .3s forwards}.freeze-loader .lbm-description,.lbm-indicator .lbm-description{margin:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor)}.freeze-loader .lbm-learn-more,.lbm-indicator .lbm-learn-more{display:inline-flex;padding:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor);text-decoration-line:underline;background-color:transparent;border:none;cursor:pointer}.freeze-loader .lbm-learn-more:hover,.lbm-indicator .lbm-learn-more:hover{text-decoration:none}@keyframes openMessage{0%{opacity:0;max-width:0;height:0}10%{height:auto;max-width:fit-content}to{opacity:1;height:auto;max-width:fit-content}}@keyframes closeMessage{0%{opacity:1;max-width:fit-content}to{opacity:0;max-width:0}}\n"] }]
|
|
8015
|
-
}] });
|
|
8016
|
-
|
|
8017
7665
|
/**
|
|
8018
7666
|
* Registers the Unreal NgRx feature state. Call this ONCE at the application
|
|
8019
7667
|
* root.
|
|
@@ -8060,5 +7708,5 @@ function provideUnrealModule() {
|
|
|
8060
7708
|
* Generated bundle index. Do not edit.
|
|
8061
7709
|
*/
|
|
8062
7710
|
|
|
8063
|
-
export { AFKService, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS,
|
|
7711
|
+
export { AFKService, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, INNER_RETRY_LIMIT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, MINIMAL_FPS, MIN_CONTAINER_SIZE, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RECONNECT_CONFIG, REGION_PING_ACCURATE_SAMPLES, REGION_PING_BACKGROUND_REFRESH_DELAY_MS, REGION_PING_CACHE_KEY, REGION_PING_CACHE_TTL_MS, REGION_PING_WARMUP_DEADLINE_MS, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, UNREAL_CONFIG, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealSceneComponent, UnrealStatusMessage, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCode_UNKNOWN, WSCloseCodes, WS_OPEN_STATE, WS_RETRY_PER_INSTANCE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, answerSent, changeStatusMainVideoOnScene, changeStreamResolutionAction, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, floatToPercents, floatToSmoothPercents, forceResizeViewport, fromResizeObserver, getActiveUrl, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, iceConnectionFailed, initSignalling, instanceReady, keepMaxUntilReset, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, saveAnalyticsEvent, selectCirrusConnectionId, selectClientAndViewIds, selectCommandProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsFullyConnected, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectUserInactivityDetected, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setUserInactivityTimeout, setViewportNotReady, setViewportReady, showLoadingProgress, showResumeStreamPopup, showUnrealErrorMessage, showUserInactivityTimeoutPopup, signalingRetryAttempted, smoothTransition, startStream, streamAdopted, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
|
|
8064
7712
|
//# sourceMappingURL=3dsource-angular-unreal-module.mjs.map
|