@3dsource/angular-unreal-module 0.0.187 → 0.0.188

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
File without changes
@@ -3,10 +3,10 @@ import { input, output, ChangeDetectionStrategy, Component, inject, DestroyRef,
3
3
  import { NgTemplateOutlet, NgOptimizedImage, JsonPipe } from '@angular/common';
4
4
  import { createAction, props, createReducer, on, createFeature, createSelector, Store, provideState } from '@ngrx/store';
5
5
  import { Actions, ofType, createEffect, provideEffects } from '@ngrx/effects';
6
- import { Subject, skip, share, timer, of, take, defer, switchMap, from, throwError, Observable, EMPTY, retry, merge, timeout as timeout$1, repeat, BehaviorSubject, interval, map as map$1, takeUntil as takeUntil$1, fromEvent, tap as tap$1, throttleTime, delay, concat, debounceTime, mergeMap, NEVER, ignoreElements, startWith, scan, timestamp, pairwise, concatMap, animationFrameScheduler, shareReplay, firstValueFrom, asyncScheduler, filter as filter$1, withLatestFrom as withLatestFrom$1, Subscription, bufferTime, combineLatestWith } from 'rxjs';
6
+ import { Subject, skip, share, timer, of, take, defer, switchMap, from, throwError, Observable, EMPTY, retry, merge, timeout as timeout$1, repeat, BehaviorSubject, interval, map as map$1, takeUntil as takeUntil$1, fromEvent, tap as tap$1, throttleTime, delay, concat, debounceTime, mergeMap, startWith, takeWhile, NEVER, ignoreElements, scan, timestamp, pairwise, concatMap, animationFrameScheduler, shareReplay, firstValueFrom, asyncScheduler, filter as filter$1, withLatestFrom as withLatestFrom$1, Subscription, bufferTime, combineLatestWith } from 'rxjs';
7
7
  import { UNREAL_CONFIG } from '@3dsource/angular-unreal-module/config';
8
8
  export { UNREAL_CONFIG } from '@3dsource/angular-unreal-module/config';
9
- import { tap, filter, takeUntil, catchError, map, timeout, finalize, first, switchMap as switchMap$1, distinctUntilChanged, withLatestFrom, exhaustMap, takeWhile, debounceTime as debounceTime$1, take as take$1, startWith as startWith$1 } from 'rxjs/operators';
9
+ import { tap, filter, takeUntil, catchError, map, timeout, finalize, first, switchMap as switchMap$1, distinctUntilChanged, withLatestFrom, exhaustMap, takeWhile as takeWhile$1, debounceTime as debounceTime$1, take as take$1, startWith as startWith$1 } from 'rxjs/operators';
10
10
  import { v4 } from 'uuid';
11
11
  import { DialogRef, DIALOG_DATA, Dialog } from '@angular/cdk/dialog';
12
12
  import { HttpClient } from '@angular/common/http';
@@ -673,6 +673,13 @@ const RECONNECT_CONFIG = {
673
673
  maxAttempts: 3,
674
674
  delayMs: 1000,
675
675
  };
676
+ // Full-signalling restarts after consecutive DataChannelTimeouts. The limit is
677
+ // read at every timeout: a hidden tab gives up sooner, since nobody watches it
678
+ // and each attempt occupies a streaming instance.
679
+ const DATA_CHANNEL_TIMEOUT_RESTARTS = {
680
+ hidden: 3,
681
+ visible: 10,
682
+ };
676
683
  const UnrealStatusMessage = {
677
684
  CONNECTING_TO_SESSION: 'Connecting to session.',
678
685
  STARTING_YOUR_SESSION: 'Starting your session',
@@ -3708,6 +3715,12 @@ class WebRtcPlayerService extends SubService {
3708
3715
  canSend() {
3709
3716
  return this.dcClient && this.dcClient.readyState === 'open';
3710
3717
  }
3718
+ describeConnectionState() {
3719
+ const pc = this.pcClient;
3720
+ return pc
3721
+ ? `signaling=${pc.signalingState}, ice=${pc.iceConnectionState}, connection=${pc.connectionState}`
3722
+ : 'no peer connection';
3723
+ }
3711
3724
  send(data) {
3712
3725
  if (this.canSend()) {
3713
3726
  this.dcClient?.send(data);
@@ -4529,7 +4542,8 @@ class UnrealEffects {
4529
4542
  mergeMap(() => EMPTY),
4530
4543
  // ⏱️ Only actual timeout (or real upstream error) ends up here.
4531
4544
  catchError(() => {
4532
- const error = `⏱️ DataChannel connection timeout ${this.dataChannelConnectionTimeout}ms, requesting new signaling.`;
4545
+ const details = `${document.visibilityState}; ${this.webRtcPlayerService.describeConnectionState()}`;
4546
+ const error = `⏱️ DataChannel connection timeout ${this.dataChannelConnectionTimeout}ms (${details}).`;
4533
4547
  Logger.error(error);
4534
4548
  const body = {
4535
4549
  awsInstance,
@@ -4553,7 +4567,7 @@ class UnrealEffects {
4553
4567
  // map response to the destroy action that ngrx will dispatch
4554
4568
  map$1(() => disconnectStream({
4555
4569
  reason: DisconnectReason.DataChannelTimeout,
4556
- message: 'Data Channel Timeout',
4570
+ message: `Data Channel Timeout (${details})`,
4557
4571
  })));
4558
4572
  }));
4559
4573
  }));
@@ -4585,8 +4599,28 @@ class UnrealEffects {
4585
4599
  this.webRtcPlayerService.releaseRemoteConnections(reason);
4586
4600
  }), filter(({ reason }) => reason === DisconnectReason.DropConnection), map$1(() => dropConnection()));
4587
4601
  });
4588
- this.destroyConnectionAndRestart$ = createEffect(() => {
4589
- return this.actions$.pipe(ofType(setCirrusDisconnected), withLatestFrom(this.store.select(unrealFeature.selectDisconnectReason)), filter(([, reason]) => reason === DisconnectReason.DataChannelTimeout), map$1(() => initSignalling()));
4602
+ /**
4603
+ * Restarts signalling after a DataChannelTimeout, a limited number of times.
4604
+ *
4605
+ * The counter is the index inside one restart window. A window opens on load,
4606
+ * on a successful data channel, on the user's `startStream` and on a scene
4607
+ * destroy, so only consecutive failures count. Once the limit for the current
4608
+ * tab visibility is reached, `establishingConnection` is cleared and the
4609
+ * resume popup shows.
4610
+ */
4611
+ this.restartAfterDataChannelTimeout$ = createEffect(() => {
4612
+ const timeoutDrops$ = this.actions$.pipe(ofType(setCirrusDisconnected), withLatestFrom(this.store.select(unrealFeature.selectDisconnectReason)), filter(([, reason]) => reason === DisconnectReason.DataChannelTimeout));
4613
+ return this.actions$.pipe(ofType(dataChannelConnected, startStream, destroyUnrealScene), startWith(null), switchMap(() => timeoutDrops$.pipe(map$1((_, attempt) => {
4614
+ const limit = document.hidden
4615
+ ? DATA_CHANNEL_TIMEOUT_RESTARTS.hidden
4616
+ : DATA_CHANNEL_TIMEOUT_RESTARTS.visible;
4617
+ if (attempt < limit) {
4618
+ Logger.warn(`[Restart] DataChannelTimeout, restart ${attempt + 1}/${limit}`);
4619
+ return initSignalling();
4620
+ }
4621
+ Logger.error(`[Restart] DataChannelTimeout, giving up after ${attempt} restarts`);
4622
+ return setEstablishingConnection({ value: false });
4623
+ }), takeWhile((action) => action.type === initSignalling.type, true))));
4590
4624
  });
4591
4625
  this.showUnrealError$ = createEffect(() => {
4592
4626
  return this.actions$.pipe(ofType(showUnrealErrorMessage), map$1(({ code }) => getRtcErrorMessage(code)), distinctUntilChanged(), filter(Truthy), exhaustMap((content) => this.dialog.open(UnrealErrorModalComponent, {
@@ -4989,7 +5023,7 @@ const floatToSmoothPercents = () => (source) => source.pipe(timestamp(), startWi
4989
5023
  */
4990
5024
  const smoothTransition = (start, end, duration) => {
4991
5025
  const startTime = animationFrameScheduler.now();
4992
- return interval(0, animationFrameScheduler).pipe(map(() => clampf(0, 1, (animationFrameScheduler.now() - startTime) / duration)), distinctUntilChanged(), takeWhile((fraction) => fraction < 1, true), map((fraction) => lerp(start, end, fraction)));
5026
+ return interval(0, animationFrameScheduler).pipe(map(() => clampf(0, 1, (animationFrameScheduler.now() - startTime) / duration)), distinctUntilChanged(), takeWhile$1((fraction) => fraction < 1, true), map((fraction) => lerp(start, end, fraction)));
4993
5027
  };
4994
5028
 
4995
5029
  const getImageFromVideoStream = (takeSizeFrom = 'video', imageOutput, sizes) => {
@@ -7190,6 +7224,7 @@ class StreamStatusTelemetryService2 {
7190
7224
  handshakeFlow: null,
7191
7225
  commandCount: 0,
7192
7226
  times,
7227
+ openPhaseIdx: 0,
7193
7228
  };
7194
7229
  // Resolve the wire session id from the stream's connection id, then flush
7195
7230
  // everything queued so far. Subscribed FIRST so the id is in place before
@@ -7345,6 +7380,10 @@ class StreamStatusTelemetryService2 {
7345
7380
  ? errorMessage.message
7346
7381
  : undefined;
7347
7382
  const includeGranular = granularReason && granularReason !== DisconnectReason.None;
7383
+ const openPhase = this.phaseCatalog[session.openPhaseIdx];
7384
+ if (openPhase) {
7385
+ this.emitPhaseEnded(openPhase, session.openPhaseIdx, null, true);
7386
+ }
7348
7387
  this.emitLifecycle('stream.session_ended', {
7349
7388
  sessionId: id,
7350
7389
  reason,
@@ -7408,9 +7447,10 @@ class StreamStatusTelemetryService2 {
7408
7447
  * phaseNo (derived from the catalog index), id, color, milestones,
7409
7448
  * params, overlays. No display text on the wire: the viewer's
7410
7449
  * vocabulary maps every id back to a human label, and boundary labels
7411
- * are derived from neighbor phases.
7450
+ * are derived from neighbor phases. `incomplete` marks the phase the
7451
+ * session ended in, sent from `endSession` instead of from its closer.
7412
7452
  */
7413
- emitPhaseEnded(bucket, bucketIdx, extrasValue) {
7453
+ emitPhaseEnded(bucket, bucketIdx, extrasValue, incomplete = false) {
7414
7454
  if (!this.session)
7415
7455
  return;
7416
7456
  const now = performance.now();
@@ -7427,7 +7467,15 @@ class StreamStatusTelemetryService2 {
7427
7467
  milestones,
7428
7468
  params,
7429
7469
  overlays,
7470
+ ...(incomplete && { incomplete: true }),
7430
7471
  });
7472
+ this.closePhase(bucketIdx);
7473
+ }
7474
+ /** Move the open phase past `bucketIdx` — phases close in catalog order. */
7475
+ closePhase(bucketIdx) {
7476
+ if (!this.session)
7477
+ return;
7478
+ this.session.openPhaseIdx = Math.max(this.session.openPhaseIdx, bucketIdx + 1);
7431
7479
  }
7432
7480
  /**
7433
7481
  * Emit the region / signaling / webrtc phases for an ADOPTED connection.
@@ -7518,6 +7566,7 @@ class StreamStatusTelemetryService2 {
7518
7566
  params: toPhaseParams({ ...extras, prefetched: true }),
7519
7567
  overlays: [],
7520
7568
  });
7569
+ this.closePhase(bucketIdx);
7521
7570
  }
7522
7571
  /** Streamer identity params for the adopted signaling phase — mirrors the
7523
7572
  * `ssinfo-received` closer's shape (client / instanceName / …ssData /
@@ -9204,5 +9253,5 @@ function provideUnrealModule() {
9204
9253
  * Generated bundle index. Do not edit.
9205
9254
  */
9206
9255
 
9207
- export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, 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, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MODIFIER_KEY_CODES, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, 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, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, STREAM_RESOLUTION_LIMITS, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, 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, clampStreamResolution, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, 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, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
9256
+ export { AFKService, ALL_KEYBOARD_KEYS, AUTO_HIGH_RESOLUTION_IDLE_MS, AfkTimeoutModalComponent, AggregatorService, AnalyticsService, AnswerHandler, COLOR_CODES, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, ControlScheme, DATA_CHANNEL_CONNECTION_TIMEOUT, DATA_CHANNEL_TIMEOUT_RESTARTS, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DESTROY_DISCONNECT_REASONS, DevModeService, DisconnectReason, FULL_HD_HEIGHT, FULL_HD_WIDTH, Falsy, FileHandlerService, FileReceiverService, FpsMonitorService, FreezeFrameComponent, FreezeFrameService, HEXtoRGB, HSVtoRGB, IME_PROCESS_KEY, INNER_RETRY_LIMIT, INSTANCE_READY_TIMEOUT, IceCandidateHandler, ImageLoadingSrcComponent, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, IntroSrcComponent, LatencyTimings, LoadingProgressService, Logger, MINIMAL_FPS, MODIFIER_KEY_CODES, MessageType, MouseButton, MouseButtonsMask, OUTER_RETRY_DELAY, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, 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, RGBtoHEX, RGBtoHSV, RegionsPingService, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_AUDIO_ID, STREAMING_VIDEO_ID, STREAM_RESOLUTION_LIMITS, SafePipe, Semaphore, SignallingService, StatGraphComponent, StreamAdoptionService, StreamStatusTelemetryService, StreamStatusTelemetryService2, SubService, ToClientMessage, Truthy, UnrealAfkSlotDirective, UnrealCallbackService, UnrealCommunicatorService, UnrealEffects, UnrealKeyCode, UnrealResumeSlotDirective, UnrealSceneComponent, UnrealStatusMessage, UnrealStatusSlotDirective, 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, clampStreamResolution, clampf, commandCompleted, commandStarted, dataChannelConnected, dataChannelReady, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, dropDC, dropPC, fitIntoRectangle, floatToPercents, floatToSmoothPercents, forceResizeViewport, fpIsASameAsB, fromResizeObserver, generateUuid, getActiveUrl, getCanvasCached, getImageFromVideoStream, getResizeStudioValues, getResizeValuesUniversal, getRtcErrorMessage, getSnapshot, iceConnectionFailed, initSignalling, instanceReady, inverseLerp, isAppOwned, isMetaboxMode, keepMaxUntilReset, lerp, makeEven, pollingEnded, pollingStarted, provideUnrealModule, provideUnrealState, qpToQuality, reconnectPeer, reconnectPeerFailed, reconnectPeerSuccess, regionPingFetchEnd, regionPingFetchStart, regionResolved, resetAfk, resetConfig, resetDataChannelForReconnect, resetIntroSrc, resetUserInactivityTimeout, resetWarnTimeout, resolveSkin, 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, startStream, streamAdopted, tapLog, trackMixpanelEvent, trackTelemetryData, uint8ToBase64, unrealCommandCallback, unrealFeature, unrealReducer, updateCirrusInfo, videoAdaptedToContainer, videoStreamInitialized };
9208
9257
  //# sourceMappingURL=3dsource-angular-unreal-module.mjs.map