@3dsource/angular-unreal-module 0.0.106-dev.0 → 0.0.106-dev.1

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.
@@ -1622,10 +1622,14 @@ class AFKService extends SubService {
1622
1622
  this.countdown = 0; // The inactivity warning overlay has a countdown to show time until disconnect.
1623
1623
  this.selectWarnTimeout = this.store.selectSignal(selectWarnTimeout);
1624
1624
  this.isViewportReady = this.store.selectSignal(unrealFeature.selectViewportReady);
1625
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
1625
1626
  this.destroyRef.onDestroy(() => this.clearTimers());
1626
1627
  this.init();
1627
1628
  }
1628
1629
  init() {
1630
+ if (this.unrealConfig?.playwright) {
1631
+ return;
1632
+ }
1629
1633
  merge(this.store.select(selectWarnTimeout), this.actions$.pipe(ofType(resetAfk)))
1630
1634
  .pipe(withLatestFrom(this.store.select(unrealFeature.selectViewportReady)), filter(([, viewportReady]) => viewportReady), takeUntil(this.destroy$))
1631
1635
  .subscribe(() => this.resetAfkWarningTimer());
@@ -1717,9 +1721,13 @@ class FreezeFrameService extends SubService {
1717
1721
  this.receiving = false;
1718
1722
  this.size = 0;
1719
1723
  this.freezeFrameOverlay = new Image();
1724
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
1720
1725
  this.init();
1721
1726
  }
1722
1727
  init() {
1728
+ if (this.unrealConfig?.playwright) {
1729
+ return;
1730
+ }
1723
1731
  this.store
1724
1732
  .select(unrealFeature.selectViewportReady)
1725
1733
  .pipe(filter(Truthy), takeUntil(this.destroy$))
@@ -2087,13 +2095,14 @@ class CommandTelemetryService {
2087
2095
  this.commandSequenceNumber = 0;
2088
2096
  this.payloads = [];
2089
2097
  this.httpClient = inject(HttpClient);
2090
- this.unrealInitialConfig = inject(UNREAL_CONFIG, {
2098
+ this.unrealConfig = inject(UNREAL_CONFIG, {
2091
2099
  optional: true,
2092
2100
  });
2093
2101
  this.init();
2094
2102
  }
2095
2103
  init() {
2096
- if (!this.unrealInitialConfig?.commandTelemetryReceiver) {
2104
+ if (!this.unrealConfig?.commandTelemetryReceiver ||
2105
+ this.unrealConfig?.playwright) {
2097
2106
  return;
2098
2107
  }
2099
2108
  this.reset();
@@ -2205,7 +2214,7 @@ class CommandTelemetryService {
2205
2214
  };
2206
2215
  const lastIndex = payload[payload.length - 1].commandSequenceNumber;
2207
2216
  this.httpClient
2208
- .post(this.unrealInitialConfig?.commandTelemetryReceiver || '', out)
2217
+ .post(this.unrealConfig?.commandTelemetryReceiver || '', out)
2209
2218
  .pipe(catchError(() => of(null)), take(1))
2210
2219
  .subscribe(() => {
2211
2220
  this.payloads = this.payloads.filter((p) => p.commandSequenceNumber > lastIndex);
@@ -2510,6 +2519,7 @@ class SignallingService extends SubService {
2510
2519
  this.httpClient = inject(HttpClient);
2511
2520
  this.regionsPingService = inject(RegionsPingService);
2512
2521
  this.commandTelemetryService = inject(CommandTelemetryService);
2522
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
2513
2523
  this.region = signal('', ...(ngDevMode ? [{ debugName: "region" }] : /* istanbul ignore next */ []));
2514
2524
  this.selectClientAndViewIds = this.store.selectSignal(selectClientAndViewIds);
2515
2525
  this.environmentId = this.store.selectSignal(unrealFeature.selectEnvironmentId);
@@ -2526,6 +2536,9 @@ class SignallingService extends SubService {
2526
2536
  this.init();
2527
2537
  }
2528
2538
  init() {
2539
+ if (this.unrealConfig?.playwright) {
2540
+ return;
2541
+ }
2529
2542
  this.setHandlersFromStream();
2530
2543
  this.action$.pipe(ofType(dataChannelReady)).subscribe(() => {
2531
2544
  this.send({
@@ -2546,6 +2559,13 @@ class SignallingService extends SubService {
2546
2559
  });
2547
2560
  }
2548
2561
  connectToSignaling(urlList) {
2562
+ if (this.unrealConfig?.playwright) {
2563
+ this.store.dispatch(setUnrealPlaywrightConfig());
2564
+ this.store.dispatch(dataChannelConnected({
2565
+ statusMessage: 'Playwright set data channel connected',
2566
+ }));
2567
+ return EMPTY;
2568
+ }
2549
2569
  Logger.log('CONNECT TO SIGNALLING');
2550
2570
  // Preparation for WebSocket Orchestration
2551
2571
  this.correlationId = generateUuid();
@@ -3297,9 +3317,13 @@ class FileReceiverService extends SubService {
3297
3317
  this.receiving = false;
3298
3318
  this.extension = '';
3299
3319
  this.data = [];
3320
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
3300
3321
  this.init();
3301
3322
  }
3302
3323
  init() {
3324
+ if (this.unrealConfig?.playwright) {
3325
+ return;
3326
+ }
3303
3327
  this.store
3304
3328
  .select(unrealFeature.selectViewportReady)
3305
3329
  .pipe(filter(Truthy))
@@ -3408,11 +3432,14 @@ class AggregatorService extends SubService {
3408
3432
  this.webrtcPlayer = inject(WebRtcPlayerService);
3409
3433
  this.freezeFrame = inject(FreezeFrameService);
3410
3434
  this.fileReceiver = inject(FileReceiverService);
3411
- this.unrealInitialConfig = inject(UNREAL_CONFIG);
3435
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
3412
3436
  this.responseEventListeners = new Map();
3413
3437
  this.init();
3414
3438
  }
3415
3439
  init() {
3440
+ if (this.unrealConfig?.playwright) {
3441
+ return;
3442
+ }
3416
3443
  this.listenWebRTC();
3417
3444
  this.initialize();
3418
3445
  }
@@ -3464,7 +3491,7 @@ class AggregatorService extends SubService {
3464
3491
  }
3465
3492
  removeLoadScreen() {
3466
3493
  document
3467
- .getElementById(this.unrealInitialConfig?.screenLockerContainerId ||
3494
+ .getElementById(this.unrealConfig?.screenLockerContainerId ||
3468
3495
  SCREEN_LOCKER_CONTAINER_ID)
3469
3496
  ?.remove();
3470
3497
  }
@@ -3588,11 +3615,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
3588
3615
  }], ctorParameters: () => [] });
3589
3616
 
3590
3617
  class ConsoleExtensionsService extends SubService {
3591
- #httpClient = inject(HttpClient);
3592
- #commandsSender = inject(UnrealCommunicatorService);
3593
- #isDevMode = inject(DevModeService).isDevMode;
3618
+ #httpClient;
3619
+ #commandsSender;
3620
+ #isDevMode;
3594
3621
  constructor() {
3595
3622
  super();
3623
+ this.#httpClient = inject(HttpClient);
3624
+ this.#commandsSender = inject(UnrealCommunicatorService);
3625
+ this.#isDevMode = inject(DevModeService).isDevMode;
3626
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
3596
3627
  this.init();
3597
3628
  // Clean up window properties on destroyRef
3598
3629
  this.destroyRef.onDestroy(() => {
@@ -3611,7 +3642,7 @@ class ConsoleExtensionsService extends SubService {
3611
3642
  });
3612
3643
  }
3613
3644
  init() {
3614
- if (!this.#isDevMode) {
3645
+ if (!this.#isDevMode || this.unrealConfig?.playwright) {
3615
3646
  return;
3616
3647
  }
3617
3648
  window.dropConnection = () => {
@@ -3702,11 +3733,13 @@ class UnrealCommunicatorService {
3702
3733
  this.actions$ = inject(Actions);
3703
3734
  this.commandTelemetryService = inject(CommandTelemetryService);
3704
3735
  this.webRtcPlayerService = inject(WebRtcPlayerService);
3736
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
3705
3737
  this.destroy$ = new Subject();
3706
3738
  this.cirrusConnected = this.store.selectSignal(unrealFeature.selectCirrusConnected);
3707
3739
  this.init();
3708
3740
  }
3709
3741
  init() {
3742
+ this.isPlaywrightMode();
3710
3743
  this.emitUIInteraction = this.commandTelemetryService.decorate(this.emitUIInteraction.bind(this));
3711
3744
  // Listen to the dataChannelConnected ACTION (point-in-time event) instead
3712
3745
  // of the store selector. The selector reads the current state and can fire on
@@ -3724,6 +3757,7 @@ class UnrealCommunicatorService {
3724
3757
  this.destroy$ = new Subject();
3725
3758
  }
3726
3759
  sendCommandToUnreal(data) {
3760
+ this.isPlaywrightMode();
3727
3761
  if (this.webRtcPlayerService.canSend()) {
3728
3762
  const uniqId = data?.correlationId ?? generateUuid();
3729
3763
  const sendData = { ...data, correlationId: uniqId };
@@ -3750,6 +3784,7 @@ class UnrealCommunicatorService {
3750
3784
  this.emitDescriptor(MessageType.Command, descriptor);
3751
3785
  }
3752
3786
  sendInputData(data) {
3787
+ this.isPlaywrightMode();
3753
3788
  try {
3754
3789
  this.store.dispatch(resetAfk());
3755
3790
  this.webRtcPlayerService.send(data);
@@ -3760,6 +3795,11 @@ class UnrealCommunicatorService {
3760
3795
  }
3761
3796
  }
3762
3797
  }
3798
+ isPlaywrightMode() {
3799
+ if (this.unrealConfig?.playwright) {
3800
+ return;
3801
+ }
3802
+ }
3763
3803
  emitDescriptor(messageType, descriptor) {
3764
3804
  // Convert the descriptor object into a JSON string.
3765
3805
  const descriptorAsString = JSON.stringify(descriptor);
@@ -3797,6 +3837,7 @@ class InputService extends SubService {
3797
3837
  this.commandsSender = inject(UnrealCommunicatorService);
3798
3838
  this.isDevMode = inject(DevModeService).isDevMode;
3799
3839
  this.videoService = inject(VideoService);
3840
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
3800
3841
  this.defaultKeys = [
3801
3842
  KeyboardNumericCode.KeyW,
3802
3843
  KeyboardNumericCode.KeyS,
@@ -3830,6 +3871,9 @@ class InputService extends SubService {
3830
3871
  this.init();
3831
3872
  }
3832
3873
  init() {
3874
+ if (this.unrealConfig?.playwright) {
3875
+ return;
3876
+ }
3833
3877
  const visibilityHiddenTrigger$ = fromEvent(document, 'visibilitychange').pipe(map$1(() => document.visibilityState === 'hidden'), filter(Truthy));
3834
3878
  const visibilityVisibleTrigger$ = fromEvent(document, 'visibilitychange').pipe(map$1(() => document.visibilityState === 'visible'), filter(Truthy), startWith(true));
3835
3879
  this.deactivatedVideoTrigger$ = merge(this.disconnect$, this.reInit$, visibilityHiddenTrigger$);
@@ -4373,12 +4417,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
4373
4417
  }] });
4374
4418
 
4375
4419
  class StreamStatusTelemetryService {
4376
- #store = inject(Store);
4377
- #videoService = inject(VideoService);
4420
+ #store;
4421
+ #videoService;
4378
4422
  constructor() {
4423
+ this.#store = inject(Store);
4424
+ this.#videoService = inject(VideoService);
4425
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
4379
4426
  this.init();
4380
4427
  }
4381
4428
  init() {
4429
+ if (this.unrealConfig?.playwright) {
4430
+ return;
4431
+ }
4382
4432
  this.#videoService.videoStats$
4383
4433
  .pipe(withLatestFrom(this.#store.select(unrealFeature.selectAwsInstance), this.#store.select(unrealFeature.selectLowBandwidth), this.#store.select(unrealFeature.selectLowBandwidthStats), this.#store.select(unrealFeature.selectCirrusConnected)), auditTime(5000), filter(([, , , , cirrusConnected]) => cirrusConnected), map$1(([data, signalingServer, isLowBandwidth, lbmStats]) => this.mapEventData(data, signalingServer, isLowBandwidth, lbmStats)))
4384
4434
  .subscribe((data) => this.trackEventToMixPanel(data));
@@ -4412,10 +4462,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
4412
4462
  type: Injectable
4413
4463
  }], ctorParameters: () => [] });
4414
4464
 
4415
- /*
4416
- * Copyright (c) 2026.
4417
- * 3DSource.com. Sergii Karanda steve@3dsource.com. All Rights Reserved.
4418
- */
4419
4465
  class WebRtcPlayerService2 extends SubService {
4420
4466
  constructor() {
4421
4467
  super();
@@ -4469,7 +4515,7 @@ class WebRtcPlayerService2 extends SubService {
4469
4515
  * Creates a new peer connection, applies the remote offer,
4470
4516
  * then responds with an SDP answer.
4471
4517
  *
4472
- * The DataChannel is NOT created here — the server creates it
4518
+ * The DataChannel is NOT created here — the server creates it,
4473
4519
  * and we receive it via the `datachannel` event on the peer connection.
4474
4520
  */
4475
4521
  async handleServerOffer(offer) {
@@ -4688,13 +4734,13 @@ class WebRtcPlayerService2 extends SubService {
4688
4734
  }
4689
4735
  else {
4690
4736
  Logger.colored('black', 'yellow', `DataChannel connection not prepared or in state: ${this.dcClient?.readyState}`);
4691
- // Trigger peer reconnection if DC is not open and we're not already reconnecting
4737
+ // Trigger peer reconnection if DC is not open and we're not yet reconnecting
4692
4738
  this.tryReconnectOnSendFailure();
4693
4739
  }
4694
4740
  }
4695
4741
  /**
4696
4742
  * Attempts to reconnect the peer when send fails due to DataChannel not being open.
4697
- * This handles cases where the DC connection is broken but no error events are fired.
4743
+ * This handles cases where the DC connection is broken, but no error events are fired.
4698
4744
  */
4699
4745
  tryReconnectOnSendFailure() {
4700
4746
  // Skip if already reconnecting or signaling is not connected
@@ -4923,7 +4969,7 @@ class WebRtcPlayerService2 extends SubService {
4923
4969
  this.store.dispatch(dataChannelConnected({ statusMessage }));
4924
4970
  }
4925
4971
  /**
4926
- * Creates an SDP offer, applies SDP munging, sets it as local description,
4972
+ * Creates an SDP offer, applies SDP munging, sets it as a local description,
4927
4973
  * and sends it to the server via signaling.
4928
4974
  * Transceivers already configure media directions, so deprecated
4929
4975
  * offerToReceive* options are not used.
@@ -4940,7 +4986,7 @@ class WebRtcPlayerService2 extends SubService {
4940
4986
  }
4941
4987
  }
4942
4988
  /**
4943
- * Creates an SDP answer, applies SDP munging, sets it as local description,
4989
+ * Creates an SDP answer, applies SDP munging, sets it as a local description,
4944
4990
  * and sends it to the server via signaling.
4945
4991
  */
4946
4992
  async createAnswer(pcClient) {
@@ -4961,115 +5007,136 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
4961
5007
  type: Injectable
4962
5008
  }], ctorParameters: () => [] });
4963
5009
 
4964
- class AfkPlaywrightService extends AFKService {
4965
- init() {
4966
- return;
4967
- }
4968
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AfkPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
4969
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AfkPlaywrightService }); }
4970
- }
4971
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AfkPlaywrightService, decorators: [{
4972
- type: Injectable
4973
- }] });
5010
+ const ReceivedMimeTypes = {
5011
+ ApplicationJson: 'application/json',
5012
+ };
4974
5013
 
4975
- class SignallingPlaywrightService extends SignallingService {
5014
+ class FileHandlerService {
4976
5015
  constructor() {
4977
- super();
4978
- }
4979
- init() {
4980
- return;
5016
+ this.fileService = inject(FileReceiverService);
5017
+ this.fileHandlers = {
5018
+ [ReceivedMimeTypes.ApplicationJson]: this.handleJsonFile.bind(this),
5019
+ };
4981
5020
  }
4982
- connectToSignaling() {
4983
- this.store.dispatch(setUnrealPlaywrightConfig());
4984
- this.store.dispatch(dataChannelConnected({
4985
- statusMessage: 'Playwright set data channel connected',
5021
+ handleJsonFile(data, correlationId) {
5022
+ const { blob } = data;
5023
+ return from(blob.text()).pipe(map$1((text) => JSON.parse(text)), filter(({ commandCallback }) => {
5024
+ return commandCallback.correlationId === correlationId;
4986
5025
  }));
4987
- return EMPTY;
4988
- }
4989
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SignallingPlaywrightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4990
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SignallingPlaywrightService }); }
4991
- }
4992
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SignallingPlaywrightService, decorators: [{
4993
- type: Injectable
4994
- }], ctorParameters: () => [] });
4995
-
4996
- class UnrealCommunicatorPlaywrightService extends UnrealCommunicatorService {
4997
- init() {
4998
- return;
4999
5026
  }
5000
- sendCommandToUnreal() {
5001
- return;
5002
- }
5003
- sendInputData() {
5004
- return;
5005
- }
5006
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UnrealCommunicatorPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5007
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UnrealCommunicatorPlaywrightService }); }
5008
- }
5009
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UnrealCommunicatorPlaywrightService, decorators: [{
5010
- type: Injectable
5011
- }] });
5012
-
5013
- class AggregatorPlaywrightService extends AggregatorService {
5014
- init() {
5015
- return;
5016
- }
5017
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AggregatorPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5018
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AggregatorPlaywrightService }); }
5019
- }
5020
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AggregatorPlaywrightService, decorators: [{
5021
- type: Injectable
5022
- }] });
5023
-
5024
- class FreezeFramePlaywrightService extends FreezeFrameService {
5025
- init() {
5026
- return;
5027
+ observeFileResponse(mimetype, data, sender, timeOut = 60000) {
5028
+ const correlationId = generateUuid();
5029
+ const out = { ...data, correlationId };
5030
+ const observable = this.fileService.fileComplete$.pipe(switchMap((data) => {
5031
+ if (data.valid && this.fileHandlers[mimetype]) {
5032
+ return this.fileHandlers[mimetype](data, correlationId).pipe(filter(Truthy));
5033
+ }
5034
+ return of(null);
5035
+ }), timeout(timeOut), catchError((e) => {
5036
+ Logger.error(e);
5037
+ return of(null);
5038
+ }), take(1));
5039
+ setTimeout(() => sender(out), 0);
5040
+ return observable;
5027
5041
  }
5028
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FreezeFramePlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5029
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FreezeFramePlaywrightService }); }
5042
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5043
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService }); }
5030
5044
  }
5031
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FreezeFramePlaywrightService, decorators: [{
5045
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService, decorators: [{
5032
5046
  type: Injectable
5033
5047
  }] });
5034
5048
 
5035
- class CommandTelemetryPlaywrightService extends CommandTelemetryService {
5036
- init() {
5037
- return;
5049
+ class AnalyticsService extends SubService {
5050
+ #store = inject(Store);
5051
+ /** Signals monitorMouse inner subscriptions to stop (viewport lost / new session). */
5052
+ #stopMouse$ = new Subject();
5053
+ sendEventToMixPanel(name, params = {}) {
5054
+ Logger.log('Analytics Event:', name, params);
5055
+ this.#store.dispatch(saveAnalyticsEvent({ event: { name, params } }));
5038
5056
  }
5039
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CommandTelemetryPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5040
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CommandTelemetryPlaywrightService }); }
5041
- }
5042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CommandTelemetryPlaywrightService, decorators: [{
5043
- type: Injectable
5044
- }] });
5045
-
5046
- class StreamStatusTelemetryPlaywrightService extends StreamStatusTelemetryService {
5047
- init() {
5048
- return;
5057
+ constructor() {
5058
+ super();
5059
+ const abortSignal$ = this.#store
5060
+ .select(unrealFeature.selectViewportReady)
5061
+ .pipe(filter$1(Falsy), map(() => void 0));
5062
+ this.#store
5063
+ .select(unrealFeature.selectViewportReady)
5064
+ .pipe(distinctUntilChanged(), filter$1(Truthy), tap(() => this.monitorMouse(abortSignal$)))
5065
+ .subscribe();
5049
5066
  }
5050
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StreamStatusTelemetryPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5051
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StreamStatusTelemetryPlaywrightService }); }
5052
- }
5053
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StreamStatusTelemetryPlaywrightService, decorators: [{
5054
- type: Injectable
5055
- }] });
5056
-
5057
- class ConsoleExtensionsPlaywrightService extends ConsoleExtensionsService {
5058
- init() {
5059
- return;
5067
+ monitorMouse(abortSignal$) {
5068
+ this.#stopMouse$.next();
5069
+ const stop$ = merge(this.#stopMouse$.asObservable(), abortSignal$);
5070
+ const element = document.getElementById('streamingVideo');
5071
+ if (!element) {
5072
+ return;
5073
+ }
5074
+ // Monitor mousewheel events
5075
+ const mousewheel$ = fromEvent(element, 'wheel').pipe(takeUntil$1(stop$), throttleTime(1000));
5076
+ // Monitor mouse button states
5077
+ const mousedown$ = fromEvent(element, 'mousedown').pipe(takeUntil$1(stop$));
5078
+ const touchStart$ = fromEvent(element, 'touchstart').pipe(takeUntil$1(stop$));
5079
+ const touchMove$ = fromEvent(element, 'touchmove').pipe(takeUntil$1(stop$), throttleTime(200));
5080
+ // Track mouse movement while the left or right button is pressed
5081
+ mousedown$
5082
+ .pipe(filter$1((event) => event.button === 0 || event.button === 2), tap((downEvent) => {
5083
+ this.sendEventToMixPanel('mouse_interaction', {
5084
+ viewX: downEvent.clientX / element.clientWidth,
5085
+ viewY: downEvent.clientY / element.clientHeight,
5086
+ action: downEvent.button === 0 ? 'spinning' : 'panning',
5087
+ });
5088
+ }))
5089
+ .subscribe();
5090
+ // Track mouse movement while the left or right button is pressed
5091
+ touchStart$
5092
+ .pipe(tap((downEvent) => {
5093
+ const totalTouches = downEvent.touches.length;
5094
+ const touch = downEvent.touches[0];
5095
+ this.sendEventToMixPanel('touch_interaction', {
5096
+ viewX: touch.clientX / element.clientWidth,
5097
+ viewY: touch.clientY / element.clientHeight,
5098
+ action: totalTouches === 1 ? 'spinning' : 'panning',
5099
+ });
5100
+ }))
5101
+ .subscribe();
5102
+ let initialTouchDistance = 0;
5103
+ // Subscribe to mousewheel events
5104
+ touchMove$.subscribe((event) => {
5105
+ const totalTouches = event.touches.length;
5106
+ if (totalTouches < 2) {
5107
+ return;
5108
+ }
5109
+ // Calculate the current distance between two touches
5110
+ const touch1 = event.touches[0];
5111
+ const touch2 = event.touches[1];
5112
+ const currentDistance = Math.sqrt(Math.pow(touch2.clientX - touch1.clientX, 2) +
5113
+ Math.pow(touch2.clientY - touch1.clientY, 2));
5114
+ // Determine if zooming in or out based on distance change
5115
+ const deltaDistance = currentDistance - initialTouchDistance;
5116
+ const isZoomingIn = deltaDistance > 0;
5117
+ // Only send event if there's a significant change (avoid noise)
5118
+ if (Math.abs(deltaDistance) > 10) {
5119
+ this.sendEventToMixPanel('touch_zoom_interaction', {
5120
+ delta: isZoomingIn ? 1 : -1,
5121
+ action: isZoomingIn ? 'zoomin' : 'zoomout',
5122
+ });
5123
+ // Update initial distance for next comparison
5124
+ initialTouchDistance = currentDistance;
5125
+ }
5126
+ });
5127
+ mousewheel$.subscribe((event) => {
5128
+ this.sendEventToMixPanel('mouse_zoom_interaction', {
5129
+ delta: -(event.deltaY / Math.abs(event.deltaY)),
5130
+ action: event.deltaY < 0 ? 'zoomin' : 'zoomout',
5131
+ });
5132
+ });
5060
5133
  }
5061
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ConsoleExtensionsPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5062
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ConsoleExtensionsPlaywrightService }); }
5134
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5135
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService }); }
5063
5136
  }
5064
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ConsoleExtensionsPlaywrightService, decorators: [{
5137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService, decorators: [{
5065
5138
  type: Injectable
5066
- }] });
5067
-
5068
- class FileReceiverPlaywrightService extends FileReceiverService {
5069
- init() {
5070
- return;
5071
- }
5072
- }
5139
+ }], ctorParameters: () => [] });
5073
5140
 
5074
5141
  /**
5075
5142
  * Adaptive FPS controller that monitors the incoming WebRTC video stream
@@ -5148,6 +5215,7 @@ class FpsMonitorService {
5148
5215
  constructor() {
5149
5216
  this.videoService = inject(VideoService);
5150
5217
  this.store = inject(Store);
5218
+ this.unrealConfig = inject(UNREAL_CONFIG, { optional: true });
5151
5219
  /** Discrete FPS targets the controller can switch between (ascending order). */
5152
5220
  this.FPS_STEPS = [30, 40, 50, 60];
5153
5221
  /** Reference ceiling for bitrate (bits/sec) used to normalize a bitrate load to 0..1. */
@@ -5185,6 +5253,9 @@ class FpsMonitorService {
5185
5253
  this.init();
5186
5254
  }
5187
5255
  init() {
5256
+ if (this.unrealConfig?.playwright || !this.unrealConfig?.fpsMonitor) {
5257
+ return;
5258
+ }
5188
5259
  // Reset mutable state and re-subscribe when a new session starts
5189
5260
  this.store
5190
5261
  .select(unrealFeature.selectViewportReady)
@@ -5426,159 +5497,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
5426
5497
  type: Injectable
5427
5498
  }], ctorParameters: () => [] });
5428
5499
 
5429
- class FpsMonitorEmptyService extends FpsMonitorService {
5430
- init() {
5431
- return;
5432
- }
5433
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FpsMonitorEmptyService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5434
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FpsMonitorEmptyService }); }
5435
- }
5436
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FpsMonitorEmptyService, decorators: [{
5437
- type: Injectable
5438
- }] });
5439
-
5440
- class InputPlaywrightService extends InputService {
5441
- init() {
5442
- return;
5443
- }
5444
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: InputPlaywrightService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
5445
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: InputPlaywrightService }); }
5446
- }
5447
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: InputPlaywrightService, decorators: [{
5448
- type: Injectable
5449
- }] });
5450
-
5451
- const ReceivedMimeTypes = {
5452
- ApplicationJson: 'application/json',
5453
- };
5454
-
5455
- class FileHandlerService {
5456
- constructor() {
5457
- this.fileService = inject(FileReceiverService);
5458
- this.fileHandlers = {
5459
- [ReceivedMimeTypes.ApplicationJson]: this.handleJsonFile.bind(this),
5460
- };
5461
- }
5462
- handleJsonFile(data, correlationId) {
5463
- const { blob } = data;
5464
- return from(blob.text()).pipe(map$1((text) => JSON.parse(text)), filter(({ commandCallback }) => {
5465
- return commandCallback.correlationId === correlationId;
5466
- }));
5467
- }
5468
- observeFileResponse(mimetype, data, sender, timeOut = 60000) {
5469
- const correlationId = generateUuid();
5470
- const out = { ...data, correlationId };
5471
- const observable = this.fileService.fileComplete$.pipe(switchMap((data) => {
5472
- if (data.valid && this.fileHandlers[mimetype]) {
5473
- return this.fileHandlers[mimetype](data, correlationId).pipe(filter(Truthy));
5474
- }
5475
- return of(null);
5476
- }), timeout(timeOut), catchError((e) => {
5477
- Logger.error(e);
5478
- return of(null);
5479
- }), take(1));
5480
- setTimeout(() => sender(out), 0);
5481
- return observable;
5482
- }
5483
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5484
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService }); }
5485
- }
5486
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FileHandlerService, decorators: [{
5487
- type: Injectable
5488
- }] });
5489
-
5490
- class AnalyticsService extends SubService {
5491
- #store = inject(Store);
5492
- /** Signals monitorMouse inner subscriptions to stop (viewport lost / new session). */
5493
- #stopMouse$ = new Subject();
5494
- sendEventToMixPanel(name, params = {}) {
5495
- Logger.log('Analytics Event:', name, params);
5496
- this.#store.dispatch(saveAnalyticsEvent({ event: { name, params } }));
5497
- }
5498
- constructor() {
5499
- super();
5500
- const abortSignal$ = this.#store
5501
- .select(unrealFeature.selectViewportReady)
5502
- .pipe(filter$1(Falsy), map(() => void 0));
5503
- this.#store
5504
- .select(unrealFeature.selectViewportReady)
5505
- .pipe(distinctUntilChanged(), filter$1(Truthy), tap(() => this.monitorMouse(abortSignal$)))
5506
- .subscribe();
5507
- }
5508
- monitorMouse(abortSignal$) {
5509
- this.#stopMouse$.next();
5510
- const stop$ = merge(this.#stopMouse$.asObservable(), abortSignal$);
5511
- const element = document.getElementById('streamingVideo');
5512
- if (!element) {
5513
- return;
5514
- }
5515
- // Monitor mousewheel events
5516
- const mousewheel$ = fromEvent(element, 'wheel').pipe(takeUntil$1(stop$), throttleTime(1000));
5517
- // Monitor mouse button states
5518
- const mousedown$ = fromEvent(element, 'mousedown').pipe(takeUntil$1(stop$));
5519
- const touchStart$ = fromEvent(element, 'touchstart').pipe(takeUntil$1(stop$));
5520
- const touchMove$ = fromEvent(element, 'touchmove').pipe(takeUntil$1(stop$), throttleTime(200));
5521
- // Track mouse movement while the left or right button is pressed
5522
- mousedown$
5523
- .pipe(filter$1((event) => event.button === 0 || event.button === 2), tap((downEvent) => {
5524
- this.sendEventToMixPanel('mouse_interaction', {
5525
- viewX: downEvent.clientX / element.clientWidth,
5526
- viewY: downEvent.clientY / element.clientHeight,
5527
- action: downEvent.button === 0 ? 'spinning' : 'panning',
5528
- });
5529
- }))
5530
- .subscribe();
5531
- // Track mouse movement while the left or right button is pressed
5532
- touchStart$
5533
- .pipe(tap((downEvent) => {
5534
- const totalTouches = downEvent.touches.length;
5535
- const touch = downEvent.touches[0];
5536
- this.sendEventToMixPanel('touch_interaction', {
5537
- viewX: touch.clientX / element.clientWidth,
5538
- viewY: touch.clientY / element.clientHeight,
5539
- action: totalTouches === 1 ? 'spinning' : 'panning',
5540
- });
5541
- }))
5542
- .subscribe();
5543
- let initialTouchDistance = 0;
5544
- // Subscribe to mousewheel events
5545
- touchMove$.subscribe((event) => {
5546
- const totalTouches = event.touches.length;
5547
- if (totalTouches < 2) {
5548
- return;
5549
- }
5550
- // Calculate the current distance between two touches
5551
- const touch1 = event.touches[0];
5552
- const touch2 = event.touches[1];
5553
- const currentDistance = Math.sqrt(Math.pow(touch2.clientX - touch1.clientX, 2) +
5554
- Math.pow(touch2.clientY - touch1.clientY, 2));
5555
- // Determine if zooming in or out based on distance change
5556
- const deltaDistance = currentDistance - initialTouchDistance;
5557
- const isZoomingIn = deltaDistance > 0;
5558
- // Only send event if there's a significant change (avoid noise)
5559
- if (Math.abs(deltaDistance) > 10) {
5560
- this.sendEventToMixPanel('touch_zoom_interaction', {
5561
- delta: isZoomingIn ? 1 : -1,
5562
- action: isZoomingIn ? 'zoomin' : 'zoomout',
5563
- });
5564
- // Update initial distance for next comparison
5565
- initialTouchDistance = currentDistance;
5566
- }
5567
- });
5568
- mousewheel$.subscribe((event) => {
5569
- this.sendEventToMixPanel('mouse_zoom_interaction', {
5570
- delta: -(event.deltaY / Math.abs(event.deltaY)),
5571
- action: event.deltaY < 0 ? 'zoomin' : 'zoomout',
5572
- });
5573
- });
5574
- }
5575
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5576
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService }); }
5577
- }
5578
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AnalyticsService, decorators: [{
5579
- type: Injectable
5580
- }], ctorParameters: () => [] });
5581
-
5582
5500
  class UnrealCallbackService {
5583
5501
  constructor() {
5584
5502
  this.actions$ = inject(Actions);
@@ -6197,10 +6115,7 @@ class UnrealSceneComponent {
6197
6115
  this.videoService = inject(VideoService);
6198
6116
  this.element = inject(ElementRef);
6199
6117
  this.destroyRef = inject(DestroyRef);
6200
- this.destroyRef.onDestroy(() => {
6201
- console.log('DEBUG: UnrealSceneComponent destroyed');
6202
- this.#store.dispatch(destroyUnrealScene());
6203
- });
6118
+ this.destroyRef.onDestroy(() => this.#store.dispatch(destroyUnrealScene()));
6204
6119
  effect(() => {
6205
6120
  const videoElement = this.videoElement();
6206
6121
  const isExistMatchUrls = this.isExistMatchUrls();
@@ -6526,7 +6441,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
6526
6441
  args: [{ selector: 'app-low-bandwidth-detector', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FilterSettingsComponent], template: "@if (isReducedQuality() || isLowBandwidth()) {\n <div\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\n class=\"lbm-indicator freeze-loader\"\n >\n <div (click)=\"toggleIndicator(true)\" class=\"lbm-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\n <path\n fill=\"#85888E\"\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\"\n />\n <path\n fill=\"#fff\"\n fill-rule=\"evenodd\"\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\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n\n <div\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\n class=\"lbm-message\"\n >\n <p class=\"lbm-description\">\n Fluid Interactivity Modes were disabled due to an unstable connection.\n\n <button\n (click)=\"openLBMDialog()\"\n [attr.data-testid]=\"'learn-more-lbm'\"\n type=\"button\"\n class=\"lbm-learn-more\"\n >\n Learn more\n </button>\n </p>\n <button\n (click)=\"toggleIndicator(false)\"\n [attr.data-testid]=\"'close-lbm-indicator'\"\n type=\"button\"\n class=\"lbm-close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\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\"\n fill=\"white\"\n />\n </svg>\n </button>\n </div>\n </div>\n}\n\n@if (isDevMode) {\n <app-filter-settings />\n}\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"] }]
6527
6442
  }] });
6528
6443
 
6529
- function provideUnrealModule(config) {
6444
+ function provideUnrealModule() {
6530
6445
  return makeEnvironmentProviders([
6531
6446
  provideState(commandsFeature),
6532
6447
  provideState(unrealFeature),
@@ -6539,69 +6454,22 @@ function provideUnrealModule(config) {
6539
6454
  FileHandlerService,
6540
6455
  AnalyticsService,
6541
6456
  UnrealCallbackService,
6457
+ CommandTelemetryService,
6458
+ AggregatorService,
6459
+ FreezeFrameService,
6460
+ UnrealCommunicatorService,
6461
+ AFKService,
6462
+ SignallingService,
6463
+ StreamStatusTelemetryService,
6464
+ FpsMonitorService,
6542
6465
  {
6543
6466
  provide: WebRtcPlayerService,
6544
- useClass: config?.newWebRtcConnector
6545
- ? WebRtcPlayerService2
6546
- : WebRtcPlayerService,
6547
- },
6548
- {
6549
- provide: FpsMonitorService,
6550
- useClass: config?.playwright || !config?.fpsMonitor
6551
- ? FpsMonitorEmptyService
6552
- : FpsMonitorService,
6553
- },
6554
- {
6555
- provide: StreamStatusTelemetryService,
6556
- useClass: config?.playwright
6557
- ? StreamStatusTelemetryPlaywrightService
6558
- : StreamStatusTelemetryService,
6559
- },
6560
- {
6561
- provide: CommandTelemetryService,
6562
- useClass: config?.playwright
6563
- ? CommandTelemetryPlaywrightService
6564
- : CommandTelemetryService,
6565
- },
6566
- {
6567
- provide: AggregatorService,
6568
- useClass: config?.playwright
6569
- ? AggregatorPlaywrightService
6570
- : AggregatorService,
6571
- },
6572
- {
6573
- provide: FreezeFrameService,
6574
- useClass: config?.playwright
6575
- ? FreezeFramePlaywrightService
6576
- : FreezeFrameService,
6577
- },
6578
- {
6579
- provide: UnrealCommunicatorService,
6580
- useClass: config?.playwright
6581
- ? UnrealCommunicatorPlaywrightService
6582
- : UnrealCommunicatorService,
6583
- },
6584
- {
6585
- provide: AFKService,
6586
- useClass: config?.playwright ? AfkPlaywrightService : AFKService,
6587
- },
6588
- {
6589
- provide: SignallingService,
6590
- useClass: config?.playwright
6591
- ? SignallingPlaywrightService
6592
- : SignallingService,
6593
- },
6594
- {
6595
- provide: ConsoleExtensionsService,
6596
- useClass: config?.playwright
6597
- ? ConsoleExtensionsPlaywrightService
6598
- : ConsoleExtensionsService,
6599
- },
6600
- {
6601
- provide: FileReceiverService,
6602
- useClass: config?.playwright
6603
- ? FileReceiverPlaywrightService
6604
- : FileReceiverService,
6467
+ useFactory: () => {
6468
+ const config = inject(UNREAL_CONFIG, { optional: true });
6469
+ return config?.newWebRtcConnector
6470
+ ? new WebRtcPlayerService2()
6471
+ : new WebRtcPlayerService();
6472
+ },
6605
6473
  },
6606
6474
  provideEnvironmentInitializer(() => {
6607
6475
  inject(AggregatorService);
@@ -6620,5 +6488,5 @@ function provideUnrealModule(config) {
6620
6488
  * Generated bundle index. Do not edit.
6621
6489
  */
6622
6490
 
6623
- export { AFKService, AfkPlaywrightService, AfkTimeoutModalComponent, AggregatorPlaywrightService, AggregatorService, AnalyticsService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, CommandTelemetryPlaywrightService, CommandTelemetryService, CommandsEffects, ConfigHandler, ConsoleExtensionsPlaywrightService, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DEFAULT_RECONNECT_DELAY_MS, DEFAULT_RECONNECT_ENABLED, DEFAULT_RECONNECT_MAX_ATTEMPTS, DEFAULT_RECONNECT_ON_DATACHANNEL_CLOSE, DEFAULT_RECONNECT_ON_ICE_FAILURE, DataFlowMonitor, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverPlaywrightService, FileReceiverService, FilterSettingsComponent, FpsMonitorEmptyService, FpsMonitorService, FreezeFrameComponent, FreezeFramePlaywrightService, FreezeFrameService, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputPlaywrightService, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MessageType, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingPlaywrightService, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryPlaywrightService, StreamStatusTelemetryService, SubService, ToClientMessage, UNREAL_CONFIG, UnrealCallbackService, UnrealCommunicatorPlaywrightService, 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_TIMEOUT, WebRtcPlayerService, WebRtcPlayerService2, WebrtcErrorModalComponent, abortEstablishingConnection, changeLowBandwidth, changeStatusMainVideoOnScene, changeStreamResolutionAction, changeStreamResolutionSuccessAction, commandCompleted, commandStarted, commandsFeature, commandsReducer, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, floatToSmoothPercents, forceResizeViewport, fromResizeObserver, getActiveUrl, getImageFromVideoStream, getResizeStudioValues, getResizeStudioValuesOld, getResizeValuesUniversal, getResizeValuesUniversalOld, getRtcErrorMessage, iceConnectionFailed, initSignalling, keepMaxUntilReset, makeEven, provideUnrealModule, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetWarnTimeout, saveAnalyticsEvent, selectClientAndViewIds, selectCommandProgress, selectCommandsInProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setDataChannelConnected, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setKalmanSettings, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setViewportNotReady, setViewportReady, showUnrealErrorMessage, smoothTransition, startStream, trackMixpanelEvent, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
6491
+ export { AFKService, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, CommandTelemetryService, CommandsEffects, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DEFAULT_RECONNECT_DELAY_MS, DEFAULT_RECONNECT_ENABLED, DEFAULT_RECONNECT_MAX_ATTEMPTS, DEFAULT_RECONNECT_ON_DATACHANNEL_CLOSE, DEFAULT_RECONNECT_ON_ICE_FAILURE, DataFlowMonitor, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, FileHandlerService, FileReceiverService, FilterSettingsComponent, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MessageType, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryService, 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_TIMEOUT, WebRtcPlayerService, WebRtcPlayerService2, WebrtcErrorModalComponent, abortEstablishingConnection, changeLowBandwidth, changeStatusMainVideoOnScene, changeStreamResolutionAction, changeStreamResolutionSuccessAction, commandCompleted, commandStarted, commandsFeature, commandsReducer, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, floatToSmoothPercents, forceResizeViewport, fromResizeObserver, getActiveUrl, getImageFromVideoStream, getResizeStudioValues, getResizeStudioValuesOld, getResizeValuesUniversal, getResizeValuesUniversalOld, getRtcErrorMessage, iceConnectionFailed, initSignalling, keepMaxUntilReset, makeEven, provideUnrealModule, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetWarnTimeout, saveAnalyticsEvent, selectClientAndViewIds, selectCommandProgress, selectCommandsInProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsExistMatchUrls, selectIsFreezeFrameLoading, selectIsLoaderScreenVisible, selectIsVideoPlayingAndDataChannelConnected, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectWarnTimeout, setAfkTimerCountdown, setAfkTimerHide, setAfkTimerVisible, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setDataChannelConnected, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setKalmanSettings, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMaxFps, setOrchestrationContext, setOrchestrationMessage, setOrchestrationParameters, setOrchestrationProgress, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setUnrealPlaywrightConfig, setViewportNotReady, setViewportReady, showUnrealErrorMessage, smoothTransition, startStream, trackMixpanelEvent, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
6624
6492
  //# sourceMappingURL=3dsource-angular-unreal-module.mjs.map