bitmovin-player-ui 3.76.0 → 3.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/ts/arrayutils.ts","src/ts/audiotrackutils.ts","src/ts/browserutils.ts","src/ts/components/adclickoverlay.ts","src/ts/components/admessagelabel.ts","src/ts/components/adskipbutton.ts","src/ts/components/airplaytogglebutton.ts","src/ts/components/audioqualityselectbox.ts","src/ts/components/audiotracklistbox.ts","src/ts/components/audiotrackselectbox.ts","src/ts/components/bufferingoverlay.ts","src/ts/components/button.ts","src/ts/components/caststatusoverlay.ts","src/ts/components/casttogglebutton.ts","src/ts/components/castuicontainer.ts","src/ts/components/clickoverlay.ts","src/ts/components/closebutton.ts","src/ts/components/component.ts","src/ts/components/container.ts","src/ts/components/controlbar.ts","src/ts/components/ecomodecontainer.ts","src/ts/components/ecomodetogglebutton.ts","src/ts/components/errormessageoverlay.ts","src/ts/components/fullscreentogglebutton.ts","src/ts/components/hugeplaybacktogglebutton.ts","src/ts/components/hugereplaybutton.ts","src/ts/components/itemselectionlist.ts","src/ts/components/label.ts","src/ts/components/listbox.ts","src/ts/components/listselector.ts","src/ts/components/metadatalabel.ts","src/ts/components/pictureinpicturetogglebutton.ts","src/ts/components/playbackspeedselectbox.ts","src/ts/components/playbacktimelabel.ts","src/ts/components/playbacktogglebutton.ts","src/ts/components/playbacktoggleoverlay.ts","src/ts/components/quickseekbutton.ts","src/ts/components/recommendationoverlay.ts","src/ts/components/replaybutton.ts","src/ts/components/seekbar.ts","src/ts/components/seekbarbufferlevel.ts","src/ts/components/seekbarcontroller.ts","src/ts/components/seekbarlabel.ts","src/ts/components/selectbox.ts","src/ts/components/settingspanel.ts","src/ts/components/settingspanelitem.ts","src/ts/components/settingspanelpage.ts","src/ts/components/settingspanelpagebackbutton.ts","src/ts/components/settingspanelpagenavigatorbutton.ts","src/ts/components/settingspanelpageopenbutton.ts","src/ts/components/settingstogglebutton.ts","src/ts/components/spacer.ts","src/ts/components/subtitlelistbox.ts","src/ts/components/subtitleoverlay.ts","src/ts/components/subtitleselectbox.ts","src/ts/components/subtitlesettings/backgroundcolorselectbox.ts","src/ts/components/subtitlesettings/backgroundopacityselectbox.ts","src/ts/components/subtitlesettings/characteredgeselectbox.ts","src/ts/components/subtitlesettings/fontcolorselectbox.ts","src/ts/components/subtitlesettings/fontfamilyselectbox.ts","src/ts/components/subtitlesettings/fontopacityselectbox.ts","src/ts/components/subtitlesettings/fontsizeselectbox.ts","src/ts/components/subtitlesettings/subtitlesettingselectbox.ts","src/ts/components/subtitlesettings/subtitlesettingslabel.ts","src/ts/components/subtitlesettings/subtitlesettingsmanager.ts","src/ts/components/subtitlesettings/subtitlesettingspanelpage.ts","src/ts/components/subtitlesettings/subtitlesettingsresetbutton.ts","src/ts/components/subtitlesettings/windowcolorselectbox.ts","src/ts/components/subtitlesettings/windowopacityselectbox.ts","src/ts/components/timelinemarkershandler.ts","src/ts/components/titlebar.ts","src/ts/components/togglebutton.ts","src/ts/components/tvnoisecanvas.ts","src/ts/components/uicontainer.ts","src/ts/components/videoqualityselectbox.ts","src/ts/components/volumecontrolbutton.ts","src/ts/components/volumeslider.ts","src/ts/components/volumetogglebutton.ts","src/ts/components/vrtogglebutton.ts","src/ts/components/watermark.ts","src/ts/demofactory.ts","src/ts/dom.ts","src/ts/errorutils.ts","src/ts/eventdispatcher.ts","src/ts/focusvisibilitytracker.ts","src/ts/groupplaybackapi.ts","src/ts/guid.ts","src/ts/imageloader.ts","src/ts/localization/i18n.ts","src/ts/localization/languages/de.json","src/ts/localization/languages/en.json","src/ts/localization/languages/es.json","src/ts/localization/languages/nl.json","src/ts/main.ts","src/ts/mobilev3playerapi.ts","src/ts/playerutils.ts","src/ts/spatialnavigation/ListNavigationGroup.ts","src/ts/spatialnavigation/gethtmlelementsfromcomponents.ts","src/ts/spatialnavigation/keymap.ts","src/ts/spatialnavigation/navigationalgorithm.ts","src/ts/spatialnavigation/navigationgroup.ts","src/ts/spatialnavigation/nodeeventsubscriber.ts","src/ts/spatialnavigation/rootnavigationgroup.ts","src/ts/spatialnavigation/seekbarhandler.ts","src/ts/spatialnavigation/spatialnavigation.ts","src/ts/spatialnavigation/typeguards.ts","src/ts/spatialnavigation/types.ts","src/ts/storageutils.ts","src/ts/stringutils.ts","src/ts/subtitleutils.ts","src/ts/timeout.ts","src/ts/uifactory.ts","src/ts/uimanager.ts","src/ts/uiutils.ts","src/ts/volumecontroller.ts","src/ts/vttutils.ts"],"names":["f","g","exports","module","define","amd","window","global","self","this","bitmovin","playerui","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","ArrayUtils","remove","array","item","index","indexOf","splice","i18n_1","AudioTrackSwitchHandler","player","element","uimanager","_this","addAudioTrack","event","audioTrack","track","listElement","hasItem","id","addItem","i18n","getLocalizer","label","removeAudioTrack","removeItem","selectCurrentAudioTrack","currentAudioTrack","getAudio","selectItem","refreshAudioTracks","audioTracks","getAvailableAudio","synchronizeItems","map","key","bindSelectionEvent","bindPlayerEvents","prototype","onItemSelected","subscribe","_","value","setAudio","on","PlayerEvent","AudioChanged","SourceUnloaded","PeriodSwitched","AudioAdded","AudioRemoved","getConfig","events","onUpdated","BrowserUtils","Object","defineProperty","windowExists","navigator","userAgent","test","isHisense","platform","includes","maxTouchPoints","msMaxTouchPoints","_super","clickoverlay_1","AdClickOverlay","ClickOverlay","__extends","configure","adFinishedHandler","setUrl","clickThroughCallback","AdStarted","ad","clickThroughUrl","clickThroughUrlOpened","AdFinished","AdSkipped","AdError","onClick","pause","config","mergeConfig","acceptsTouchWithUiHidden","label_1","stringutils_1","AdMessageLabel","Label","adEndHandler","off","TimeChanged","updateMessageHandler","text","setText","StringUtils","replaceAdMessagePlaceholders","performLocalization","uiConfig","message","cssClass","button_1","AdSkipButton","Button","updateSkipMessageHandler","untilSkippableMessage","skippableMessage","skipOffset","show","getCurrentTime","disable","enable","skippableAfter","hide","ads","skip","togglebutton_1","AirPlayToggleButton","ToggleButton","airPlayAvailableHandler","isAirplayAvailable","showAirplayTargetPicker","console","log","airPlayChangedHandler","isAirplayActive","AirplayAvailable","AirplayChanged","selectbox_1","AudioQualitySelectBox","SelectBox","updateAudioQualities","audioQualities","getAvailableAudioQualities","clearItems","_i","audioQualities_1","audioQuality","selectCurrentAudioQuality","getAudioQuality","sender","setAudioQuality","AudioQualityChanged","AudioQualityAdded","AudioQualityRemoved","cssClasses","listbox_1","audiotrackutils_1","AudioTrackListBox","ListBox","AudioTrackSelectBox","container_1","component_1","timeout_1","BufferingOverlay","Container","showOverlay","overlayShowTimeout","start","hideOverlay","clear","Timeout","showDelayMs","StallStarted","StallEnded","Play","Playing","Paused","Seek","Seeked","TimeShift","TimeShifted","isStalled","indicators","Component","tag","role","hidden","components","dom_1","eventdispatcher_1","toDomElement","buttonElementAttributes","aria-label","ariaLabel","class","getCssClasses","type","aria-pressed","tabindex","tabIndex","toString","buttonElement","DOM","append","prefixCss","html","onClickEvent","getDomElement","find","buttonEvents","dispatch","getEvent","EventDispatcher","CastStatusOverlay","CastWaitingForDevice","castDeviceName","castPayload","deviceName","statusLabel","CastStarted","CastStopped","CastToggleButton","castAvailableHander","isCastAvailable","isCasting","castStop","castVideo","CastAvailable","uicontainer_1","CastUIContainer","UIContainer","isUiShown","showUi","castUiHideTimeout","hideDelay","onControlsHide","onControlsShow","showUiPermanently","showUiWithTimeout","isPlaying","release","initialize","url","data","open","getUrl","undefined","CloseButton","target","ViewMode","guid_1","disabled","isHidden","isDisabled","onShow","onComponentShow","onHide","onComponentHide","onViewModeChanged","args","onComponentViewModeChanged","onHoverChangedEvent","hasDomElement","Boolean","setAriaLabel","setAriaAttr","name","attr","concat","defaults","base","assign","css","join","trim","cssClassOrId","cssPrefix","addClass","CLASS_HIDDEN","onHideEvent","removeClass","onShowEvent","isShown","toggleHidden","CLASS_DISABLED","onDisabledEvent","onEnabledEvent","isEnabled","isHovered","hovered","componentEvents","onEnabled","onDisabled","onViewModeChangedEvent","mode","viewMode","onHoverChanged","Guid","next","Temporary","arrayutils_1","addComponent","component","push","componentsToAdd","removeComponent","componentsToRemove","getComponents","removeComponents","_a","slice","updateComponents","shift","innerContainerElement","containerElement","innerContainer","initialComponent","suspendHideTimeout","resumeHideTimeout","trackComponentViewMode","Persistent","componentsInPersistentViewMode","Math","max","uiutils_1","spacer_1","browserutils_1","settingspanel_1","ControlBar","hoverStackCount","isSettingsPanelShown","disableAutoHideWhenHovered","isTouchSupported","UIUtils","traverseTree","Spacer","isMobile","SettingsPanel","onPreviewControlsHide","cancel","ecomodetogglebutton_1","settingspanelitem_1","EcoModeContainer","setOnToggleCallback","callback","onToggleCallback","SegmentPlayback","segment","bitrate","frameRate","maxHeight","maxBitrate","maxWidth","currentEnergyKwh","maxEnergyKwh","mimeType","height","mediaInfo","width","_b","getMaxQualityAvailable","getAvailableVideoQualities","calculateEnergyConsumption","duration","ecoModeSavedEmissionsItem","updateSavedEmissions","emissionsSavedLabel","currentEnergyConsuption","maxEnergyConsuption","currentEnergyEmission","maxEnergyEmisson","savedEmissons","toFixed","fps","availableVideoQualities","sortedQualities","sort","b","ecoModeToggleButton","EcoModeToggleButton","labelEcoMode","for","ecoModeToggleButtonItem","SettingsPanelItem","onToggleOn","onToggleOff","areAdaptationApisAvailable","toggle","enableEcoMode","setVideoQuality","disableEcoMode","VideoQualityChanged","quality","targetQuality","isGetConfigAvailable","adaptation","isSetConfigAvailable","setConfig","adaptationConfig","codec","resolution","maxSelectableVideoHeight","limitToPlayerSize","defaultConfig","onClass","offClass","tvnoisecanvas_1","errorutils_1","mobilev3playerapi_1","ErrorMessageOverlay","errorEventHandler","handleErrorMessage","customizedMessage","errorMessages","customMessage","messages","display","isMobileV3PlayerAPI","MobileV3PlayerEvent","PlayerError","ErrorUtils","defaultMobileV3ErrorMessageTranslator","SourceError","defaultWebErrorMessageTranslator","SourceLoaded","tvNoiseBackground","stop","errorMessage","errorLabel","TvNoiseCanvas","FullscreenToggleButton","fullscreenStateHandler","getViewMode","Fullscreen","fullscreenAvailabilityChangedHandler","isFullScreenAvailable","isViewModeAvailable","ViewModeChanged","ViewModeAvailabilityChanged","targetViewMode","Inline","setViewMode","playbacktogglebutton_1","HugePlaybackToggleButton","PlaybackToggleButton","togglePlayback","isPlayInitiated","play","toggleFullscreen","suppressPlayButtonTransitionAnimation","setTransitionAnimationsEnabled","onToggle","subscribeOnce","firstPlay","enterFullscreenOnInitialPlayback","clickTime","doubleClickTime","isAutoplayEnabled","now","Date","setTimeout","Warning","WarningCode","PLAYBACK_COULD_NOT_BE_STARTED","playback","autoplay","isAutoplayUpcoming","getSource","enabled","noTransitionAnimationsClass","hasClass","HugeReplayButton","listselector_1","ItemSelectionList","ListSelector","isActive","items","updateDomItems","selectedValue","selectedListItem","empty","listItem","CLASS_SELECTED","deselectItem","this_1","String","onItemSelectedEvent","onItemAddedEvent","selectedItem","onItemRemovedEvent","tagName","labelElement","localizedText","onTextChangedEvent","getText","clearText","isEmpty","labelEvents","onTextChanged","onItemAdded","addListBoxDomItem","onItemRemoved","removeListBoxDomItem","refreshSelectedItem","listBoxElement","createListBoxDomItems","buildListBoxItemButton","ListBoxItemButton","getComponentForKey","c","listBoxItemButton_1","newItem","getItemForKey","handleSelectionChange","getItemIndex","parseInt","getItems","sortedInsert","__assign","filter","translator","findIndex","entry","getSelectedItem","newItems","forEach","items_1","itemCount","keys","listSelectorEvents","MetadataLabelContent","MetadataLabel","init","content","Title","uiconfig","metadata","title","Description","description","toLowerCase","PictureInPictureToggleButton","pictureInPictureStateHandler","PictureInPicture","pictureInPictureAvailabilityChangedHandler","isPictureInPictureAvailable","PlaybackSpeedSelectBox","setDefaultValue","playbackSpeed","getPlaybackSpeed","setSpeed","addDefaultItems","setPlaybackSpeed","parseFloat","PlaybackSpeedChanged","speed","customItems","defaultPlaybackSpeeds","PlaybackTimeLabelMode","playerutils_1","PlaybackTimeLabel","minWidth","min-width","updateTimeFormatBasedOnDuration","live","liveCssClass","liveEdgeCssClass","liveClickHandler","timeShift","updateLiveTimeshiftState","isTimeshifted","isTimeshiftAvailable","getTimeShift","getMaxTimeShift","isPaused","liveStreamDetector","PlayerUtils","LiveStreamDetector","playbackTimeHandler","onLiveChanged","isLive","hideInLivePlayback","unsubscribe","detect","getDuration","Infinity","setTime","getCurrentTimeRelativeToSeekableRange","timeFormat","abs","FORMAT_HHMMSS","FORMAT_MMSS","Ready","playbackSeconds","durationSeconds","currentTime","secondsToTime","totalTime","timeLabelMode","CurrentTime","TotalTime","CurrentAndTotalTime","RemainingTime","remainingTime","setTimeFormat","handleClickEvent","playbackStateHandler","isSeeking","updateLiveState","isTimeShiftAvailable","CLASS_STOPTOGGLE","timeShiftDetector","PlaybackFinished","TimeShiftAvailabilityDetector","onTimeShiftAvailabilityChanged","onSeek","onSeeked","onAriaLabel","offAriaLabel","hugeplaybacktogglebutton_1","PlaybackToggleOverlay","playbackToggleButton","QuickSeekButton","switchVisibility","hasTimeShift","timeShiftAvailable","newSeekTime","clampedValue","seekSeconds","currentSeekTarget","clampValueToRange","seek","onSeekedOrTimeShifted","onTimeShift","seekDirection","seekTarget","position","hugereplaybutton_1","RecommendationOverlay","setupRecommendations","clearRecommendations","recommendations","recommendations_1","RecommendationItem","itemConfig","replayButton","itemElement","href","background-image","thumbnail","bgElement","titleElement","timeElement","ReplayButton","hasEnded","groupplaybackapi_1","seekbarcontroller_1","timelinemarkershandler_1","seekbarbufferlevel_1","SeekBar","hasLabel","getLabel","setAriaSliderMinMax","min","setAriaSliderValues","ariaValueText","seekBarType","SeekBarType","Live","timeshiftValue","ceil","Vod","secondsToText","floor","getPlaybackPositionPercentage","getRelativeCurrentTime","updateBufferLevel","playbackPositionPercentage","bufferLoadedPercentageLevel","getMinBufferLevel","setBufferPosition","configureSeek","scrubbing","isPlayerSeeking","suspension","playbackPositionHandler","isGroupPlaybackAPIAvailable","uiManager","setPosition","seekBarBackdrop","SeekBarController","keyStepIncrements","volumeController","setSeekBarControls","smoothPlaybackPositionUpdater","forceUpdate","isUserSeeking","SegmentRequestFinished","setPlaybackPosition","isInInitialStartupState","smoothPlaybackPositionUpdateIntervalMs","SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED","isNeitherPausedNorPlaying","configureLivePausedTimeshiftUpdater","onPlayerSeek","setSeeking","onPlayerSeeked","groupPlayback","hasJoined","beginSuspension","GroupPlaybackSuspensionReason","UserIsScrubbing","onSeekPreview","enableSeekPreview","subscribeRateLimited","seekWhileScrubbing","percentage","proposedPlaybackTime","getTargetSeekPosition","endSuspension","refreshPlaybackPosition","PlayerResized","uiBoundingRect","getUI","get","getBoundingClientRect","onConfigured","seekbarSnappingRange","snappingRange","seekbarSnappingEnabled","snappingEnabled","setSeekPosition","configureSmoothPlaybackPositionUpdater","initializeTimelineMarkers","Volume","timelineMarkerConfig","timelineMarkersHandler","TimelineMarkersHandler","seekBar","seekBarMarkersContainer","pausedTimeshiftUpdater","startSmoothPlaybackPositionUpdater","currentTimeSeekBar","stopSmoothPlaybackPositionUpdater","currentTimePlayer","updateIntervalMs","error","PlayerAPINotAvailableError","currentTimeDelta","seekBarContainer","vertical","seekBarBufferLevel","seekBarPlaybackPosition","seekBarBufferPosition","seekBarPlaybackPositionMarker","seekBarSeekPosition","seekBarChapterMarkersContainer","seeking","mouseTouchMoveHandler","preventDefault","vr","stopPropagation","offset","getOffset","targetPercentage","seekPositionPx","onSeekPreviewEvent","mouseTouchUpHandler","document","matchingMarker","getMarkerAtPosition","onSeekedEvent","isTouchEvent","onSeekEvent","seekPositionPercentage","getHorizontalOffset","eventPageX","elementOffsetPx","left","widthPx","sanitizeOffset","getVerticalOffset","eventPageY","top","changedTouches","touches","pageY","pageX","MouseEvent","warn","percent","px","style","transform","-ms-transform","-webkit-transform","scale","CLASS_SEEKING","seekBarEvents","targetOffsetPx","snappedMarker","updateLabelPosition","marker","TouchEvent","seekableRangeStart","maxTimeShift","getSeekableRangeStart","targetPlaybackPosition","pixelPosition","setPositionInBounds","leftRight","upDown","playerDuration","videoBufferLength","getVideoBufferLength","audioBufferLength","getAudioBufferLength","bufferLength","Number","MAX_VALUE","coerceValueIntoRange","range","cb","arrowKeyControls","currentValue","valueUpdate","controlValue","right","up","down","home","end","seekBarControls","volumeTransition","startTransition","getVolume","finish","bind","domElement","controls","keyCode","KeyCode","LeftArrow","RightArrow","UpArrow","DownArrow","Home","End","Space","imageloader_1","SeekBarLabel","setTitleText","setThumbnail","handleSeekPreview","bounds","labelBounding","container","parentElement","preventOverflowOffset","caret","timeLabel","seconds","titleLabel","thumbnailElement","thumbnailImageLoader","load","x","thumbnailCssSprite","thumbnailCssSingleImage","sizeX","sizeY","offsetX","offsetY","y","aspectRatio","padding-bottom","background-size","background-position","appliedMarkerCssClasses","targetTimeShift","currentTimeShift","timeShiftPreview","wallClockTime","getThumbnail","time","ImageLoader","DocumentDropdownClosedEvents","SelectDropdownClosedEvents","DropdownOpenedEvents","selectElement","closeDropdown","addDropdownOpenedListeners","onChange","uiContainer","onPlayerStateChange","getSelectElement","optionElement","addDropdownCloseListeners","removeDropdownCloseListeners","clearTimeout","dropdownCloseListenerTimeoutId","addEventListener","onDropdownClosed","removeEventListener","removeListenerFunctions","removeDropdownOpenedListeners","event_1","listener","onDropdownOpened","DropdownOpenedEvents_1","removeListenerFunctions_1","val","select","blur","state","PlayerState","Idle","Finished","NavigationDirection","settingspanelpage_1","hideHoveredSelectBoxes","hideTimeout","reset","activePage","onInactiveEvent","resetNavigation","onActiveEvent","getRootPage","onSettingsStateChanged","onSettingsStateChangedEvent","updateActivePageClass","getActivePage","setActivePageIndex","setActivePage","getPages","targetPage","navigateToPage","Forwards","pageTransitionAnimation","popToRootSettingsPanelPage","popSettingsPanelPage","navigationStack","Backwards","rootPageHasActiveSettings","hasActiveSettings","SettingsPanelPage","settingsPanelEvents","suspend","resume","page","CLASS_ACTIVE_PAGE","resetNavigationOnShow","sourcePage","rootPage","animateNavigation","direction","skipAnimation","pop","settingsPanelDomElement","settingsPanelWidth","settingsPanelHeight","clone","targetSettingsPanelHeight","settingsPanelHTMLElement","scrollWidth","scrollHeight","targetPageHtmlElement","cloneNode","parentNode","appendChild","targetSettingsPanelWidth","removeChild","forceBrowserReflow","offsetLeft","getComputedItems","selectBox","allItems","apply","videoqualityselectbox_1","audioqualityselectbox_1","playbackspeedselectbox_1","handleConfigItemChanged","setting","minItemsToDisplay","VideoQualitySelectBox","hasAutoItem","playbackSpeedSelectionEnabled","onActiveChangedEvent","settingsPanelItemEvents","onActiveChanged","settingsStateChangedHandler","lastShownItem","CLASS_LAST","settingsPanelPageEvents","activeItems","onActive","isIOS","isMacIntel","focusToFirstInput","onInactive","settingspanelpagenavigatorbutton_1","SettingsPanelPageBackButton","SettingsPanelPageNavigatorButton","popPage","pushTargetPage","SettingsPanelPageOpenButton","SettingsToggleButton","settingsPanel","visibleSettingsPanels","autoHideWhenNoActiveSettings","settingsPanelItemsChangedHandler","subtitleutils_1","SubtitleListBox","SubtitleSwitchHandler","controlbar_1","vttutils_1","SubtitleOverlay","subtitleClearHandler","subtitleContainerManager","subtitleManager","clearInactiveCues","toRemove","removeLabel","ActiveSubtitleManager","SubtitleRegionContainerManager","CueEnter","generateLabel","cueEnter","preprocessLabelEventCallback","previewSubtitleActive","previewSubtitle","addLabel","size","forceSubtitlesIntoViewContainer","handleSubtitleCropping","CueUpdate","labelToReplace","cueUpdate","replaceLabel","CueExit","labelToRemove","cueExit","hasCues","SubtitleDisabled","CLASS_CONTROLBAR_VISIBLE","configureCea608Captions","detectCroppedSubtitleLabel","parent","childRect","parentRect","bottom","labelDomElement","cropDetection","removeCss","row","column","SubtitleLabel","generateImageTagText","image","vtt","region","regionStyle","updateCEA608FontSize","dummyLabel","font-size","line-height","visibility","dummyLabelCharWidth","dummyLabelCharHeight","fontSizeRatio","subtitleOverlayWidth","subtitleOverlayHeight","fontLetterSpacing","CEA608_NUM_COLUMNS","CEA608_NUM_ROWS","fontSize","letter-spacing","CLASS_CEA_608","fontSizeCalculationRequired","CEA608_COLUMN_OFFSET","CEA608_ROW_OFFSET","SubtitleEnabled","enablePreviewSubtitleLabel","removePreviewSubtitleLabel","calculateId","addCueToMap","popCueFromMap","activeSubtitleCueMap","activeSubtitleCueCount","activeSubtitleCues","activeSubtitleCue","removedCues","cue","imageData","imgTag","src","outerHTML","getCues","cueCount","getRegion","regionContainerId","regionName","overlaySize","subtitleRegionContainers","regionContainerId_1","regionContainer","SubtitleRegionContainer","subtitleOverlay","previousLabel","newLabel","labelToAdd","labelCount","VttUtils","setVttRegionStyles","setVttCueBoxStyles","SubtitleSelectBox","subtitlesettingselectbox_1","BackgroundColorSelectBox","SubtitleSettingSelectBox","setColorAndOpacity","settingsManager","backgroundColor","isSet","backgroundOpacity","toggleOverlayClass","onChanged","property","BackgroundOpacitySelectBox","CharacterEdgeSelectBox","characterEdge","FontColorSelectBox","fontColor","fontOpacity","FontFamilySelectBox","fontFamily","FontOpacitySelectBox","FontSizeSelectBox","currentCssClass","overlay","getSubtitleSettingsManager","SubtitleSettingsLabel","opener","storageutils_1","SubtitleSettingsManager","_properties","SubtitleSettingsProperty","windowColor","windowOpacity","userSettings","localStorageKey","DummyComponent","instance","propertyName","save","StorageUtils","setObject","getObject","_instance","_value","onChangedEvent","_onChanged","_manager","manager","fontsizeselectbox_1","fontfamilyselectbox_1","fontcolorselectbox_1","fontopacityselectbox_1","characteredgeselectbox_1","backgroundcolorselectbox_1","backgroundopacityselectbox_1","windowcolorselectbox_1","windowopacityselectbox_1","subtitlesettingsresetbutton_1","settingspanelpagebackbutton_1","SubtitleSettingsPanelPage","WindowColorSelectBox","WindowOpacitySelectBox","SubtitleSettingsResetButton","getSeekBarWidth","markersContainer","timelineMarkers","configureMarkers","clearMarkers","AdBreakStarted","AdBreakFinished","updateMarkers","updateMarkersDOM","onRelease","intervalMarkerMatch","positionMarkerMatch","removeMarkerFromConfig","markers","_marker","filterRemovedMarkers","seekbarMarker","removeMarkerFromDOM","shouldProcessMarkers","validToProcess","hasMarkers","markerPosition","markerDuration","getSeekableRangeRespectingLive","isNaN","updateMarkerDOM","newMarker","createMarkerDOM","getMarkerCssProperties","seekBarWidthPx","positionInPx","cssProperties","markerWidthPx","round","imageElement_1","markerClasses","markerElement","data-marker-time","data-marker-title","imageUrl","handler","Destroy","metadatalabel_1","TitleBar","shouldBeShown","hasMetadataText","checkMetadataTextAndUpdateVisibility","keepHiddenWithoutMetadata","isOff","onState","onToggleEvent","onToggleOnEvent","isOn","onToggleOffEvent","toggleButtonEvents","canvas","canvasElement","canvasContext","getContext","noiseAnimationWindowPos","canvasHeight","lastFrameUpdate","canvasWidth","renderFrame","useAnimationFrame","cancelAnimationFrame","frameUpdateHandlerId","frameInterval","getTime","currentPixelOffset","noiseImage","createImageData","random","interferenceHeight","putImageData","scheduleNextRender","requestAnimationFrame","userInteractionEventSource","configureUIShowHide","configurePlayerStates","isFirstTouch","playerState","hidingPrevented","hidePlayerStateExceptions","uiHideTimeout","hideUi","previewHideEventArgs","userInteractionEvents","shouldPreventDefault","findButtonComponent","buttonComponent","hideImmediatelyOnMouseLeave","playerStateChange","enumName","stateClassNames","STATE_PREFIX","updateState","removeStates","updateLayoutSizeClasses","Prepared","getState","FULLSCREEN","BUFFERING","REMOTE_CONTROL","CONTROLS_HIDDEN","CONTROLS_SHOWN","substring","getContainer","createElement","flex","updateVideoQualities","videoQualities","hasAuto","getStreamType","videoQualities_1","videoQuality","selectCurrentVideoQuality","getVideoQuality","VideoQualityAdded","VideoQualityRemoved","volumeslider_1","volumetogglebutton_1","VolumeControlButton","volumeToggleButton","getVolumeToggleButton","volumeSlider","getVolumeSlider","volumeSliderHovered","volumeSliderHideTimeout","VolumeToggleButton","VolumeSlider","seekbar_1","setVolumeAriaSliderValues","hideIfVolumeControlProhibited","detectVolumeControlAvailability","muted","volume","updateVolumeWhileScrubbing","dummyVideoElement","update","volumeLevelTens","toggleMuted","VRToggleButton","vrStateHandler","ev","VR_RENDERING_ERROR","isVRConfigured","isVRStereoAvailable","getStereo","vrButtonVisibilityHandler","source","VRStereoChanged","setStereo","Watermark","vrtogglebutton_1","settingstogglebutton_1","playbacktimelabel_1","airplaytogglebutton_1","errormessageoverlay_1","casttogglebutton_1","fullscreentogglebutton_1","recommendationoverlay_1","caststatusoverlay_1","watermark_1","subtitleoverlay_1","seekbarlabel_1","playbacktoggleoverlay_1","pictureinpicturetogglebutton_1","uimanager_1","titlebar_1","bufferingoverlay_1","subtitlelistbox_1","audiotracklistbox_1","uifactory_1","main_1","DemoFactory","buildDemoWithSeparateAudioSubtitlesButtons","subtitleListBox","audioTrackListBox","UIManager","ui","UIFactory","modernSmallScreenAdsUI","condition","context","documentWidth","isAd","adRequiresUi","modernAdsUI","modernSmallScreenUI","subtitleSettingsPanel","audioTrackSettingsPanel","controlBar","something","attributes","Array","HTMLElement","elements","Document","attributeName","attributeValue","setAttribute","findChildElements","findChildElementsOfElement","selector","childElements","querySelectorAll","allChildElements","inputElements","focus","scrollTo","arguments","setHtml","getHtml","innerHTML","HTMLSelectElement","HTMLInputElement","attribute","setAttr","getAttr","removeAttr","removeAttribute","getAttribute","dataAttribute","setData","getData","childElement","elementRect","htmlRect","body","offsetWidth","offsetHeight","eventName","eventHandler","options","split","className","classNames","classList","add","replace","RegExp","contains","propertyNameOrCollection","setCss","getCss","setCssCollection","elementIndex","removeProperty","getComputedStyle","ruleValueCollection","defaultErrorMessages","1000","1001","1100","1101","1102","1103","1104","1105","1106","1107","1108","1109","1110","1111","1112","1113","1200","1201","1202","1203","1204","1205","1206","1207","1208","1209","1210","1211","1300","1301","1302","1303","1304","1400","1401","1402","1403","1404","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2100","2101","3000","3001","3002","3003","3004","3100","listeners","EventListenerWrapper","rateMs","RateLimitedEventListenerWrapper","subscribedListener","unsubscribeAll","listenersToRemove","listeners_1","fire","isOnce","listenersToRemove_1","eventListener","once","shouldFireEvent","rateLimitTimout","fireSuper","rateLimitingEventListener","startRateLimiting","lastSeenEvent","FocusVisibleCssClassName","FocusVisibilityTracker","bitmovinUiPrefix","lastInteractionWasKeyboard","onKeyDown","metaKey","altKey","ctrlKey","onMouseOrPointerOrTouch","onFocus","isHtmlElement","onBlur","eventHandlerMap","mousedown","pointerdown","touchstart","keydown","registerEventListeners","DOMTokenList","unregisterEventListeners","event_2","guid","loadedCallback","state_1","loaded","callLoadedCallback","de_json_1","__importDefault","en_json_1","es_json_1","nl_json_1","defaultLocalizationConfig","defaultVocabularies","en","default","de","es","nl","language","vocabularies","I18n","mergedConfig","detectBrowserLanguage","mergeVocabulariesWithDefaultVocabularies","initializeLanguage","initializeVocabulary","containsLanguage","hasOwnProperty","rawVocabularies","reduce","mergedVocabularies","vocabulary","browserLanguageDetectionEnabled","userLanguage","shortenedUserLanguage","vocab","lang","replaceVariableWithPlaceholderIfExists","matches","match","m","str","vocabularyString","settings.video.quality","settings.audio.quality","settings.audio.track","playPause","close","settings.audio.mute","settings.audio.volume","pictureInPicture","appleAirplay","googleCast","settings","fullscreen","settings.subtitles","settings.subtitles.font.size","settings.subtitles.font.family","settings.subtitles.font.color","settings.subtitles.font.opacity","settings.subtitles.characterEdge","settings.subtitles.background.color","settings.subtitles.background.opacity","settings.subtitles.window.color","settings.subtitles.window.opacity","settings.time.hours","settings.time.minutes","settings.time.seconds","back","replay","ads.remainingTime","colors.white","colors.black","colors.red","colors.green","colors.blue","colors.yellow","subtitle.example","subtitle.select","playingOn","connectingTo","watermarkLink","seekBar.value","seekBar.timeshift","seekBar.durationText","quickseek.forward","quickseek.rewind","ecoMode","ecoMode.title","colors.cyan","colors.magenta","settings.subtitles.characterEdge.raised","settings.subtitles.characterEdge.depressed","settings.subtitles.characterEdge.uniform","settings.subtitles.characterEdge.dropshadowed","settings.subtitles.font.family.monospacedserif","settings.subtitles.font.family.proportionalserif","settings.subtitles.font.family.monospacedsansserif","settings.subtitles.font.family.proportionalsansserif","settings.subtitles.font.family.casual","settings.subtitles.font.family.cursive","settings.subtitles.font.family.smallcapital","auto","normal","version","__exportStar","demofactory_1","enumerable","spatialnavigation_1","navigationgroup_1","SpatialNavigation","rootnavigationgroup_1","NavigationGroup","ListNavigationGroup_1","RootNavigationGroup","ListNavigationGroup","ListOrientation","itemselectionlist_1","audiotrackselectbox_1","subtitleselectbox_1","volumecontrolbutton_1","adskipbutton_1","admessagelabel_1","adclickoverlay_1","castuicontainer_1","closebutton_1","subtitlesettingslabel_1","settingspanelpageopenbutton_1","subtitlesettingspanelpage_1","replaybutton_1","quickseekbutton_1","TypeError","timeShiftAvailabilityChangedEvent","liveDetector","liveChangedEvent","isAndroid","isChrome","DurationChanged","defaultValue","getSeekableRange","currentTimeshift","maxTimeshift","timeShiftAvailableNow","liveNow","boundary1","boundary2","lowerBoundary","upperBoundary","types_1","handleAction","action","Action","SELECT","BACK","handleNavigation","listNavigationDirections","orientation","__spreadArray","Vertical","Direction","UP","DOWN","Horizontal","LEFT","RIGHT","typeguards_1","getHtmlElementsFromComponents","htmlElements","resolveAllComponents","childComponents","containerOrComponent","isContainer","isComponent","isListBox","children","TizenKeyMap","isApplicable","isTizen","keyCodes","38","40","37","39","13","10009","WebOsKeyMap","isWebOs","461","PlayStationKeyMap","isPlayStation","27","AndroidKeyMap","HisenseKeyMap","8","DefaultKeyMap","getKeyMapForPlatform","applicableKeyMap","keyMap","vector","sqrt","pow","getElementVector","boundingRect","getBoundingRectFromElement","calculateAngle","directionVector","len","elementVector","angleCos","acos","PI","getElementInDirection","activeElement","activeElemVector","elem","dist","angle","angleA","distA","navigationalgorithm_1","gethtmlelementsfromcomponents_1","nodeeventsubscriber_1","removeElementHoverEventListeners","eventSubscriber","NodeEventSubscriber","getActiveElement","focusElement","blurActiveElement","focusFirstElement","defaultNavigationHandler","targetElement","defaultActionHandler","click","handleInput","defaultHandler","userHandler","handleDefault","onNavigation","activeElementBeforeDisable","onAction","isSettingsPanel","trackElementHover","removeEventListenerFunctions","htmlElem","exitListener","enterListener","fn","attachedListeners","Map","getEventListenersOfType","has","set","node","listenersOfType","listenerIndex","otherNode","otherListener","otherOptions","SeekBarHandler","rootNavigationGroup","cursorPosition","isScrubbing","scrubSpeedPercentage","isSeekBarWrapper","stopSeeking","getSeekBar","initializeOrUpdateCursorPosition","dispatchMouseMoveEvent","dispatchMouseClickEvent","from","seekBarWrapper","updateScrubSpeedPercentage","scrubSpeedResetTimeout","getIncrement","increment","resetCursorPosition","updateCursorPosition","initializeCursorPosition","playbackPositionMarker","querySelector","rect","startX","startY","getCursorPositionMouseEventInit","clientX","clientY","dispatchEvent","mouseDownHandler","mouseEventInit","dispatchMouseLeaveEvent","seekbarhandler_1","keymap_1","navigationGroups","group","activeNavigationGroups","updateEnabledNavigationGroup","groupIndex","other","handleKeyEvent","active","getActiveNavigationGroup","isDirection","isAction","seekBarHandler","unsubscribeVisibilityChangesFns","subscribeToNavigationGroupVisibilityChanges","attachKeyEventHandler","enableDefaultNavigationGroup","onShowHandler","onHideHandler","unsubscribeFromNavigationGroupVisibilityChanges","unsub","groupToEnable","idx","obj","values","disableStorageApi","shouldUseLocalStorage","localStorage","getItem","setItem","debug","setStorageApiDisabled","JSON","stringify","json","parse","totalSeconds","format","isNegative","hours","minutes","leftPadWithZeros","num","substr","adMessage","adMessagePlaceholderRegex","formatString","isLinearAdActive","indexOfActiveAd","getActiveAdBreak","getActiveAd","total","isLinear","leadingZeroes","numDecimalPlaces","leadingZeroesMatches","decimalPlacesMatches","timeString","currentSubtitle","SUBTITLES_OFF_KEY","subtitles","list","subtitle","SubtitleAdded","addSubtitle","selectCurrentSubtitle","SubtitleRemoved","removeSubtitle","clearSubtitles","refreshSubtitles","offListItem","delay","repeat","timeoutOrIntervalId","suspended","clearInternal","setInterval","clearInterval","ecomodecontainer_1","modernUI","ecoModeContainer","unshift","mainSettingsPanelPage","subtitleSettingsPanelPage","subtitleSelectBox","subtitleSettingsOpenButton","modernCastReceiverUI","modernTvUI","subtitleListPanel","audioTrackListPanel","playbackToggleOverlay","subtitleToggleButton","audioToggleButton","spatialNavigation","buildDefaultUI","buildModernUI","buildDefaultSmallScreenUI","buildModernSmallScreenUI","buildDefaultCastReceiverUI","buildModernCastReceiverUI","buildDefaultTvUI","buildModernTvUI","volumecontroller_1","focusvisibilitytracker_1","subtitlesettingsmanager_1","playerUiOrUiVariants","updateConfig","onUiVariantResolve","onActiveUiChanged","uiVariants","subtitleSettingsManager","managerPlayerWrapper","PlayerWrapper","autoUiVariantResolve","VolumeController","getPlayer","playerSourceConfig","playerSourceUiConfig","updateSource","wrappedPlayer","uiVariantsWithoutCondition","PlaylistTransition","uiContainerElement","uiInstanceManagers","uiVariant","InternalUIInstanceManager","resolveUiVariant","adStartedEvent","requestsUi","currentUi","getWrappedPlayer","fireEventInUI","focusVisibilityTracker","localize","setLocalizationConfig","localizationConfig","getUiVariants","switchToUiVariant","uiVariantIndex","previousUi","nextUi","isConfigured","addUi","defaultContext","isFullscreen","clientWidth","switchingContext","nextUiVariant","matchesCondition","dom","configureControls","releaseUi","releaseControls","clearEventHandlers","uiInstanceManager","getTimelineMarkers","addTimelineMarker","timelineMarker","removeTimelineMarker","UIInstanceManager","playerWrapper","configureControlsTree","configured","configuredComponents","configuredComponents_1","constructor","releaseControlsTree","released","isReleased","childComponent","wrapper","eventHandlers","eventType","objectProtoPropertyNames","getOwnPropertyNames","getPrototypeOf","namesToIgnore","methods","properties","members_1","names","newNames","member","methods_1","method","properties_1","propertyDescriptor","propertyDescriptor_1","getOwnPropertyDescriptor","playerEventData","timestamp","uiSourced","visit","recursiveTreeWalker","setVolume","issuerName","setMuted","mute","unmute","isMuted","recallVolume","storeVolume","storedVolume","VolumeTransition","playerMuted","playerVolume","uiMuted","uiVolume","VolumeChanged","Muted","Unmuted","controller","setCueBoxPositionForVerticalWriting","cueContainerDom","subtitleOverlaySize","writingMode","Right","Top","setVttLine","setVttPositionAlign","positionAlign","DirectionPair","VttVerticalWriting","defaultLineNumber","Bottom","Left","setVttLineAlign","relativeCueBoxPosition","lineAlign","setCssForCenterLineAlign","subtitleOverLaySize","targetLine","relativeLinePosition","overlayReferenceEdge","line","snapToLines","cueContainer","GrowingRight","GrowingLeft","textAlign","align","containerSize","regionContainerDom","regionPositionX","viewportAnchorX","regionAnchorX","regionPositionY","viewportAnchorY","lines","regionAnchorY"],"mappings":"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","file":"bitmovinplayer-ui.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","/**\n * @category Utils\n */\nexport namespace ArrayUtils {\n /**\n * Removes an item from an array.\n * @param array the array that may contain the item to remove\n * @param item the item to remove from the array\n * @returns {any} the removed item or null if it wasn't part of the array\n */\n export function remove<T>(array: T[], item: T): T | null {\n let index = array.indexOf(item);\n\n if (index > -1) {\n return array.splice(index, 1)[0];\n } else {\n return null;\n }\n }\n}\n","import { ListItem, ListSelector, ListSelectorConfig } from './components/listselector';\nimport { UIInstanceManager } from './uimanager';\nimport { AudioTrackEvent, PlayerAPI, AudioTrack } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * Helper class to handle all audio tracks related events\n *\n * This class listens to player events as well as the `ListSelector` event if selection changed\n *\n * @category Utils\n */\nexport class AudioTrackSwitchHandler {\n\n private player: PlayerAPI;\n private listElement: ListSelector<ListSelectorConfig>;\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, element: ListSelector<ListSelectorConfig>, uimanager: UIInstanceManager) {\n this.player = player;\n this.listElement = element;\n this.uimanager = uimanager;\n\n this.bindSelectionEvent();\n this.bindPlayerEvents();\n this.refreshAudioTracks();\n }\n\n private bindSelectionEvent(): void {\n this.listElement.onItemSelected.subscribe((_, value: string) => {\n this.player.setAudio(value);\n });\n }\n\n private bindPlayerEvents(): void {\n // Update selection when selected track has changed\n this.player.on(this.player.exports.PlayerEvent.AudioChanged, this.selectCurrentAudioTrack);\n // Update tracks when source goes away\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, this.refreshAudioTracks);\n // Update tracks when the period within a source changes\n this.player.on(this.player.exports.PlayerEvent.PeriodSwitched, this.refreshAudioTracks);\n // Update tracks when a track is added or removed\n this.player.on(this.player.exports.PlayerEvent.AudioAdded, this.addAudioTrack);\n this.player.on(this.player.exports.PlayerEvent.AudioRemoved, this.removeAudioTrack);\n this.uimanager.getConfig().events.onUpdated.subscribe(this.refreshAudioTracks);\n }\n\n private addAudioTrack = (event: AudioTrackEvent) => {\n const audioTrack = event.track;\n if (!this.listElement.hasItem(audioTrack.id)) {\n this.listElement.addItem(audioTrack.id, i18n.getLocalizer(audioTrack.label), true);\n }\n };\n\n private removeAudioTrack = (event: AudioTrackEvent) => {\n const audioTrack = event.track;\n if (this.listElement.hasItem(audioTrack.id)) {\n this.listElement.removeItem(audioTrack.id);\n }\n };\n\n private selectCurrentAudioTrack = () => {\n let currentAudioTrack = this.player.getAudio();\n\n // HLS streams don't always provide this, so we have to check\n if (currentAudioTrack) {\n this.listElement.selectItem(currentAudioTrack.id);\n }\n };\n\n private refreshAudioTracks = () => {\n const audioTracks = this.player.getAvailableAudio();\n const audioTrackToListItem = (audioTrack: AudioTrack): ListItem => {\n return { key: audioTrack.id, label: audioTrack.label };\n };\n\n this.listElement.synchronizeItems(audioTracks.map(audioTrackToListItem));\n this.selectCurrentAudioTrack();\n };\n}\n","declare global {\n interface Navigator {\n msMaxTouchPoints?: number;\n }\n}\n\n/**\n * @category Utils\n */\nexport class BrowserUtils {\n // isMobile only needs to be evaluated once (it cannot change during a browser session)\n // Mobile detection according to Mozilla recommendation: \"In summary, we recommend looking for the string “Mobi”\n // anywhere in the User Agent to detect a mobile device.\"\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent\n static get isMobile(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Mobi/.test(navigator.userAgent);\n }\n\n static get isChrome(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Chrome/.test(navigator.userAgent);\n }\n\n static get isAndroid(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Android/.test(navigator.userAgent) && !this.isHisense;\n }\n\n static get isIOS(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /iPad|iPhone|iPod/.test(navigator.userAgent);\n }\n\n static get isMacIntel(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && navigator.platform === 'MacIntel';\n }\n\n static get isHisense(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Hisense/.test(navigator.userAgent);\n }\n\n static get isPlayStation(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /PlayStation/i.test(navigator.userAgent);\n }\n\n static get isWebOs(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return (\n navigator &&\n navigator.userAgent &&\n (navigator.userAgent.includes('Web0S') || navigator.userAgent.includes('NetCast'))\n );\n }\n\n static get isTizen(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Tizen/.test(navigator.userAgent);\n }\n\n // https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/\n static get isTouchSupported() {\n if (!this.windowExists()) {\n return false;\n }\n return 'ontouchstart' in window || navigator && navigator.userAgent && (navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0);\n }\n\n private static windowExists(): boolean {\n return typeof window !== 'undefined';\n }\n}\n","import { ClickOverlay, ClickOverlayConfig } from './clickoverlay';\nimport { UIInstanceManager } from '../uimanager';\nimport { Ad, AdEvent, PlayerAPI } from 'bitmovin-player';\n\n/**\n * A simple click capture overlay for clickThroughUrls of ads.\n *\n * @category Components\n */\nexport class AdClickOverlay extends ClickOverlay {\n constructor(config: ClickOverlayConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n acceptsTouchWithUiHidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let clickThroughCallback: () => void = null;\n\n player.on(player.exports.PlayerEvent.AdStarted, (event: AdEvent) => {\n let ad = event.ad;\n this.setUrl(ad.clickThroughUrl);\n clickThroughCallback = ad.clickThroughUrlOpened;\n });\n\n // Clear click-through URL when ad has finished\n let adFinishedHandler = () => {\n this.setUrl(null);\n };\n\n player.on(player.exports.PlayerEvent.AdFinished, adFinishedHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adFinishedHandler);\n player.on(player.exports.PlayerEvent.AdError, adFinishedHandler);\n\n this.onClick.subscribe(() => {\n // Pause the ad when overlay is clicked\n player.pause('ui-ad-click-overlay');\n\n if (clickThroughCallback) {\n clickThroughCallback();\n }\n });\n }\n}\n","import {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport { AdEvent, LinearAd, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A label that displays a message about a running ad, optionally with a countdown.\n *\n * @category Components\n */\nexport class AdMessageLabel extends Label<LabelConfig> {\n\n constructor(config: LabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-label-ad-message',\n text: i18n.getLocalizer('ads.remainingTime') ,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let text = config.text;\n\n let updateMessageHandler = () => {\n this.setText(StringUtils.replaceAdMessagePlaceholders(i18n.performLocalization(text), null, player));\n };\n\n let adStartHandler = (event: AdEvent) => {\n let uiConfig = (event.ad as LinearAd).uiConfig;\n text = uiConfig && uiConfig.message || config.text;\n\n updateMessageHandler();\n\n player.on(player.exports.PlayerEvent.TimeChanged, updateMessageHandler);\n };\n\n let adEndHandler = () => {\n player.off(player.exports.PlayerEvent.TimeChanged, updateMessageHandler);\n };\n\n player.on(player.exports.PlayerEvent.AdStarted, adStartHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adEndHandler);\n player.on(player.exports.PlayerEvent.AdError, adEndHandler);\n player.on(player.exports.PlayerEvent.AdFinished, adEndHandler);\n }\n}","import { ButtonConfig, Button } from './button';\nimport { UIInstanceManager } from '../uimanager';\nimport { StringUtils } from '../stringutils';\nimport { AdEvent, LinearAd, PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for the {@link AdSkipButton}.\n *\n * @category Configs\n */\nexport interface AdSkipButtonConfig extends ButtonConfig {\n /**\n * Message which gets displayed during the countdown is active.\n * Supported placeholders: look at {@link StringUtils.replaceAdMessagePlaceholders}\n */\n untilSkippableMessage?: string;\n /**\n * Message displayed when the ad is skippable.\n * Supported placeholders: look at {@link StringUtils.replaceAdMessagePlaceholders}\n */\n skippableMessage?: string;\n}\n\n/**\n * A button that is displayed during ads and can be used to skip the ad.\n *\n * @category Buttons\n */\nexport class AdSkipButton extends Button<AdSkipButtonConfig> {\n\n constructor(config: AdSkipButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <AdSkipButtonConfig>{\n cssClass: 'ui-button-ad-skip',\n untilSkippableMessage: 'Skip ad in {remainingTime}',\n skippableMessage: 'Skip ad',\n acceptsTouchWithUiHidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let untilSkippableMessage = config.untilSkippableMessage;\n let skippableMessage = config.skippableMessage;\n let skipOffset = -1;\n\n let updateSkipMessageHandler = () => {\n this.show();\n\n // Update the skip message on the button\n if (player.getCurrentTime() < skipOffset) {\n this.setText(StringUtils.replaceAdMessagePlaceholders(untilSkippableMessage, skipOffset, player));\n this.disable();\n } else {\n this.setText(skippableMessage);\n this.enable();\n }\n };\n\n let adStartHandler = (event: AdEvent) => {\n let ad = event.ad as LinearAd;\n skipOffset = ad.skippableAfter;\n untilSkippableMessage = ad.uiConfig && ad.uiConfig.untilSkippableMessage || config.untilSkippableMessage;\n skippableMessage = ad.uiConfig && ad.uiConfig.skippableMessage || config.skippableMessage;\n\n // Display this button only if ad is skippable.\n // Non-skippable ads will return -1 for skippableAfter for player version < v8.3.0.\n if (typeof skipOffset === 'number' && skipOffset >= 0) {\n updateSkipMessageHandler();\n player.on(player.exports.PlayerEvent.TimeChanged, updateSkipMessageHandler);\n } else {\n this.hide();\n }\n };\n\n let adEndHandler = () => {\n player.off(player.exports.PlayerEvent.TimeChanged, updateSkipMessageHandler);\n };\n\n player.on(player.exports.PlayerEvent.AdStarted, adStartHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adEndHandler);\n player.on(player.exports.PlayerEvent.AdError, adEndHandler);\n player.on(player.exports.PlayerEvent.AdFinished, adEndHandler);\n\n this.onClick.subscribe(() => {\n // Try to skip the ad (this only works if it is skippable so we don't need to take extra care of that here)\n player.ads.skip();\n });\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles Apple AirPlay.\n *\n * @category Buttons\n */\nexport class AirPlayToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-airplaytogglebutton',\n text: i18n.getLocalizer('appleAirplay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n if (!player.isAirplayAvailable) {\n // If the player does not support Airplay (player 7.0), we just hide this component and skip configuration\n this.hide();\n return;\n }\n\n this.onClick.subscribe(() => {\n if (player.isAirplayAvailable()) {\n player.showAirplayTargetPicker();\n } else {\n if (console) {\n console.log('AirPlay unavailable');\n }\n }\n });\n\n const airPlayAvailableHandler = () => {\n if (player.isAirplayAvailable()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n const airPlayChangedHandler = () => {\n if (player.isAirplayActive()) {\n this.on();\n } else {\n this.off();\n }\n };\n\n player.on(player.exports.PlayerEvent.AirplayAvailable, airPlayAvailableHandler);\n player.on(player.exports.PlayerEvent.AirplayChanged, airPlayChangedHandler);\n\n // Startup init\n airPlayAvailableHandler(); // Hide button if AirPlay is not available\n airPlayChangedHandler();\n }\n}","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between 'auto' and the available audio qualities.\n *\n * @category Components\n */\nexport class AudioQualitySelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-audioqualityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let selectCurrentAudioQuality = () => {\n this.selectItem(player.getAudioQuality().id);\n };\n\n let updateAudioQualities = () => {\n let audioQualities = player.getAvailableAudioQualities();\n\n this.clearItems();\n\n // Add entry for automatic quality switching (default setting)\n this.addItem('auto', i18n.getLocalizer('auto'));\n\n // Add audio qualities\n for (let audioQuality of audioQualities) {\n this.addItem(audioQuality.id, audioQuality.label);\n }\n\n // Select initial quality\n selectCurrentAudioQuality();\n };\n\n this.onItemSelected.subscribe((sender: AudioQualitySelectBox, value: string) => {\n player.setAudioQuality(value);\n });\n\n // Update qualities when audio track has changed\n player.on(player.exports.PlayerEvent.AudioChanged, updateAudioQualities);\n // Update qualities when source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, updateAudioQualities);\n // Update qualities when the period within a source changes\n player.on(player.exports.PlayerEvent.PeriodSwitched, updateAudioQualities);\n // Update quality selection when quality is changed (from outside)\n player.on(player.exports.PlayerEvent.AudioQualityChanged, selectCurrentAudioQuality);\n if ((player.exports.PlayerEvent as any).AudioQualityAdded) {\n // Update qualities when their availability changed\n // TODO: remove any cast after next player release\n player.on((player.exports.PlayerEvent as any).AudioQualityAdded, updateAudioQualities);\n player.on((player.exports.PlayerEvent as any).AudioQualityRemoved, updateAudioQualities);\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(updateAudioQualities);\n }\n}","import {ListBox} from './listbox';\nimport {UIInstanceManager} from '../uimanager';\nimport {AudioTrackSwitchHandler} from '../audiotrackutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A element that is similar to a select box where the user can select a subtitle\n *\n * @category Components\n */\nexport class AudioTrackListBox extends ListBox {\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n new AudioTrackSwitchHandler(player, this, uimanager);\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport {AudioTrackSwitchHandler} from '../audiotrackutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A select box providing a selection between available audio tracks (e.g. different languages).\n *\n * @category Components\n */\nexport class AudioTrackSelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-audiotrackselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new AudioTrackSwitchHandler(player, this, uimanager);\n }\n}","import {ContainerConfig, Container} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for the {@link BufferingOverlay} component.\n *\n * @category Configs\n */\nexport interface BufferingOverlayConfig extends ContainerConfig {\n /**\n * Delay in milliseconds after which the buffering overlay will be displayed. Useful to bypass short stalls without\n * displaying the overlay. Set to 0 to display the overlay instantly.\n * Default: 1000ms (1 second)\n */\n showDelayMs?: number;\n}\n\n/**\n * Overlays the player and displays a buffering indicator.\n *\n * @category Components\n */\nexport class BufferingOverlay extends Container<BufferingOverlayConfig> {\n\n private indicators: Component<ComponentConfig>[];\n\n constructor(config: BufferingOverlayConfig = {}) {\n super(config);\n\n this.indicators = [\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n ];\n\n this.config = this.mergeConfig(config, <BufferingOverlayConfig>{\n cssClass: 'ui-buffering-overlay',\n hidden: true,\n components: this.indicators,\n showDelayMs: 1000,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n let overlayShowTimeout = new Timeout(config.showDelayMs, () => {\n this.show();\n });\n\n let showOverlay = () => {\n overlayShowTimeout.start();\n };\n\n let hideOverlay = () => {\n overlayShowTimeout.clear();\n this.hide();\n };\n\n player.on(player.exports.PlayerEvent.StallStarted, showOverlay);\n player.on(player.exports.PlayerEvent.StallEnded, hideOverlay);\n player.on(player.exports.PlayerEvent.Play, showOverlay);\n player.on(player.exports.PlayerEvent.Playing, hideOverlay);\n player.on(player.exports.PlayerEvent.Paused, hideOverlay);\n player.on(player.exports.PlayerEvent.Seek, showOverlay);\n player.on(player.exports.PlayerEvent.Seeked, hideOverlay);\n player.on(player.exports.PlayerEvent.TimeShift, showOverlay);\n player.on(player.exports.PlayerEvent.TimeShifted, hideOverlay);\n player.on(player.exports.PlayerEvent.SourceUnloaded, hideOverlay);\n\n // Show overlay if player is already stalled at init\n if (player.isStalled()) {\n this.show();\n }\n }\n}\n","import {ComponentConfig, Component} from './component';\nimport {DOM} from '../dom';\nimport {EventDispatcher, NoArgs, Event} from '../eventdispatcher';\nimport { LocalizableText , i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Button} component.\n *\n * @category Configs\n */\nexport interface ButtonConfig extends ComponentConfig {\n /**\n * The text as string or localize callback on the button.\n */\n text?: LocalizableText;\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n */\n ariaLabel?: LocalizableText;\n\n /**\n * Specifies whether the first touch event received by the {@link UIContainer} should be prevented or not.\n *\n * Default: false\n */\n acceptsTouchWithUiHidden?: boolean;\n}\n\n/**\n * A simple clickable button.\n *\n * @category Components\n */\nexport class Button<Config extends ButtonConfig> extends Component<Config> {\n\n private buttonEvents = {\n onClick: new EventDispatcher<Button<Config>, NoArgs>(),\n };\n\n constructor(config: Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-button',\n role: 'button',\n tabIndex: 0,\n acceptsTouchWithUiHidden: false,\n } as Config, this.config);\n }\n\n protected toDomElement(): DOM {\n const buttonElementAttributes: { [name: string]: string } = {\n 'id': this.config.id,\n 'aria-label': i18n.performLocalization(this.config.ariaLabel || this.config.text),\n 'class': this.getCssClasses(),\n 'type' : 'button',\n /**\n * WCAG20 standard to display if a button is pressed or not\n */\n 'aria-pressed': 'false',\n 'tabindex': this.config.tabIndex.toString(),\n };\n\n if (this.config.role != null) {\n buttonElementAttributes['role'] = this.config.role;\n }\n\n // Create the button element with the text label\n let buttonElement = new DOM('button', buttonElementAttributes, this).append(new DOM('span', {\n 'class': this.prefixCss('label'),\n }).html(i18n.performLocalization(this.config.text)));\n\n // Listen for the click event on the button element and trigger the corresponding event on the button component\n buttonElement.on('click', () => {\n this.onClickEvent();\n });\n\n return buttonElement;\n }\n\n /**\n * Sets text on the label of the button.\n * @param text the text to put into the label of the button\n */\n setText(text: LocalizableText): void {\n this.getDomElement().find('.' + this.prefixCss('label')).html(i18n.performLocalization(text));\n }\n\n protected onClickEvent() {\n this.buttonEvents.onClick.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the button is clicked.\n * @returns {Event<Button<Config>, NoArgs>}\n */\n get onClick(): Event<Button<Config>, NoArgs> {\n return this.buttonEvents.onClick.getEvent();\n }\n}\n","import {ContainerConfig, Container} from './container';\nimport {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport { CastStartedEvent, CastWaitingForDeviceEvent, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Overlays the player and displays the status of a Cast session.\n *\n * @category Components\n */\nexport class CastStatusOverlay extends Container<ContainerConfig> {\n\n private statusLabel: Label<LabelConfig>;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.statusLabel = new Label<LabelConfig>({ cssClass: 'ui-cast-status-label' });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-cast-status-overlay',\n components: [this.statusLabel],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n player.on(player.exports.PlayerEvent.CastWaitingForDevice,\n (event: CastWaitingForDeviceEvent) => {\n this.show();\n // Get device name and update status text while connecting\n let castDeviceName = event.castPayload.deviceName;\n this.statusLabel.setText(i18n.getLocalizer('connectingTo', { castDeviceName }));\n });\n player.on(player.exports.PlayerEvent.CastStarted, (event: CastStartedEvent) => {\n // Session is started or resumed\n // For cases when a session is resumed, we do not receive the previous events and therefore show the status panel\n // here too\n this.show();\n let castDeviceName = event.deviceName;\n this.statusLabel.setText(i18n.getLocalizer('playingOn', { castDeviceName }));\n });\n player.on(player.exports.PlayerEvent.CastStopped, (event) => {\n // Cast session gone, hide the status panel\n this.hide();\n });\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles casting to a Cast receiver.\n *\n * @category Buttons\n */\nexport class CastToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-casttogglebutton',\n text: i18n.getLocalizer('googleCast'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n if (player.isCastAvailable()) {\n if (player.isCasting()) {\n player.castStop();\n } else {\n player.castVideo();\n }\n } else {\n if (console) {\n console.log('Cast unavailable');\n }\n }\n });\n\n let castAvailableHander = () => {\n if (player.isCastAvailable()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n player.on(player.exports.PlayerEvent.CastAvailable, castAvailableHander);\n\n // Toggle button 'on' state\n player.on(player.exports.PlayerEvent.CastWaitingForDevice, () => {\n this.on();\n });\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n // When a session is resumed, there is no CastStart event, so we also need to toggle here for such cases\n this.on();\n });\n player.on(player.exports.PlayerEvent.CastStopped, () => {\n this.off();\n });\n\n // Startup init\n castAvailableHander(); // Hide button if Cast not available\n if (player.isCasting()) {\n this.on();\n }\n }\n}","import {UIContainer, UIContainerConfig} from './uicontainer';\nimport {UIInstanceManager} from '../uimanager';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * The base container for Cast receivers that contains all of the UI and takes care that the UI is shown on\n * certain playback events.\n *\n * @category Containers\n */\nexport class CastUIContainer extends UIContainer {\n\n private castUiHideTimeout: Timeout;\n\n constructor(config: UIContainerConfig) {\n super(config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n /*\n * Show UI on Cast devices at certain playback events\n *\n * Since a Cast receiver does not have a direct HCI, we show the UI on certain playback events to give the user\n * a chance to see on the screen what's going on, e.g. on play/pause or a seek the UI is shown and the user can\n * see the current time and position on the seek bar.\n * The UI is shown permanently while playback is paused, otherwise hides automatically after the configured\n * hide delay time.\n */\n\n let isUiShown = false;\n\n let hideUi = () => {\n uimanager.onControlsHide.dispatch(this);\n isUiShown = false;\n };\n\n this.castUiHideTimeout = new Timeout(config.hideDelay, hideUi);\n\n let showUi = () => {\n if (!isUiShown) {\n uimanager.onControlsShow.dispatch(this);\n isUiShown = true;\n }\n };\n\n let showUiPermanently = () => {\n showUi();\n this.castUiHideTimeout.clear();\n };\n\n let showUiWithTimeout = () => {\n showUi();\n this.castUiHideTimeout.start();\n };\n\n let showUiAfterSeek = () => {\n if (player.isPlaying()) {\n showUiWithTimeout();\n } else {\n showUiPermanently();\n }\n };\n\n player.on(player.exports.PlayerEvent.Play, showUiWithTimeout);\n player.on(player.exports.PlayerEvent.Paused, showUiPermanently);\n player.on(player.exports.PlayerEvent.Seek, showUiPermanently);\n player.on(player.exports.PlayerEvent.Seeked, showUiAfterSeek);\n\n uimanager.getConfig().events.onUpdated.subscribe(showUiWithTimeout);\n }\n\n release(): void {\n super.release();\n this.castUiHideTimeout.clear();\n }\n}","import {Button, ButtonConfig} from './button';\n\n/**\n * Configuration interface for a {@link ClickOverlay}.\n *\n * @category Configs\n */\nexport interface ClickOverlayConfig extends ButtonConfig {\n /**\n * The url to open when the overlay is clicked. Set to null to disable the click handler.\n */\n url?: string;\n}\n\n/**\n * A click overlay that opens an url in a new tab if clicked.\n *\n * @category Components\n */\nexport class ClickOverlay extends Button<ClickOverlayConfig> {\n\n constructor(config: ClickOverlayConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-clickoverlay',\n role: this.config.role,\n }, <ClickOverlayConfig>this.config);\n }\n\n initialize(): void {\n super.initialize();\n\n this.setUrl((<ClickOverlayConfig>this.config).url);\n let element = this.getDomElement();\n element.on('click', () => {\n if (element.data('url')) {\n window.open(element.data('url'), '_blank');\n }\n });\n }\n\n /**\n * Gets the URL that should be followed when the watermark is clicked.\n * @returns {string} the watermark URL\n */\n getUrl(): string {\n return this.getDomElement().data('url');\n }\n\n setUrl(url: string): void {\n if (url === undefined || url == null) {\n url = '';\n }\n this.getDomElement().data('url', url);\n }\n}","import {ButtonConfig, Button} from './button';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link CloseButton}.\n *\n * @category Configs\n */\nexport interface CloseButtonConfig extends ButtonConfig {\n /**\n * The component that should be closed when the button is clicked.\n */\n target: Component<ComponentConfig>;\n}\n\n/**\n * A button that closes (hides) a configured component.\n *\n * @category Buttons\n */\nexport class CloseButton extends Button<CloseButtonConfig> {\n\n constructor(config: CloseButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-closebutton',\n text: i18n.getLocalizer('close'),\n } as CloseButtonConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n this.onClick.subscribe(() => {\n config.target.hide();\n });\n }\n}","import {Guid} from '../guid';\nimport {DOM} from '../dom';\nimport {EventDispatcher, NoArgs, Event} from '../eventdispatcher';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n, LocalizableText } from '../localization/i18n';\n\n/**\n * Base configuration interface for a component.\n * Should be extended by components that want to add additional configuration options.\n *\n * @category Configs\n */\nexport interface ComponentConfig {\n /**\n * The HTML tag name of the component.\n * Default: 'div'\n */\n tag?: string;\n /**\n * The HTML ID of the component.\n * Default: automatically generated with pattern 'ui-id-{guid}'.\n */\n id?: string;\n\n /**\n * A prefix to prepend all CSS classes with.\n */\n cssPrefix?: string;\n\n /**\n * The CSS classes of the component. This is usually the class from where the component takes its styling.\n */\n cssClass?: string; // 'class' is a reserved keyword, so we need to make the name more complicated\n\n /**\n * Additional CSS classes of the component.\n */\n cssClasses?: string[];\n\n /**\n * Specifies if the component should be hidden at startup.\n * Default: false\n */\n hidden?: boolean;\n\n /**\n * Specifies if the component is enabled (interactive) or not.\n * Default: false\n */\n disabled?: boolean;\n\n /**\n * Specifies the component role for WCAG20 standard\n */\n role?: string;\n\n /**\n * WCAG20 requirement for screen reader navigation\n */\n tabIndex?: number;\n\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n */\n ariaLabel?: LocalizableText;\n}\n\nexport interface ComponentHoverChangedEventArgs extends NoArgs {\n /**\n * True is the component is hovered, else false.\n */\n hovered: boolean;\n}\n\nexport enum ViewMode {\n /**\n * Indicates that the component has entered a view mode where it must stay visible. Auto-hiding of this component\n * must be disabled as long as it resides in this state.\n */\n Persistent = 'persistent',\n\n /**\n * The control can be hidden at any time.\n */\n Temporary = 'temporary',\n}\n\nexport interface ViewModeChangedEventArgs extends NoArgs {\n /**\n * The `ViewMode` the control is currently in.\n */\n mode: ViewMode;\n}\n\n/**\n * The base class of the UI framework.\n * Each component must extend this class and optionally the config interface.\n *\n * @category Components\n */\nexport class Component<Config extends ComponentConfig> {\n\n /**\n * The classname that is attached to the element when it is in the hidden state.\n * @type {string}\n */\n private static readonly CLASS_HIDDEN = 'hidden';\n\n /**\n * The classname that is attached to the element when it is in the disabled state.\n * @type {string}\n */\n private static readonly CLASS_DISABLED = 'disabled';\n\n /**\n * Configuration object of this component.\n */\n protected config: Config;\n\n /**\n * The component's DOM element.\n */\n private element: DOM;\n\n /**\n * Flag that keeps track of the hidden state.\n */\n private hidden: boolean;\n\n /**\n * Flat that keeps track of the disabled state.\n */\n private disabled: boolean;\n\n /**\n * Flag that keeps track of the hover state.\n */\n private hovered: boolean;\n\n /**\n * The current view mode of the component.\n */\n private viewMode: ViewMode;\n\n /**\n * The list of events that this component offers. These events should always be private and only directly\n * accessed from within the implementing component.\n *\n * Because TypeScript does not support private properties with the same name on different class hierarchy levels\n * (i.e. superclass and subclass cannot contain a private property with the same name), the default naming\n * convention for the event list of a component that should be followed by subclasses is the concatenation of the\n * camel-cased class name + 'Events' (e.g. SubClass extends Component => subClassEvents).\n * See {@link #componentEvents} for an example.\n *\n * Event properties should be named in camel case with an 'on' prefix and in the present tense. Async events may\n * have a start event (when the operation starts) in the present tense, and must have an end event (when the\n * operation ends) in the past tense (or present tense in special cases (e.g. onStart/onStarted or onPlay/onPlaying).\n * See {@link #componentEvents#onShow} for an example.\n *\n * Each event should be accompanied with a protected method named by the convention eventName + 'Event'\n * (e.g. onStartEvent), that actually triggers the event by calling {@link EventDispatcher#dispatch dispatch} and\n * passing a reference to the component as first parameter. Components should always trigger their events with these\n * methods. Implementing this pattern gives subclasses means to directly listen to the events by overriding the\n * method (and saving the overhead of passing a handler to the event dispatcher) and more importantly to trigger\n * these events without having access to the private event list.\n * See {@link #onShow} for an example.\n *\n * To provide external code the possibility to listen to this component's events (subscribe, unsubscribe, etc.),\n * each event should also be accompanied by a public getter function with the same name as the event's property,\n * that returns the {@link Event} obtained from the event dispatcher by calling {@link EventDispatcher#getEvent}.\n * See {@link #onShow} for an example.\n *\n * Full example for an event representing an example action in a example component:\n *\n * <code>\n * // Define an example component class with an example event\n * class ExampleComponent extends Component<ComponentConfig> {\n *\n * private exampleComponentEvents = {\n * onExampleAction: new EventDispatcher<ExampleComponent, NoArgs>()\n * }\n *\n * // constructor and other stuff...\n *\n * protected onExampleActionEvent() {\n * this.exampleComponentEvents.onExampleAction.dispatch(this);\n * }\n *\n * get onExampleAction(): Event<ExampleComponent, NoArgs> {\n * return this.exampleComponentEvents.onExampleAction.getEvent();\n * }\n * }\n *\n * // Create an instance of the component somewhere\n * var exampleComponentInstance = new ExampleComponent();\n *\n * // Subscribe to the example event on the component\n * exampleComponentInstance.onExampleAction.subscribe(function (sender: ExampleComponent) {\n * console.log('onExampleAction of ' + sender + ' has fired!');\n * });\n * </code>\n */\n private componentEvents = {\n onShow: new EventDispatcher<Component<Config>, NoArgs>(),\n onHide: new EventDispatcher<Component<Config>, NoArgs>(),\n onViewModeChanged: new EventDispatcher<Component<Config>, ViewModeChangedEventArgs>(),\n onHoverChanged: new EventDispatcher<Component<Config>, ComponentHoverChangedEventArgs>(),\n onEnabled: new EventDispatcher<Component<Config>, NoArgs>(),\n onDisabled: new EventDispatcher<Component<Config>, NoArgs>(),\n };\n\n /**\n * Constructs a component with an optionally supplied config. All subclasses must call the constructor of their\n * superclass and then merge their configuration into the component's configuration.\n * @param config the configuration for the component\n */\n constructor(config: ComponentConfig = {}) {\n // Create the configuration for this component\n this.config = <Config>this.mergeConfig(config, {\n tag: 'div',\n id: '{{PREFIX}}-id-' + Guid.next(),\n cssPrefix: '{{PREFIX}}',\n cssClass: 'ui-component',\n cssClasses: [],\n hidden: false,\n disabled: false,\n }, {});\n this.viewMode = ViewMode.Temporary;\n }\n\n /**\n * Initializes the component, e.g. by applying config settings.\n * This method must not be called from outside the UI framework.\n *\n * This method is automatically called by the {@link UIInstanceManager}. If the component is an inner component of\n * some component, and thus encapsulated abd managed internally and never directly exposed to the UIManager,\n * this method must be called from the managing component's {@link #initialize} method.\n */\n initialize(): void {\n this.hidden = this.config.hidden;\n this.disabled = this.config.disabled;\n\n // Hide the component at initialization if it is configured to be hidden\n if (this.isHidden()) {\n this.hidden = false; // Set flag to false for the following hide() call to work (hide() checks the flag)\n this.hide();\n }\n\n // Disable the component at initialization if it is configured to be disabled\n if (this.isDisabled()) {\n this.disabled = false; // Set flag to false for the following disable() call to work (disable() checks the flag)\n this.disable();\n }\n }\n\n /**\n * Configures the component for the supplied Player and UIInstanceManager. This is the place where all the magic\n * happens, where components typically subscribe and react to events (on their DOM element, the Player, or the\n * UIInstanceManager), and basically everything that makes them interactive.\n * This method is called only once, when the UIManager initializes the UI.\n *\n * Subclasses usually overwrite this method to add their own functionality.\n *\n * @param player the player which this component controls\n * @param uimanager the UIInstanceManager that manages this component\n */\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n this.onShow.subscribe(() => uimanager.onComponentShow.dispatch(this));\n this.onHide.subscribe(() => uimanager.onComponentHide.dispatch(this));\n this.onViewModeChanged.subscribe((_, args) => uimanager.onComponentViewModeChanged.dispatch(this, args));\n\n // Track the hovered state of the element\n this.getDomElement().on('mouseenter', () => this.onHoverChangedEvent(true));\n this.getDomElement().on('mouseleave', () => this.onHoverChangedEvent(false));\n }\n\n /**\n * Releases all resources and dependencies that the component holds. Player, DOM, and UIManager events are\n * automatically removed during release and do not explicitly need to be removed here.\n * This method is called by the UIManager when it releases the UI.\n *\n * Subclasses that need to release resources should override this method and call super.release().\n */\n release(): void {\n // Nothing to do here, override where necessary\n }\n\n /**\n * Generate the DOM element for this component.\n *\n * Subclasses usually overwrite this method to extend or replace the DOM element with their own design.\n */\n protected toDomElement(): DOM {\n let element = new DOM(this.config.tag, {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': this.config.role,\n }, this);\n\n return element;\n }\n\n /**\n * Returns the DOM element of this component. Creates the DOM element if it does not yet exist.\n *\n * Should not be overwritten by subclasses.\n *\n * @returns {DOM}\n */\n getDomElement(): DOM {\n if (!this.element) {\n this.element = this.toDomElement();\n }\n\n return this.element;\n }\n\n /**\n * Checks if this component has a DOM element.\n */\n hasDomElement(): boolean {\n return Boolean(this.element);\n }\n\n setAriaLabel(label: LocalizableText): void {\n this.setAriaAttr('label', i18n.performLocalization(label));\n }\n\n setAriaAttr(name: string, value: string) {\n this.getDomElement().attr(`aria-${name}`, value);\n }\n\n /**\n * Merges a configuration with a default configuration and a base configuration from the superclass.\n *\n * @param config the configuration settings for the components, as usually passed to the constructor\n * @param defaults a default configuration for settings that are not passed with the configuration\n * @param base configuration inherited from a superclass\n * @returns {Config}\n */\n protected mergeConfig<Config>(config: Config, defaults: Config, base: Config): Config {\n // Extend default config with supplied config\n let merged = Object.assign({}, base, defaults, config);\n\n // Return the extended config\n return merged;\n }\n\n /**\n * Helper method that returns a string of all CSS classes of the component.\n *\n * @returns {string}\n */\n protected getCssClasses(): string {\n // Merge all CSS classes into single array\n let flattenedArray = [this.config.cssClass].concat(this.config.cssClasses);\n // Prefix classes\n flattenedArray = flattenedArray.map((css) => {\n return this.prefixCss(css);\n });\n // Join array values into a string\n let flattenedString = flattenedArray.join(' ');\n // Return trimmed string to prevent whitespace at the end from the join operation\n return flattenedString.trim();\n }\n\n protected prefixCss(cssClassOrId: string): string {\n return this.config.cssPrefix + '-' + cssClassOrId;\n }\n\n /**\n * Returns the configuration object of the component.\n * @returns {Config}\n */\n public getConfig(): Config {\n return this.config;\n }\n\n /**\n * Hides the component if shown.\n * This method basically transfers the component into the hidden state. Actual hiding is done via CSS.\n */\n hide() {\n if (!this.hidden) {\n this.hidden = true;\n this.getDomElement().addClass(this.prefixCss(Component.CLASS_HIDDEN));\n this.onHideEvent();\n }\n }\n\n /**\n * Shows the component if hidden.\n */\n show() {\n if (this.hidden) {\n this.getDomElement().removeClass(this.prefixCss(Component.CLASS_HIDDEN));\n this.hidden = false;\n this.onShowEvent();\n }\n }\n\n /**\n * Determines if the component is hidden.\n * @returns {boolean} true if the component is hidden, else false\n */\n isHidden(): boolean {\n return this.hidden;\n }\n\n /**\n * Determines if the component is shown.\n * @returns {boolean} true if the component is visible, else false\n */\n isShown(): boolean {\n return !this.isHidden();\n }\n\n /**\n * Toggles the hidden state by hiding the component if it is shown, or showing it if hidden.\n */\n toggleHidden() {\n if (this.isHidden()) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n /**\n * Disables the component.\n * This method basically transfers the component into the disabled state. Actual disabling is done via CSS or child\n * components. (e.g. Button needs to unsubscribe click listeners)\n */\n disable(): void {\n if (!this.disabled) {\n this.disabled = true;\n this.getDomElement().addClass(this.prefixCss(Component.CLASS_DISABLED));\n this.onDisabledEvent();\n }\n }\n\n /**\n * Enables the component.\n * This method basically transfers the component into the enabled state. Actual enabling is done via CSS or child\n * components. (e.g. Button needs to subscribe click listeners)\n */\n enable(): void {\n if (this.disabled) {\n this.getDomElement().removeClass(this.prefixCss(Component.CLASS_DISABLED));\n this.disabled = false;\n this.onEnabledEvent();\n }\n }\n\n /**\n * Determines if the component is disabled.\n * @returns {boolean} true if the component is disabled, else false\n */\n isDisabled(): boolean {\n return this.disabled;\n }\n\n /**\n * Determines if the component is enabled.\n * @returns {boolean} true if the component is enabled, else false\n */\n isEnabled(): boolean {\n return !this.isDisabled();\n }\n\n /**\n * Determines if the component is currently hovered.\n * @returns {boolean} true if the component is hovered, else false\n */\n isHovered(): boolean {\n return this.hovered;\n }\n\n /**\n * Fires the onShow event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onShowEvent(): void {\n this.componentEvents.onShow.dispatch(this);\n }\n\n /**\n * Fires the onHide event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onHideEvent(): void {\n this.componentEvents.onHide.dispatch(this);\n }\n\n /**\n * Fires the onEnabled event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onEnabledEvent(): void {\n this.componentEvents.onEnabled.dispatch(this);\n }\n\n /**\n * Fires the onDisabled event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onDisabledEvent(): void {\n this.componentEvents.onDisabled.dispatch(this);\n }\n\n /**\n * Fires the onViewModeChanged event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onViewModeChangedEvent(mode: ViewMode): void {\n if (this.viewMode === mode) {\n return;\n }\n\n this.viewMode = mode;\n this.componentEvents.onViewModeChanged.dispatch(this, { mode });\n }\n\n /**\n * Fires the onHoverChanged event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onHoverChangedEvent(hovered: boolean): void {\n this.hovered = hovered;\n this.componentEvents.onHoverChanged.dispatch(this, { hovered: hovered });\n }\n\n /**\n * Gets the event that is fired when the component is showing.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onShow(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onShow.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is hiding.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onHide(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onHide.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is enabling.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onEnabled(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onEnabled.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is disabling.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onDisabled(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onDisabled.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component's hover-state is changing.\n * @returns {Event<Component<Config>, ComponentHoverChangedEventArgs>}\n */\n get onHoverChanged(): Event<Component<Config>, ComponentHoverChangedEventArgs> {\n return this.componentEvents.onHoverChanged.getEvent();\n }\n\n /**\n * Gets the event that is fired when the `ViewMode` of this component has changed.\n * @returns {Event<Component<Config>, ViewModeChangedEventArgs>}\n */\n get onViewModeChanged(): Event<Component<Config>, ViewModeChangedEventArgs> {\n return this.componentEvents.onViewModeChanged.getEvent();\n }\n}","import { ComponentConfig, Component, ViewModeChangedEventArgs, ViewMode } from './component';\nimport {DOM} from '../dom';\nimport {ArrayUtils} from '../arrayutils';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Container}.\n *\n * @category Configs\n */\nexport interface ContainerConfig extends ComponentConfig {\n /**\n * Child components of the container.\n */\n components?: Component<ComponentConfig>[];\n}\n\n/**\n * A container component that can contain a collection of child components.\n * Components can be added at construction time through the {@link ContainerConfig#components} setting, or later\n * through the {@link Container#addComponent} method. The UIManager automatically takes care of all components, i.e. it\n * initializes and configures them automatically.\n *\n * In the DOM, the container consists of an outer <div> (that can be configured by the config) and an inner wrapper\n * <div> that contains the components. This double-<div>-structure is often required to achieve many advanced effects\n * in CSS and/or JS, e.g. animations and certain formatting with absolute positioning.\n *\n * DOM example:\n * <code>\n * <div class='ui-container'>\n * <div class='container-wrapper'>\n * ... child components ...\n * </div>\n * </div>\n * </code>\n *\n * @category Components\n */\nexport class Container<Config extends ContainerConfig> extends Component<Config> {\n\n /**\n * A reference to the inner element that contains the components of the container.\n */\n private innerContainerElement: DOM;\n private componentsToAdd: Component<ComponentConfig>[];\n private componentsToRemove: Component<ComponentConfig>[];\n private componentsInPersistentViewMode: number;\n\n constructor(config: Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-container',\n components: [],\n } as Config, this.config);\n\n this.componentsToAdd = [];\n this.componentsToRemove = [];\n this.componentsInPersistentViewMode = 0;\n }\n\n /**\n * Adds a child component to the container.\n * @param component the component to add\n */\n addComponent(component: Component<ComponentConfig>) {\n this.config.components.push(component);\n this.componentsToAdd.push(component);\n }\n\n /**\n * Removes a child component from the container.\n * @param component the component to remove\n * @returns {boolean} true if the component has been removed, false if it is not contained in this container\n */\n removeComponent(component: Component<ComponentConfig>): boolean {\n if (ArrayUtils.remove(this.config.components, component) != null) {\n this.componentsToRemove.push(component);\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Gets an array of all child components in this container.\n * @returns {Component<ComponentConfig>[]}\n */\n getComponents(): Component<ComponentConfig>[] {\n return this.config.components;\n }\n\n /**\n * Removes all child components from the container.\n */\n removeComponents(): void {\n for (let component of this.getComponents().slice()) {\n this.removeComponent(component);\n }\n }\n\n /**\n * Updates the DOM of the container with the current components.\n */\n protected updateComponents(): void {\n /* We cannot just clear the container to remove all elements and then re-add those that should stay, because\n * IE looses the innerHTML of unattached elements, leading to empty elements within the container (e.g. missing\n * subtitle text in SubtitleLabel).\n * Instead, we keep a list of elements to add and remove, leaving remaining elements alone. By keeping them in\n * the DOM, their content gets preserved in all browsers.\n */\n let component;\n\n while (component = this.componentsToRemove.shift()) {\n component.getDomElement().remove();\n }\n\n while (component = this.componentsToAdd.shift()) {\n this.innerContainerElement.append(component.getDomElement());\n }\n }\n\n protected toDomElement(): DOM {\n // Create the container element (the outer <div>)\n let containerElement = new DOM(this.config.tag, {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': this.config.role,\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n }, this);\n\n // Create the inner container element (the inner <div>) that will contain the components\n let innerContainer = new DOM(this.config.tag, {\n 'class': this.prefixCss('container-wrapper'),\n });\n this.innerContainerElement = innerContainer;\n\n for (let initialComponent of this.config.components) {\n this.componentsToAdd.push(initialComponent);\n }\n this.updateComponents();\n\n containerElement.append(innerContainer);\n\n return containerElement;\n }\n\n protected suspendHideTimeout(): void {\n // to be implemented in subclass\n }\n\n protected resumeHideTimeout(): void {\n // to be implemented in subclass\n }\n\n protected trackComponentViewMode(mode: ViewMode) {\n if (mode === ViewMode.Persistent) {\n this.componentsInPersistentViewMode++;\n } else if (mode === ViewMode.Temporary) {\n this.componentsInPersistentViewMode = Math.max(this.componentsInPersistentViewMode - 1, 0);\n }\n\n if (this.componentsInPersistentViewMode > 0) {\n // There is at least one component that must not be hidden,\n // therefore the hide timeout must be suspended\n this.suspendHideTimeout();\n } else {\n this.resumeHideTimeout();\n }\n }\n}","import {ContainerConfig, Container} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {UIUtils} from '../uiutils';\nimport {Spacer} from './spacer';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { BrowserUtils } from '../browserutils';\nimport {Component, ComponentConfig} from './component';\nimport {SettingsPanel} from './settingspanel';\n\n/**\n * Configuration interface for the {@link ControlBar}.\n *\n * @category Configs\n */\nexport interface ControlBarConfig extends ContainerConfig {\n // nothing yet\n}\n\n/**\n * A container for main player control components, e.g. play toggle button, seek bar, volume control, fullscreen toggle\n * button.\n *\n * @category Components\n */\nexport class ControlBar extends Container<ControlBarConfig> {\n\n constructor(config: ControlBarConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-controlbar',\n hidden: true,\n role: 'region',\n ariaLabel: i18n.getLocalizer('controlBar'),\n }, <ControlBarConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n // Counts how many components are hovered and block hiding of the control bar\n let hoverStackCount = 0;\n let isSettingsPanelShown = false;\n\n // Only enabling this for platforms without touch input.\n // Enabling this for touch devices causes the UI to not disappear after hideDelay seconds,\n // because `mouseleave` event is not emitted.\n // Instead, it will stay visible until another manual interaction is performed.\n if (uimanager.getConfig().disableAutoHideWhenHovered && !BrowserUtils.isTouchSupported) {\n // Track hover status of child components\n UIUtils.traverseTree(this, (component) => {\n // Do not track hover status of child containers or spacers, only of 'real' controls\n if (component instanceof Container || component instanceof Spacer) {\n return;\n }\n\n // Subscribe hover event and keep a count of the number of hovered children\n component.onHoverChanged.subscribe((_, args) => {\n if (args.hovered) {\n hoverStackCount++;\n } else {\n hoverStackCount--;\n }\n });\n });\n }\n\n if (BrowserUtils.isMobile) {\n uimanager.onComponentShow.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof SettingsPanel) {\n isSettingsPanelShown = true;\n }\n });\n\n uimanager.onComponentHide.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof SettingsPanel) {\n isSettingsPanelShown = false;\n }\n });\n }\n\n uimanager.onControlsShow.subscribe(() => {\n this.show();\n });\n\n uimanager.onPreviewControlsHide.subscribe((sender, args) => {\n // Cancel the hide event if hovered child components block hiding or if the settings panel is active on mobile.\n args.cancel = args.cancel || (hoverStackCount > 0 || isSettingsPanelShown);\n });\n\n uimanager.onControlsHide.subscribe(() => {\n this.hide();\n });\n }\n}\n","import { PlayerAPI, SegmentPlaybackEvent, VideoQuality } from 'bitmovin-player';\r\nimport { i18n } from '../localization/i18n';\r\nimport { Container, ContainerConfig } from './container';\r\nimport { EcoModeToggleButton } from './ecomodetogglebutton';\r\nimport { Label, LabelConfig } from './label';\r\nimport { SettingsPanelItem } from './settingspanelitem';\r\n\r\n/**\r\n * @category Containers\r\n */\r\nexport class EcoModeContainer extends Container<ContainerConfig> {\r\n private ecoModeSavedEmissionsItem: SettingsPanelItem;\r\n private ecoModeToggleButtonItem: SettingsPanelItem;\r\n private emissionsSavedLabel: Label<LabelConfig>;\r\n private savedEmissons = 0;\r\n private currentEnergyEmission: number;\r\n\r\n constructor(config: ContainerConfig = {}) {\r\n super(config);\r\n\r\n const ecoModeToggleButton = new EcoModeToggleButton();\r\n const labelEcoMode = new Label({\r\n text: i18n.getLocalizer('ecoMode.title'),\r\n for: ecoModeToggleButton.getConfig().id,\r\n id: 'ecomodelabel',\r\n });\r\n this.emissionsSavedLabel = new Label({\r\n text: `${this.savedEmissons.toFixed(4)} gCO2`,\r\n cssClass: 'ui-label-savedEnergy',\r\n });\r\n\r\n this.ecoModeToggleButtonItem = new SettingsPanelItem(labelEcoMode, ecoModeToggleButton);\r\n this.ecoModeSavedEmissionsItem = new SettingsPanelItem('Saved Emissions', this.emissionsSavedLabel, {\r\n hidden: true,\r\n });\r\n\r\n this.addComponent(this.ecoModeToggleButtonItem);\r\n this.addComponent(this.ecoModeSavedEmissionsItem);\r\n\r\n ecoModeToggleButton.onToggleOn.subscribe(() => {\r\n this.ecoModeSavedEmissionsItem.show();\r\n this.onToggleCallback();\r\n });\r\n\r\n ecoModeToggleButton.onToggleOff.subscribe(() => {\r\n this.ecoModeSavedEmissionsItem.hide();\r\n this.onToggleCallback();\r\n });\r\n }\r\n\r\n private onToggleCallback: () => void;\r\n\r\n public setOnToggleCallback(callback: () => void) {\r\n this.onToggleCallback = callback;\r\n }\r\n\r\n configure(player: PlayerAPI): void {\r\n player.on(player.exports.PlayerEvent.SegmentPlayback, (segment: SegmentPlaybackEvent) => {\r\n if (!segment.mimeType.includes('video')) {\r\n return;\r\n }\r\n\r\n const { height, width, bitrate, frameRate } = segment.mediaInfo;\r\n const {\r\n height: maxHeight,\r\n bitrate: maxBitrate,\r\n width: maxWidth,\r\n } = this.getMaxQualityAvailable(player.getAvailableVideoQualities());\r\n\r\n const currentEnergyKwh = this.calculateEnergyConsumption(frameRate, height, width, bitrate, segment.duration);\r\n\r\n const maxEnergyKwh = this.calculateEnergyConsumption(\r\n frameRate,\r\n maxHeight,\r\n maxWidth,\r\n maxBitrate,\r\n segment.duration,\r\n );\r\n\r\n if (this.ecoModeSavedEmissionsItem.isShown()) {\r\n this.updateSavedEmissions(currentEnergyKwh, maxEnergyKwh, this.emissionsSavedLabel);\r\n }\r\n });\r\n }\r\n\r\n updateSavedEmissions(\r\n currentEnergyConsuption: number,\r\n maxEnergyConsuption: number,\r\n emissionsSavedLabel: Label<LabelConfig>,\r\n ) {\r\n // 475 is the average carbon intensity of all countries in gCO2/kWh\r\n const averageCarbonIntensity = 475;\r\n\r\n this.currentEnergyEmission = currentEnergyConsuption * averageCarbonIntensity;\r\n const maxEnergyEmisson = maxEnergyConsuption * averageCarbonIntensity;\r\n this.savedEmissons += maxEnergyEmisson - this.currentEnergyEmission;\r\n emissionsSavedLabel.setText(this.savedEmissons.toFixed(4) + ' gCO2');\r\n }\r\n\r\n /**\r\n * The calculations are based on the following paper: https://arxiv.org/pdf/2210.05444.pdf\r\n */\r\n calculateEnergyConsumption(fps: number, height: number, width: number, bitrate: number, duration: number): number {\r\n const fpsWeight = 0.035;\r\n const pixeldWeight = 5.76e-9;\r\n const birateWeight = 6.97e-6;\r\n const constantOffset = 8.52;\r\n const bitrateInternetWeight = 3.24e-5;\r\n const internetConnectionOffset = 1.15;\r\n const videoCodec = 4.16;\r\n\r\n const energyConsumptionW =\r\n fpsWeight * fps +\r\n pixeldWeight * height * width +\r\n (birateWeight + bitrateInternetWeight) * (bitrate / 1000) +\r\n videoCodec +\r\n constantOffset +\r\n internetConnectionOffset;\r\n\r\n // Convert energy consumption from Watts (W) to Kilowatt-hours (kWh) for the given time duration of the segment\r\n const energyConsumptionKwh = (energyConsumptionW * duration) / 3.6e6;\r\n\r\n return energyConsumptionKwh;\r\n }\r\n getMaxQualityAvailable(availableVideoQualities: VideoQuality[]) {\r\n const sortedQualities = availableVideoQualities.sort((a, b) => a.bitrate - b.bitrate);\r\n return sortedQualities[sortedQualities.length - 1];\r\n }\r\n}\r\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\r\nimport { UIInstanceManager } from '../uimanager';\r\nimport { DynamicAdaptationConfig, PlayerAPI, VideoQualityChangedEvent } from 'bitmovin-player';\r\nimport { i18n } from '../localization/i18n';\r\n\r\n/**\r\n * @category Buttons\r\n */\r\nexport class EcoModeToggleButton extends ToggleButton<ToggleButtonConfig> {\r\n private adaptationConfig: DynamicAdaptationConfig;\r\n\r\n constructor(config: ToggleButtonConfig = {}) {\r\n super(config);\r\n\r\n const defaultConfig: ToggleButtonConfig = {\r\n text: i18n.getLocalizer('ecoMode'),\r\n cssClass: 'ui-ecomodetogglebutton',\r\n onClass: 'on',\r\n offClass: 'off',\r\n ariaLabel: i18n.getLocalizer('ecoMode'),\r\n };\r\n\r\n this.config = this.mergeConfig(config, defaultConfig, this.config);\r\n }\r\n\r\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\r\n super.configure(player, uimanager);\r\n\r\n if (this.areAdaptationApisAvailable(player)) {\r\n this.onClick.subscribe(() => {\r\n this.toggle();\r\n });\r\n\r\n this.onToggleOn.subscribe(() => {\r\n this.enableEcoMode(player);\r\n player.setVideoQuality('auto');\r\n });\r\n\r\n this.onToggleOff.subscribe(() => {\r\n this.disableEcoMode(player);\r\n });\r\n\r\n player.on(player.exports.PlayerEvent.VideoQualityChanged, (quality: VideoQualityChangedEvent) => {\r\n if (quality.targetQuality.id !== 'auto') {\r\n this.off();\r\n this.disableEcoMode(player);\r\n }\r\n });\r\n } else {\r\n super.disable();\r\n }\r\n\r\n }\r\n\r\n private areAdaptationApisAvailable(player: PlayerAPI): boolean {\r\n const isGetConfigAvailable = Boolean(player.adaptation.getConfig && typeof player.adaptation.getConfig === 'function');\r\n const isSetConfigAvailable = Boolean(player.adaptation.setConfig && typeof player.adaptation.setConfig === 'function');\r\n\r\n return Boolean(player.adaptation && isGetConfigAvailable && isSetConfigAvailable);\r\n }\r\n\r\n enableEcoMode(player: PlayerAPI): void {\r\n this.adaptationConfig = player.adaptation.getConfig();\r\n const codec = player.getAvailableVideoQualities()[0].codec;\r\n\r\n if (codec.includes('avc')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 720 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n if (codec.includes('hvc') || codec.includes('hev')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 1080 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n if (codec.includes('av1') || codec.includes('av01')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 1440 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n }\r\n\r\n disableEcoMode(player: PlayerAPI): void {\r\n player.adaptation.setConfig(this.adaptationConfig);\r\n }\r\n}\r\n","import {ContainerConfig, Container} from './container';\nimport {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {TvNoiseCanvas} from './tvnoisecanvas';\nimport { ErrorUtils } from '../errorutils';\nimport { ErrorEvent, PlayerAPI, PlayerEventBase } from 'bitmovin-player';\nimport {\n isMobileV3PlayerAPI,\n MobileV3PlayerAPI, MobileV3PlayerErrorEvent, MobileV3PlayerEvent, MobileV3SourceErrorEvent,\n} from '../mobilev3playerapi';\n\nexport interface ErrorMessageTranslator {\n (error: ErrorEvent | MobileV3PlayerErrorEvent): string;\n}\n\nexport interface ErrorMessageMap {\n [code: number]: string | ErrorMessageTranslator;\n}\n\n/**\n * Configuration interface for the {@link ErrorMessageOverlay}.\n *\n * @category Configs\n */\nexport interface ErrorMessageOverlayConfig extends ContainerConfig {\n /**\n * Allows overwriting of the error messages displayed in the overlay for customization and localization.\n * This is either a function that receives any {@link ErrorEvent} as parameter and translates error messages,\n * or a map of error codes that overwrites specific error messages with a plain string or a function that\n * receives the {@link ErrorEvent} as parameter and returns a customized string.\n * The translation functions can be used to extract data (e.g. parameters) from the original error message.\n *\n * Example 1 (catch-all translation function):\n * <code>\n * errorMessageOverlayConfig = {\n * messages: function(error) {\n * switch (error.code) {\n * // Overwrite error 1000 'Unknown error'\n * case 1000:\n * return 'Houston, we have a problem'\n *\n * // Transform error 1201 'The downloaded manifest is invalid' to uppercase\n * case 1201:\n * var description = ErrorUtils.defaultErrorMessages[error.code];\n * return description.toUpperCase();\n *\n * // Customize error 1207 'The manifest could not be loaded'\n * case 1207:\n * var statusCode = error.data.statusCode;\n * return 'Manifest loading failed with HTTP error ' + statusCode;\n * }\n * // Return unmodified error message for all other errors\n * return error.message;\n * }\n * };\n * </code>\n *\n * Example 2 (translating specific errors):\n * <code>\n * errorMessageOverlayConfig = {\n * messages: {\n * // Overwrite error 1000 'Unknown error'\n * 1000: 'Houston, we have a problem',\n *\n * // Transform error 1201 'Unsupported manifest format' to uppercase\n * 1201: function(error) {\n * var description = ErrorUtils.defaultErrorMessages[error.code];\n * return description.toUpperCase();\n * },\n *\n * // Customize error 1207 'The manifest could not be loaded'\n * 1207: function(error) {\n * var statusCode = error.data.statusCode;\n * return 'Manifest loading failed with HTTP error ' + statusCode;\n * }\n * }\n * };\n * </code>\n */\n messages?: ErrorMessageMap | ErrorMessageTranslator;\n}\n\n/**\n * Overlays the player and displays error messages.\n *\n * @category Components\n */\nexport class ErrorMessageOverlay extends Container<ErrorMessageOverlayConfig> {\n\n private errorLabel: Label<LabelConfig>;\n private tvNoiseBackground: TvNoiseCanvas;\n\n constructor(config: ErrorMessageOverlayConfig = {}) {\n super(config);\n\n this.errorLabel = new Label<LabelConfig>({ cssClass: 'ui-errormessage-label' });\n this.tvNoiseBackground = new TvNoiseCanvas();\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-errormessage-overlay',\n components: [this.tvNoiseBackground, this.errorLabel],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI | MobileV3PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n const handleErrorMessage = (\n event: ErrorEvent | MobileV3SourceErrorEvent | MobileV3PlayerErrorEvent,\n message: string,\n ) => {\n const customizedMessage = customizeErrorMessage(uimanager.getConfig().errorMessages || config.messages, event);\n if (customizedMessage) {\n message = customizedMessage;\n }\n\n this.display(message);\n };\n\n if (isMobileV3PlayerAPI(player)) {\n const errorEventHandler = (event: MobileV3SourceErrorEvent | MobileV3PlayerErrorEvent) => {\n const message = ErrorUtils.defaultMobileV3ErrorMessageTranslator(event);\n handleErrorMessage(event, message);\n };\n\n player.on(MobileV3PlayerEvent.PlayerError, errorEventHandler);\n player.on(MobileV3PlayerEvent.SourceError, errorEventHandler);\n } else {\n player.on(player.exports.PlayerEvent.Error, (event: ErrorEvent) => {\n let message = ErrorUtils.defaultWebErrorMessageTranslator(event);\n handleErrorMessage(event, message);\n });\n }\n\n player.on(player.exports.PlayerEvent.SourceLoaded, (event: PlayerEventBase) => {\n if (this.isShown()) {\n this.tvNoiseBackground.stop();\n this.hide();\n }\n });\n }\n\n display(errorMessage: string): void {\n this.errorLabel.setText(errorMessage);\n this.tvNoiseBackground.start();\n this.show();\n }\n\n release(): void {\n super.release();\n\n // Canvas rendering must be explicitly stopped, else it just continues forever and hogs resources\n this.tvNoiseBackground.stop();\n }\n}\n\nfunction customizeErrorMessage(\n errorMessages: ErrorMessageTranslator | ErrorMessageMap,\n event: ErrorEvent | MobileV3PlayerErrorEvent | MobileV3SourceErrorEvent,\n): string | undefined {\n if (!errorMessages) {\n return undefined;\n }\n\n // Process message vocabularies\n if (typeof errorMessages === 'function') {\n // Translation function for all errors\n return errorMessages(event);\n }\n if (errorMessages[event.code]) {\n // It's not a translation function, so it must be a map of strings or translation functions\n const customMessage = errorMessages[event.code];\n\n return typeof customMessage === 'string' ? customMessage : customMessage(event);\n }\n}\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles the player between windowed and fullscreen view.\n *\n * @category Buttons\n */\nexport class FullscreenToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-fullscreentogglebutton',\n text: i18n.getLocalizer('fullscreen'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const isFullScreenAvailable = () => {\n return player.isViewModeAvailable(player.exports.ViewMode.Fullscreen);\n };\n\n const fullscreenStateHandler = () => {\n player.getViewMode() === player.exports.ViewMode.Fullscreen ? this.on() : this.off();\n };\n\n const fullscreenAvailabilityChangedHandler = () => {\n isFullScreenAvailable() ? this.show() : this.hide();\n };\n\n player.on(player.exports.PlayerEvent.ViewModeChanged, fullscreenStateHandler);\n\n // Available only in our native SDKs for now\n if ((player.exports.PlayerEvent as any).ViewModeAvailabilityChanged) {\n player.on(\n (player.exports.PlayerEvent as any).ViewModeAvailabilityChanged,\n fullscreenAvailabilityChangedHandler,\n );\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(fullscreenAvailabilityChangedHandler);\n\n this.onClick.subscribe(() => {\n if (!isFullScreenAvailable()) {\n if (console) {\n console.log('Fullscreen unavailable');\n }\n return;\n }\n\n const targetViewMode =\n player.getViewMode() === player.exports.ViewMode.Fullscreen\n ? player.exports.ViewMode.Inline\n : player.exports.ViewMode.Fullscreen;\n\n player.setViewMode(targetViewMode);\n });\n\n // Startup init\n fullscreenAvailabilityChangedHandler();\n fullscreenStateHandler();\n }\n}\n","import {PlaybackToggleButton, PlaybackToggleButtonConfig} from './playbacktogglebutton';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI, PlayerEventBase, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that overlays the video and toggles between playback and pause.\n *\n * @category Buttons\n */\nexport class HugePlaybackToggleButton extends PlaybackToggleButton {\n\n constructor(config: PlaybackToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-hugeplaybacktogglebutton',\n text: i18n.getLocalizer('playPause'),\n role: 'button',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // Update button state through API events\n super.configure(player, uimanager, false);\n\n // Set enterFullscreenOnInitialPlayback if set in the uimanager config\n if (typeof uimanager.getConfig().enterFullscreenOnInitialPlayback === 'boolean') {\n this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;\n }\n\n let togglePlayback = () => {\n if (player.isPlaying() || this.isPlayInitiated) {\n player.pause('ui');\n } else {\n player.play('ui');\n }\n };\n\n let toggleFullscreen = () => {\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n player.setViewMode(player.exports.ViewMode.Inline);\n } else {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n };\n\n let firstPlay = true;\n let clickTime = 0;\n let doubleClickTime = 0;\n\n /*\n * YouTube-style toggle button handling\n *\n * The goal is to prevent a short pause or playback interval between a click, that toggles playback, and a\n * double click, that toggles fullscreen. In this naive approach, the first click would e.g. start playback,\n * the second click would be detected as double click and toggle to fullscreen, and as second normal click stop\n * playback, which results is a short playback interval with max length of the double click detection\n * period (usually 500ms).\n *\n * To solve this issue, we defer handling of the first click for 200ms, which is almost unnoticeable to the user,\n * and just toggle playback if no second click (double click) has been registered during this period. If a double\n * click is registered, we just toggle the fullscreen. In the first 200ms, undesired playback changes thus cannot\n * happen. If a double click is registered within 500ms, we undo the playback change and switch fullscreen mode.\n * In the end, this method basically introduces a 200ms observing interval in which playback changes are prevented\n * if a double click happens.\n */\n this.onClick.subscribe(() => {\n // Directly start playback on first click of the button.\n // This is a required workaround for mobile browsers where video playback needs to be triggered directly\n // by the user. A deferred playback start through the timeout below is not considered as user action and\n // therefore ignored by mobile browsers.\n if (firstPlay) {\n // Try to start playback. Then we wait for Play and only when it arrives, we disable the firstPlay flag.\n // If we disable the flag here, onClick was triggered programmatically instead of by a user interaction, and\n // playback is blocked (e.g. on mobile devices due to the programmatic play() call), we loose the chance to\n // ever start playback through a user interaction again with this button.\n togglePlayback();\n\n if (this.config.enterFullscreenOnInitialPlayback) {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n\n return;\n }\n\n let now = Date.now();\n\n if (now - clickTime < 200) {\n // We have a double click inside the 200ms interval, just toggle fullscreen mode\n toggleFullscreen();\n doubleClickTime = now;\n return;\n } else if (now - clickTime < 500) {\n // We have a double click inside the 500ms interval, undo playback toggle and toggle fullscreen mode\n toggleFullscreen();\n togglePlayback();\n doubleClickTime = now;\n return;\n }\n\n clickTime = now;\n\n setTimeout(() => {\n if (Date.now() - doubleClickTime > 200) {\n // No double click detected, so we toggle playback and wait what happens next\n togglePlayback();\n }\n }, 200);\n });\n\n player.on(player.exports.PlayerEvent.Play, () => {\n // Playback has really started, we can disable the flag to switch to normal toggle button handling\n firstPlay = false;\n });\n\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n // if playback could not be started, reset the first play flag as we need the user interaction to start\n firstPlay = true;\n }\n });\n\n const suppressPlayButtonTransitionAnimation = () => {\n // Disable the current animation\n this.setTransitionAnimationsEnabled(false);\n\n // Enable the transition animations for the next state change\n this.onToggle.subscribeOnce(() => {\n this.setTransitionAnimationsEnabled(true);\n });\n };\n\n // Hide the play button animation when the UI is loaded (it should only be animated on state changes)\n suppressPlayButtonTransitionAnimation();\n\n const isAutoplayEnabled = player.getConfig().playback && Boolean(player.getConfig().playback.autoplay);\n // We only know if an autoplay attempt is upcoming if the player is not yet ready. It the player is already ready,\n // the attempt might be upcoming or might have already happened, but we don't have to handle that because we can\n // simply rely on isPlaying and the play state events.\n const isAutoplayUpcoming = !player.getSource() && isAutoplayEnabled;\n\n // Hide the play button when the player is already playing or autoplay is upcoming\n if (player.isPlaying() || isAutoplayUpcoming) {\n // Hide the play button (switch to playing state)\n this.on();\n // Disable the animation of the playing state switch\n suppressPlayButtonTransitionAnimation();\n\n // Show the play button without an animation if a play attempt is blocked\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n suppressPlayButtonTransitionAnimation();\n }\n });\n }\n }\n\n protected toDomElement(): DOM {\n let buttonElement = super.toDomElement();\n\n // Add child that contains the play button image\n // Setting the image directly on the button does not work together with scaling animations, because the button\n // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined\n // to the size if the image, it can scale inside the player without overshooting.\n buttonElement.append(new DOM('div', {\n 'class': this.prefixCss('image'),\n }));\n\n return buttonElement;\n }\n\n /**\n * Enables or disables the play state transition animations of the play button image. Can be used to suppress\n * animations.\n * @param {boolean} enabled true to enable the animations (default), false to disable them\n */\n protected setTransitionAnimationsEnabled(enabled: boolean): void {\n const noTransitionAnimationsClass = this.prefixCss('no-transition-animations');\n\n if (enabled) {\n this.getDomElement().removeClass(noTransitionAnimationsClass);\n } else if (!this.getDomElement().hasClass(noTransitionAnimationsClass)) {\n this.getDomElement().addClass(noTransitionAnimationsClass);\n }\n }\n}\n","import {ButtonConfig, Button} from './button';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button to play/replay a video.\n *\n * @category Buttons\n */\nexport class HugeReplayButton extends Button<ButtonConfig> {\n\n constructor(config: ButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-hugereplaybutton',\n text: i18n.getLocalizer('replay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n player.play('ui');\n });\n }\n\n protected toDomElement(): DOM {\n let buttonElement = super.toDomElement();\n\n // Add child that contains the play button image\n // Setting the image directly on the button does not work together with scaling animations, because the button\n // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined\n // to the size if the image, it can scale inside the player without overshooting.\n buttonElement.append(new DOM('div', {\n 'class': this.prefixCss('image'),\n }));\n\n return buttonElement;\n }\n}","import {ListSelector, ListSelectorConfig} from './listselector';\nimport {DOM} from '../dom';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Components\n */\nexport class ItemSelectionList extends ListSelector<ListSelectorConfig> {\n\n private static readonly CLASS_SELECTED = 'selected';\n\n private listElement: DOM;\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n tag: 'ul',\n cssClass: 'ui-itemselectionlist',\n }, this.config);\n }\n\n protected isActive(): boolean {\n return this.items.length > 1;\n }\n\n protected toDomElement(): DOM {\n let listElement = new DOM('ul', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n }, this);\n\n this.listElement = listElement;\n this.updateDomItems();\n\n return listElement;\n }\n\n protected updateDomItems(selectedValue: string = null) {\n // Delete all children\n this.listElement.empty();\n\n let selectedListItem: DOM = null;\n\n const selectItem = (listItem: DOM) => {\n listItem.addClass(this.prefixCss(ItemSelectionList.CLASS_SELECTED));\n };\n\n const deselectItem = (listItem: DOM) => {\n listItem.removeClass(this.prefixCss(ItemSelectionList.CLASS_SELECTED));\n };\n\n for (let item of this.items) {\n let listItem = new DOM('li', {\n 'type': 'li',\n 'class': this.prefixCss('ui-selectionlistitem'),\n }).append(new DOM('a', {\n }).html(i18n.performLocalization(item.label)));\n\n if (!selectedListItem) {\n if (selectedValue == null) { // If there is no pre-selected value, select the first one\n selectedListItem = listItem;\n } else if (String(selectedValue) === item.key) { // convert selectedValue to string to catch 'null'/null case\n selectedListItem = listItem;\n }\n }\n\n // Handle list item selections\n listItem.on('click', () => {\n // Deselect the previous item (if there was a selected item)\n if (selectedListItem) {\n deselectItem(selectedListItem);\n }\n\n // Select the clicked item\n selectedListItem = listItem;\n selectItem(listItem);\n\n // Fire the event\n this.onItemSelectedEvent(item.key, false);\n });\n\n // Select default item\n if (selectedListItem) {\n selectItem(selectedListItem);\n }\n\n this.listElement.append(listItem);\n }\n }\n\n protected onItemAddedEvent(value: string) {\n super.onItemAddedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemRemovedEvent(value: string) {\n super.onItemRemovedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemSelectedEvent(value: string, updateDomItems: boolean = true) {\n super.onItemSelectedEvent(value);\n if (updateDomItems) {\n this.updateDomItems(value);\n }\n }\n}\n","import {ComponentConfig, Component} from './component';\nimport {DOM} from '../dom';\nimport {EventDispatcher, Event, NoArgs} from '../eventdispatcher';\nimport { LocalizableText, i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Label} component.\n *\n * @category Configs\n */\nexport interface LabelConfig extends ComponentConfig {\n /**\n * The text as string or localize callback on the label.\n */\n text?: LocalizableText;\n\n /**\n * WCAG20 standard: Associate label to form control.\n */\n for?: string;\n}\n\n/**\n * A simple text label.\n *\n * DOM example:\n * <code>\n * <span class='ui-label'>...some text...</span>\n * </code>\n *\n * @category Components\n */\nexport class Label<Config extends LabelConfig> extends Component<Config> {\n\n private text: LocalizableText;\n\n private labelEvents = {\n onClick: new EventDispatcher<Label<Config>, NoArgs>(),\n onTextChanged: new EventDispatcher<Label<Config>, string>(),\n };\n\n constructor(config: Config = {} as Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-label',\n } as Config, this.config);\n this.text = this.config.text;\n }\n\n protected toDomElement(): DOM {\n const tagName = this.config.for != null ? 'label' : 'span';\n\n let labelElement = new DOM(tagName, {\n 'id': this.config.id,\n 'for': this.config.for,\n 'class': this.getCssClasses(),\n }, this).html(i18n.performLocalization(this.text));\n\n labelElement.on('click', () => {\n this.onClickEvent();\n });\n\n return labelElement;\n }\n\n /**\n * Set the text on this label.\n * @param text\n */\n setText(text: LocalizableText) {\n if (text === this.text) {\n return;\n }\n\n this.text = text;\n const localizedText = i18n.performLocalization(text);\n this.getDomElement().html(localizedText);\n this.onTextChangedEvent(localizedText);\n }\n\n /**\n * Gets the text on this label.\n * @return {string} The text on the label\n */\n getText(): string {\n return i18n.performLocalization(this.text);\n }\n\n /**\n * Clears the text on this label.\n */\n clearText() {\n this.getDomElement().html('');\n this.onTextChangedEvent(null);\n }\n\n /**\n * Tests if the label is empty and does not contain any text.\n * @return {boolean} True if the label is empty, else false\n */\n isEmpty(): boolean {\n return !this.text;\n }\n\n /**\n * Fires the {@link #onClick} event.\n * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method\n * and calling the super method.\n */\n protected onClickEvent() {\n this.labelEvents.onClick.dispatch(this);\n }\n\n /**\n * Fires the {@link #onClick} event.\n * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method\n * and calling the super method.\n */\n protected onTextChangedEvent(text: string) {\n this.labelEvents.onTextChanged.dispatch(this, text);\n }\n\n /**\n * Gets the event that is fired when the label is clicked.\n * @returns {Event<Label<LabelConfig>, NoArgs>}\n */\n get onClick(): Event<Label<LabelConfig>, NoArgs> {\n return this.labelEvents.onClick.getEvent();\n }\n\n /**\n * Gets the event that is fired when the text on the label is changed.\n * @returns {Event<Label<LabelConfig>, string>}\n */\n get onTextChanged(): Event<Label<LabelConfig>, string> {\n return this.labelEvents.onTextChanged.getEvent();\n }\n}\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\nimport { ListItem, ListSelector, ListSelectorConfig } from './listselector';\nimport {DOM} from '../dom';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { ArrayUtils } from '../arrayutils';\n\n/**\n * A element to select a single item out of a list of available items.\n *\n * DOM example:\n * <code>\n * <div class='ui-listbox'>\n * <button class='ui-listbox-button'>label</button>\n * ...\n * </div\n * </code>\n *\n * @category Components\n */\n// TODO: change ListSelector to extends container in v4 to improve usage of ListBox.\n// Currently we are creating the dom element of the list box with child elements manually here.\n// But this functionality is already covered within the Container component.\nexport class ListBox extends ListSelector<ListSelectorConfig> {\n private listBoxElement: DOM;\n private components: ListBoxItemButton[] = [];\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-listbox',\n } as ListSelectorConfig, this.config);\n }\n\n public configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // Subscribe before super call to receive initial events\n this.onItemAdded.subscribe(this.addListBoxDomItem);\n this.onItemRemoved.subscribe(this.removeListBoxDomItem);\n this.onItemSelected.subscribe(this.refreshSelectedItem);\n\n super.configure(player, uimanager);\n }\n\n protected toDomElement(): DOM {\n let listBoxElement = new DOM('div', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n }, this);\n\n this.listBoxElement = listBoxElement;\n this.createListBoxDomItems();\n this.refreshSelectedItem();\n\n return listBoxElement;\n }\n\n private createListBoxDomItems() {\n // Delete all children\n this.listBoxElement.empty();\n this.components = [];\n\n // Add updated children\n for (let item of this.items) {\n this.addListBoxDomItem(this, item.key);\n }\n }\n\n private removeListBoxDomItem = (_: ListBox, key: string) => {\n const component = this.getComponentForKey(key);\n if (component) {\n component.getDomElement().remove();\n ArrayUtils.remove(this.components, component);\n }\n };\n\n private addListBoxDomItem = (_: ListBox, key: string) => {\n const component = this.getComponentForKey(key);\n const newItem = this.getItemForKey(key);\n if (component) {\n // Update existing component\n component.setText(newItem.label);\n } else {\n const listBoxItemButton = this.buildListBoxItemButton(newItem);\n\n listBoxItemButton.onClick.subscribe(() => {\n this.handleSelectionChange(listBoxItemButton);\n });\n\n this.components.push(listBoxItemButton);\n this.listBoxElement.append(listBoxItemButton.getDomElement());\n }\n };\n\n private refreshSelectedItem = () => {\n // This gets called twice because the first time is triggered when the user clicks on the ListBoxItemButton. And the\n // second call comes from the player event when the actual item is selected (Subtitle / AudioTrack in this case).\n // As this is a generic component we can't prohibit this behaviour. We need to treat this component as it acts\n // independent from PlayerEvents and on the other hand we need to react to PlayerEvents as it could be triggered\n // from outside.\n\n for (let item of this.items) {\n const component = this.getComponentForKey(item.key);\n if (component) {\n String(component.key) === String(this.selectedItem) ? component.on() : component.off();\n }\n }\n };\n\n private buildListBoxItemButton(listItem: ListItem): ListBoxItemButton {\n return new ListBoxItemButton({\n key: listItem.key,\n text: listItem.label,\n ariaLabel: listItem.ariaLabel,\n });\n }\n\n private getComponentForKey(key: string): ListBoxItemButton {\n return this.components.find((c) => key === c.key);\n }\n\n private handleSelectionChange = (sender: ListBoxItemButton) => {\n this.onItemSelectedEvent(sender.key);\n };\n}\n\ninterface ListBoxItemButtonConfig extends ToggleButtonConfig {\n /**\n * key to identify selected item. Similar to the value attribute of an select option.\n */\n key: string;\n}\n\nclass ListBoxItemButton extends ToggleButton<ListBoxItemButtonConfig> {\n\n constructor(config: ListBoxItemButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-listbox-button',\n onClass: 'selected',\n offClass: '',\n } as ListBoxItemButtonConfig, this.config);\n }\n\n get key(): string {\n return (this.config as ListBoxItemButtonConfig).key;\n }\n}\n","import {Component, ComponentConfig} from './component';\nimport {EventDispatcher, Event} from '../eventdispatcher';\nimport {ArrayUtils} from '../arrayutils';\nimport { LocalizableText, i18n } from '../localization/i18n';\n\n/**\n * A map of items (key/value -> label} for a {@link ListSelector} in a {@link ListSelectorConfig}.\n */\nexport interface ListItem {\n key: string;\n label: LocalizableText;\n sortedInsert?: boolean;\n ariaLabel?: string;\n}\n\n/**\n * Filter function that can be used to filter out list items added through {@link ListSelector.addItem}.\n *\n * This is intended to be used in conjunction with subclasses that populate themselves automatically\n * via the player API, e.g. {@link SubtitleSelectBox}.\n */\nexport interface ListItemFilter {\n /**\n * Takes a list item and decides whether it should pass or be discarded.\n * @param {ListItem} listItem the item to apply the filter to\n * @returns {boolean} true to let the item pass through the filter, false to discard the item\n */\n (listItem: ListItem): boolean;\n}\n\n/**\n * Translator function to translate labels of list items added through {@link ListSelector.addItem}.\n *\n * This is intended to be used in conjunction with subclasses that populate themselves automatically\n * via the player API, e.g. {@link SubtitleSelectBox}.\n */\nexport interface ListItemLabelTranslator {\n /**\n * Takes a list item, optionally changes the label, and returns the new label.\n * @param {ListItem} listItem the item to translate\n * @returns {string} the translated or original label\n */\n (listItem: ListItem): string;\n}\n\n/**\n * Configuration interface for a {@link ListSelector}.\n *\n * @category Configs\n */\nexport interface ListSelectorConfig extends ComponentConfig {\n items?: ListItem[];\n filter?: ListItemFilter;\n translator?: ListItemLabelTranslator;\n}\n\nexport abstract class ListSelector<Config extends ListSelectorConfig> extends Component<ListSelectorConfig> {\n\n protected items: ListItem[];\n protected selectedItem: string;\n\n private listSelectorEvents = {\n onItemAdded: new EventDispatcher<ListSelector<Config>, string>(),\n onItemRemoved: new EventDispatcher<ListSelector<Config>, string>(),\n onItemSelected: new EventDispatcher<ListSelector<Config>, string>(),\n };\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n items: [],\n cssClass: 'ui-listselector',\n }, this.config);\n\n this.items = this.config.items;\n }\n\n private getItemIndex(key: string): number {\n for (let index in this.items) {\n if (key === this.items[index].key) {\n return parseInt(index);\n }\n }\n return -1;\n }\n\n /**\n * Returns all current items of this selector.\n * * @returns {ListItem[]}\n */\n getItems(): ListItem[] {\n return this.items;\n }\n\n /**\n * Checks if the specified item is part of this selector.\n * @param key the key of the item to check\n * @returns {boolean} true if the item is part of this selector, else false\n */\n hasItem(key: string): boolean {\n return this.getItemIndex(key) > -1;\n }\n\n /**\n * Adds an item to this selector by doing a sorted insert or by appending the element to the end of the list of items.\n * If an item with the specified key already exists, it is replaced.\n * @param key the key of the item to add\n * @param label the (human-readable) label of the item to add\n * @param sortedInsert whether the item should be added respecting the order of keys\n * @param ariaLabel custom aria label for the listItem\n */\n addItem(key: string, label: LocalizableText, sortedInsert = false, ariaLabel = '') {\n const listItem = { key: key, label: i18n.performLocalization(label), ...(ariaLabel && { ariaLabel })};\n\n // Apply filter function\n if (this.config.filter && !this.config.filter(listItem)) {\n return;\n }\n\n // Apply translator function\n if (this.config.translator) {\n listItem.label = this.config.translator(listItem);\n }\n\n // Try to remove key first to get overwrite behavior and avoid duplicate keys\n this.removeItem(key); // This will trigger an ItemRemoved and an ItemAdded event\n\n // Add the item to the list\n if (sortedInsert) {\n const index = this.items.findIndex(entry => entry.key > key);\n if (index < 0) {\n this.items.push(listItem);\n } else {\n this.items.splice(index, 0, listItem);\n }\n } else {\n this.items.push(listItem);\n }\n this.onItemAddedEvent(key);\n }\n\n /**\n * Removes an item from this selector.\n * @param key the key of the item to remove\n * @returns {boolean} true if removal was successful, false if the item is not part of this selector\n */\n removeItem(key: string): boolean {\n let index = this.getItemIndex(key);\n if (index > -1) {\n ArrayUtils.remove(this.items, this.items[index]);\n this.onItemRemovedEvent(key);\n return true;\n }\n\n return false;\n }\n\n /**\n * Selects an item from the items in this selector.\n * @param key the key of the item to select\n * @returns {boolean} true is the selection was successful, false if the selected item is not part of the selector\n */\n selectItem(key: string): boolean {\n if (key === this.selectedItem) {\n // itemConfig is already selected, suppress any further action\n return true;\n }\n\n let index = this.getItemIndex(key);\n\n if (index > -1) {\n this.selectedItem = key;\n this.onItemSelectedEvent(key);\n return true;\n }\n\n return false;\n }\n\n /**\n * Returns the key of the selected item.\n * @returns {string} the key of the selected item or null if no item is selected\n */\n getSelectedItem(): string | null {\n return this.selectedItem;\n }\n\n /**\n * Returns the items for the given key or undefined if no item with the given key exists.\n * @param key the key of the item to return\n * @returns {ListItem} the item with the requested key. Undefined if no item with the given key exists.\n */\n getItemForKey(key: string): ListItem {\n return this.items.find((item) => item.key === key);\n }\n\n /**\n * Synchronize the current items of this selector with the given ones. This will remove and add items selectively.\n * For each removed item the ItemRemovedEvent and for each added item the ItemAddedEvent will be triggered. Favour\n * this method over using clearItems and adding all items again afterwards.\n * @param newItems\n */\n synchronizeItems(newItems: ListItem[]): void {\n newItems\n .filter((item) => !this.hasItem(item.key))\n .forEach((item) => this.addItem(item.key, item.label, item.sortedInsert, item.ariaLabel));\n\n this.items\n .filter((item) => newItems.filter((i) => i.key === item.key).length === 0)\n .forEach((item) => this.removeItem(item.key));\n }\n\n /**\n * Removes all items from this selector.\n */\n clearItems() {\n // local copy for iteration after clear\n let items = this.items;\n // clear items\n this.items = [];\n\n // clear the selection as the selected item is also removed\n this.selectedItem = null;\n\n // fire events\n for (let item of items) {\n this.onItemRemovedEvent(item.key);\n }\n }\n\n /**\n * Returns the number of items in this selector.\n * @returns {number}\n */\n itemCount(): number {\n return Object.keys(this.items).length;\n }\n\n protected onItemAddedEvent(key: string) {\n this.listSelectorEvents.onItemAdded.dispatch(this, key);\n }\n\n protected onItemRemovedEvent(key: string) {\n this.listSelectorEvents.onItemRemoved.dispatch(this, key);\n }\n\n protected onItemSelectedEvent(key: string) {\n this.listSelectorEvents.onItemSelected.dispatch(this, key);\n }\n\n /**\n * Gets the event that is fired when an item is added to the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemAdded(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemAdded.getEvent();\n }\n\n /**\n * Gets the event that is fired when an item is removed from the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemRemoved(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemRemoved.getEvent();\n }\n\n /**\n * Gets the event that is fired when an item is selected from the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemSelected(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemSelected.getEvent();\n }\n}","import {LabelConfig, Label} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Enumerates the types of content that the {@link MetadataLabel} can display.\n */\nexport enum MetadataLabelContent {\n /**\n * Title of the data source.\n */\n Title,\n /**\n * Description fo the data source.\n */\n Description,\n}\n\n/**\n * Configuration interface for {@link MetadataLabel}.\n *\n * @category Configs\n */\nexport interface MetadataLabelConfig extends LabelConfig {\n /**\n * The type of content that should be displayed in the label.\n */\n content: MetadataLabelContent;\n}\n\n/**\n * A label that can be configured to display certain metadata.\n *\n * @category Labels\n */\nexport class MetadataLabel extends Label<MetadataLabelConfig> {\n\n constructor(config: MetadataLabelConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['label-metadata', 'label-metadata-' + MetadataLabelContent[config.content].toLowerCase()],\n } as MetadataLabelConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let uiconfig = uimanager.getConfig();\n\n let init = () => {\n switch (config.content) {\n case MetadataLabelContent.Title:\n this.setText(uiconfig.metadata.title);\n break;\n case MetadataLabelContent.Description:\n this.setText(uiconfig.metadata.description);\n break;\n }\n };\n\n let unload = () => {\n this.setText(null);\n };\n\n // Init label\n init();\n // Clear labels when source is unloaded\n player.on(player.exports.PlayerEvent.SourceUnloaded, unload);\n\n uimanager.getConfig().events.onUpdated.subscribe(init);\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles Apple macOS picture-in-picture mode.\n *\n * @category Buttons\n */\nexport class PictureInPictureToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-piptogglebutton',\n text: i18n.getLocalizer('pictureInPicture'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const isPictureInPictureAvailable = () => {\n return player.isViewModeAvailable(player.exports.ViewMode.PictureInPicture);\n };\n\n const pictureInPictureStateHandler = () => {\n player.getViewMode() === player.exports.ViewMode.PictureInPicture ? this.on() : this.off();\n };\n\n const pictureInPictureAvailabilityChangedHandler = () => {\n isPictureInPictureAvailable() ? this.show() : this.hide();\n };\n\n player.on(player.exports.PlayerEvent.ViewModeChanged, pictureInPictureStateHandler);\n\n // Available only in our native SDKs for now\n if ((player.exports.PlayerEvent as any).ViewModeAvailabilityChanged) {\n player.on(\n (player.exports.PlayerEvent as any).ViewModeAvailabilityChanged,\n pictureInPictureAvailabilityChangedHandler,\n );\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(pictureInPictureAvailabilityChangedHandler);\n\n this.onClick.subscribe(() => {\n if (!isPictureInPictureAvailable()) {\n if (console) {\n console.log('PIP unavailable');\n }\n return;\n }\n\n const targetViewMode =\n player.getViewMode() === player.exports.ViewMode.PictureInPicture\n ? player.exports.ViewMode.Inline\n : player.exports.ViewMode.PictureInPicture;\n\n player.setViewMode(targetViewMode);\n });\n\n // Startup init\n pictureInPictureAvailabilityChangedHandler(); // Hide button if PIP not available\n pictureInPictureStateHandler();\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection of different playback speeds.\n *\n * @category Components\n */\nexport class PlaybackSpeedSelectBox extends SelectBox {\n protected defaultPlaybackSpeeds: number[];\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n this.defaultPlaybackSpeeds = [0.25, 0.5, 1, 1.5, 2];\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-playbackspeedselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addDefaultItems();\n\n this.onItemSelected.subscribe((sender: PlaybackSpeedSelectBox, value: string) => {\n player.setPlaybackSpeed(parseFloat(value));\n this.selectItem(value);\n });\n\n const setDefaultValue = (): void => {\n const playbackSpeed = player.getPlaybackSpeed();\n this.setSpeed(playbackSpeed);\n };\n\n player.on(player.exports.PlayerEvent.PlaybackSpeedChanged, setDefaultValue);\n uimanager.getConfig().events.onUpdated.subscribe(setDefaultValue);\n }\n\n setSpeed(speed: number): void {\n if (!this.selectItem(String(speed))) {\n // a playback speed was set which is not in the list, add it to the list to show it to the user\n this.clearItems();\n this.addDefaultItems([speed]);\n this.selectItem(String(speed));\n }\n }\n\n addDefaultItems(customItems: number[] = []): void {\n const sortedSpeeds = this.defaultPlaybackSpeeds.concat(customItems).sort();\n\n sortedSpeeds.forEach(element => {\n if (element !== 1) {\n this.addItem(String(element), `${element}x`);\n } else {\n this.addItem(String(element), i18n.getLocalizer('normal'));\n }\n });\n }\n\n clearItems(): void {\n this.items = [];\n this.selectedItem = null;\n }\n}","import {LabelConfig, Label} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\nimport {PlayerUtils} from '../playerutils';\nimport {StringUtils} from '../stringutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\nexport enum PlaybackTimeLabelMode {\n /**\n * Displays the current time\n */\n CurrentTime,\n /**\n * Displays the duration of the content\n */\n TotalTime,\n /**\n * Displays the current time and the duration of the content\n * Format: ${currentTime} / ${totalTime}\n */\n CurrentAndTotalTime,\n /**\n * Displays the remaining time of the content\n */\n RemainingTime,\n}\n\n/**\n * @category Configs\n */\nexport interface PlaybackTimeLabelConfig extends LabelConfig {\n /**\n * The type of which time should be displayed in the label.\n * Default: PlaybackTimeLabelMode.CurrentAndTotalTime\n */\n timeLabelMode?: PlaybackTimeLabelMode;\n /**\n * Boolean if the label should be hidden in live playback\n */\n hideInLivePlayback?: boolean;\n}\n\n/**\n * A label that display the current playback time and the total time through {@link PlaybackTimeLabel#setTime setTime}\n * or any string through {@link PlaybackTimeLabel#setText setText}.\n *\n * @category Labels\n */\nexport class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {\n\n private timeFormat: string;\n\n constructor(config: PlaybackTimeLabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <PlaybackTimeLabelConfig>{\n cssClass: 'ui-playbacktimelabel',\n timeLabelMode: PlaybackTimeLabelMode.CurrentAndTotalTime,\n hideInLivePlayback: false,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let live = false;\n let liveCssClass = this.prefixCss('ui-playbacktimelabel-live');\n let liveEdgeCssClass = this.prefixCss('ui-playbacktimelabel-live-edge');\n let minWidth = 0;\n\n let liveClickHandler = () => {\n player.timeShift(0);\n };\n\n let updateLiveState = () => {\n // Player is playing a live stream when the duration is infinite\n live = player.isLive();\n\n // Attach/detach live marker class\n if (live) {\n this.getDomElement().addClass(liveCssClass);\n this.setText(i18n.getLocalizer('live'));\n if (config.hideInLivePlayback) {\n this.hide();\n }\n this.onClick.subscribe(liveClickHandler);\n updateLiveTimeshiftState();\n } else {\n this.getDomElement().removeClass(liveCssClass);\n this.getDomElement().removeClass(liveEdgeCssClass);\n this.show();\n this.onClick.unsubscribe(liveClickHandler);\n }\n };\n\n let updateLiveTimeshiftState = () => {\n if (!live) {\n return;\n }\n\n // The player is only at the live edge iff the stream is not shifted and it is actually playing or playback has\n // never been started (meaning it isn't paused). A player that is paused is always behind the live edge.\n // An exception is made for live streams without a timeshift window, because here we \"stop\" playback instead\n // of pausing it (from a UI perspective), so we keep the live edge indicator on because a play would always\n // resume at the live edge.\n const isTimeshifted = player.getTimeShift() < 0;\n const isTimeshiftAvailable = player.getMaxTimeShift() < 0;\n if (!isTimeshifted && (!player.isPaused() || !isTimeshiftAvailable)) {\n this.getDomElement().addClass(liveEdgeCssClass);\n } else {\n this.getDomElement().removeClass(liveEdgeCssClass);\n }\n };\n\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n live = args.live;\n updateLiveState();\n });\n liveStreamDetector.detect(); // Initial detection\n\n let playbackTimeHandler = () => {\n if (!live && player.getDuration() !== Infinity) {\n this.setTime(\n PlayerUtils.getCurrentTimeRelativeToSeekableRange(player),\n player.getDuration());\n }\n\n // To avoid 'jumping' in the UI by varying label sizes due to non-monospaced fonts,\n // we gradually increase the min-width with the content to reach a stable size.\n let width = this.getDomElement().width();\n if (width > minWidth) {\n minWidth = width;\n this.getDomElement().css({\n 'min-width': minWidth + 'px',\n });\n }\n };\n\n let updateTimeFormatBasedOnDuration = () => {\n // Set time format depending on source duration\n this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ?\n StringUtils.FORMAT_HHMMSS : StringUtils.FORMAT_MMSS;\n playbackTimeHandler();\n };\n\n player.on(player.exports.PlayerEvent.TimeChanged, playbackTimeHandler);\n player.on(player.exports.PlayerEvent.Ready, updateTimeFormatBasedOnDuration);\n player.on(player.exports.PlayerEvent.Seeked, playbackTimeHandler);\n\n player.on(player.exports.PlayerEvent.TimeShift, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.TimeShifted, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.Playing, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.Paused, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.StallStarted, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.StallEnded, updateLiveTimeshiftState);\n\n let init = () => {\n // Reset min-width when a new source is ready (especially for switching VOD/Live modes where the label content\n // changes)\n minWidth = 0;\n this.getDomElement().css({\n 'min-width': null,\n });\n\n updateTimeFormatBasedOnDuration();\n };\n uimanager.getConfig().events.onUpdated.subscribe(init);\n\n init();\n }\n\n /**\n * Sets the current playback time and total duration.\n * @param playbackSeconds the current playback time in seconds\n * @param durationSeconds the total duration in seconds\n */\n setTime(playbackSeconds: number, durationSeconds: number) {\n let currentTime = StringUtils.secondsToTime(playbackSeconds, this.timeFormat);\n let totalTime = StringUtils.secondsToTime(durationSeconds, this.timeFormat);\n\n switch ((<PlaybackTimeLabelConfig>this.config).timeLabelMode) {\n case PlaybackTimeLabelMode.CurrentTime:\n this.setText(`${currentTime}`);\n break;\n case PlaybackTimeLabelMode.TotalTime:\n this.setText(`${totalTime}`);\n break;\n case PlaybackTimeLabelMode.CurrentAndTotalTime:\n this.setText(`${currentTime} / ${totalTime}`);\n break;\n case PlaybackTimeLabelMode.RemainingTime:\n let remainingTime = StringUtils.secondsToTime(durationSeconds - playbackSeconds, this.timeFormat);\n this.setText(`${remainingTime}`);\n break;\n }\n }\n\n /**\n * Sets the current time format\n * @param timeFormat the time format\n */\n protected setTimeFormat(timeFormat: string): void {\n this.timeFormat = timeFormat;\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport {PlayerUtils} from '../playerutils';\nimport { PlayerAPI, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface PlaybackToggleButtonConfig extends ToggleButtonConfig {\n /**\n * Specify whether the player should be set to enter fullscreen by clicking on the playback toggle button\n * when initiating the initial playback.\n * Default is false.\n */\n enterFullscreenOnInitialPlayback?: boolean;\n}\n\n/**\n * A button that toggles between playback and pause.\n *\n * @category Buttons\n */\nexport class PlaybackToggleButton extends ToggleButton<PlaybackToggleButtonConfig> {\n\n private static readonly CLASS_STOPTOGGLE = 'stoptoggle';\n protected isPlayInitiated: boolean;\n\n constructor(config: PlaybackToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-playbacktogglebutton',\n text: i18n.getLocalizer('play'),\n onAriaLabel: i18n.getLocalizer('pause'),\n offAriaLabel: i18n.getLocalizer('play'),\n }, this.config);\n\n this.isPlayInitiated = false;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager, handleClickEvent: boolean = true): void {\n super.configure(player, uimanager);\n\n // Set enterFullscreenOnInitialPlayback if set in the uimanager config\n if (typeof uimanager.getConfig().enterFullscreenOnInitialPlayback === 'boolean') {\n this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;\n }\n\n let isSeeking = false;\n let firstPlay = true;\n\n // Handler to update button state based on player state\n let playbackStateHandler = () => {\n // If the UI is currently seeking, playback is temporarily stopped but the buttons should\n // not reflect that and stay as-is (e.g indicate playback while seeking).\n if (isSeeking) {\n return;\n }\n\n if (player.isPlaying() || this.isPlayInitiated) {\n this.on();\n } else {\n this.off();\n }\n };\n\n // Call handler upon these events\n player.on(player.exports.PlayerEvent.Play, (e) => {\n this.isPlayInitiated = true;\n firstPlay = false;\n playbackStateHandler();\n });\n\n player.on(player.exports.PlayerEvent.Paused, (e) => {\n this.isPlayInitiated = false;\n playbackStateHandler();\n });\n\n player.on(player.exports.PlayerEvent.Playing, (e) => {\n this.isPlayInitiated = false;\n playbackStateHandler();\n });\n // after unloading + loading a new source, the player might be in a different playing state (from playing into stopped)\n player.on(player.exports.PlayerEvent.SourceLoaded, playbackStateHandler);\n uimanager.getConfig().events.onUpdated.subscribe(playbackStateHandler);\n player.on(player.exports.PlayerEvent.SourceUnloaded, playbackStateHandler);\n // when playback finishes, player turns to paused mode\n player.on(player.exports.PlayerEvent.PlaybackFinished, playbackStateHandler);\n player.on(player.exports.PlayerEvent.CastStarted, playbackStateHandler);\n\n // When a playback attempt is rejected with warning 5008, we switch the button state back to off\n // This is required for blocked autoplay, because there is no Paused event in such case\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n this.isPlayInitiated = false;\n firstPlay = true;\n this.off();\n }\n });\n\n const updateLiveState = () => {\n const showStopToggle = player.isLive() && !PlayerUtils.isTimeShiftAvailable(player);\n\n if (showStopToggle) {\n this.getDomElement().addClass(this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE));\n } else {\n this.getDomElement().removeClass(this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE));\n }\n };\n\n // Detect absence of timeshifting on live streams and add tagging class to convert button icons to play/stop\n let timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(() => updateLiveState());\n liveStreamDetector.onLiveChanged.subscribe(() => updateLiveState());\n\n timeShiftDetector.detect(); // Initial detection\n liveStreamDetector.detect();\n\n if (handleClickEvent) {\n // Control player by button events\n // When a button event triggers a player API call, events are fired which in turn call the event handler\n // above that updated the button state.\n this.onClick.subscribe(() => {\n if (player.isPlaying() || this.isPlayInitiated) {\n player.pause('ui');\n } else {\n player.play('ui');\n\n if (firstPlay && this.config.enterFullscreenOnInitialPlayback) {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n }\n });\n }\n\n // Track UI seeking status\n uimanager.onSeek.subscribe(() => {\n isSeeking = true;\n });\n uimanager.onSeeked.subscribe(() => {\n isSeeking = false;\n });\n\n // Startup init\n playbackStateHandler();\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {HugePlaybackToggleButton} from './hugeplaybacktogglebutton';\n\n/**\n * @category Configs\n */\nexport interface PlaybackToggleOverlayConfig extends ContainerConfig {\n /**\n * Specify whether the player should be set to enter fullscreen by clicking on the playback toggle button\n * when initiating the initial playback.\n * Default is false.\n */\n enterFullscreenOnInitialPlayback?: boolean;\n}\n\n/**\n * Overlays the player and displays error messages.\n *\n * @category Components\n */\nexport class PlaybackToggleOverlay extends Container<PlaybackToggleOverlayConfig> {\n\n private playbackToggleButton: HugePlaybackToggleButton;\n\n constructor(config: PlaybackToggleOverlayConfig = {}) {\n super(config);\n\n this.playbackToggleButton = new HugePlaybackToggleButton({\n enterFullscreenOnInitialPlayback: Boolean(config.enterFullscreenOnInitialPlayback),\n });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-playbacktoggle-overlay',\n components: [this.playbackToggleButton],\n }, this.config);\n }\n}","import { Button, ButtonConfig } from './button';\nimport { i18n } from '../localization/i18n';\nimport { PlayerAPI, SeekEvent, TimeShiftEvent } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerUtils } from '../playerutils';\n\n/**\n * @category Configs\n */\nexport interface QuickSeekButtonConfig extends ButtonConfig {\n /**\n * Specify how many seconds the player should seek forward/backwards in the stream.\n * Negative values mean a backwards seek, positive values mean a forward seek.\n * Default is -10.\n */\n seekSeconds?: number;\n}\n\n/**\n * @category Buttons\n */\nexport class QuickSeekButton extends Button<QuickSeekButtonConfig> {\n private currentSeekTarget: number | null;\n private player: PlayerAPI;\n\n constructor(config: QuickSeekButtonConfig = {}) {\n super(config);\n this.currentSeekTarget = null;\n\n this.config = this.mergeConfig(\n config,\n {\n seekSeconds: -10,\n cssClass: 'ui-quickseekbutton',\n },\n this.config,\n );\n\n const seekDirection = this.config.seekSeconds < 0 ? 'rewind' : 'forward';\n\n this.config.text = this.config.text || i18n.getLocalizer(`quickseek.${seekDirection}`);\n this.config.ariaLabel = this.config.ariaLabel || i18n.getLocalizer(`quickseek.${seekDirection}`);\n\n this.getDomElement().data(this.prefixCss('seek-direction'), seekDirection);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n this.player = player;\n\n let isLive: boolean;\n let hasTimeShift: boolean;\n\n const switchVisibility = (isLive: boolean, hasTimeShift: boolean) => {\n if (isLive && !hasTimeShift) {\n this.hide();\n } else {\n this.show();\n }\n };\n\n const timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(\n (sender, args: PlayerUtils.TimeShiftAvailabilityChangedArgs) => {\n hasTimeShift = args.timeShiftAvailable;\n switchVisibility(isLive, hasTimeShift);\n },\n );\n\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: PlayerUtils.LiveStreamDetectorEventArgs) => {\n isLive = args.live;\n switchVisibility(isLive, hasTimeShift);\n });\n\n // Initial detection\n timeShiftDetector.detect();\n liveStreamDetector.detect();\n\n this.onClick.subscribe(() => {\n if (isLive && !hasTimeShift) {\n // If no DVR window is available, the button should be hidden anyway, so this is to be absolutely sure\n return;\n }\n\n if (isLive && this.config.seekSeconds > 0 && player.getTimeShift() === 0) {\n // Don't do anything if the player is already on the live edge\n return;\n }\n\n const currentPosition =\n this.currentSeekTarget !== null\n ? this.currentSeekTarget\n : isLive\n ? player.getTimeShift()\n : player.getCurrentTime();\n\n const newSeekTime = currentPosition + this.config.seekSeconds;\n\n if (isLive) {\n const clampedValue = PlayerUtils.clampValueToRange(newSeekTime, player.getMaxTimeShift(), 0);\n player.timeShift(clampedValue);\n } else {\n const clampedValue = PlayerUtils.clampValueToRange(newSeekTime, 0, player.getDuration());\n player.seek(clampedValue);\n }\n });\n\n this.player.on(this.player.exports.PlayerEvent.Seek, this.onSeek);\n this.player.on(this.player.exports.PlayerEvent.Seeked, this.onSeekedOrTimeShifted);\n this.player.on(this.player.exports.PlayerEvent.TimeShift, this.onTimeShift);\n this.player.on(this.player.exports.PlayerEvent.TimeShifted, this.onSeekedOrTimeShifted);\n }\n\n private onSeek = (event: SeekEvent): void => {\n this.currentSeekTarget = event.seekTarget;\n };\n\n private onSeekedOrTimeShifted = () => {\n this.currentSeekTarget = null;\n };\n\n private onTimeShift = (event: TimeShiftEvent): void => {\n this.currentSeekTarget = this.player.getTimeShift() + (event.target - event.position);\n }\n\n release(): void {\n this.player.off(this.player.exports.PlayerEvent.Seek, this.onSeek);\n this.player.off(this.player.exports.PlayerEvent.Seeked, this.onSeekedOrTimeShifted);\n this.player.off(this.player.exports.PlayerEvent.TimeShift, this.onTimeShift);\n this.player.off(this.player.exports.PlayerEvent.TimeShifted, this.onSeekedOrTimeShifted);\n this.currentSeekTarget = null;\n this.player = null;\n }\n}\n","import {ContainerConfig, Container} from './container';\nimport {Component, ComponentConfig} from './component';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport {HugeReplayButton} from './hugereplaybutton';\nimport { UIRecommendationConfig } from '../uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Overlays the player and displays recommended videos.\n *\n * @category Containers\n */\nexport class RecommendationOverlay extends Container<ContainerConfig> {\n\n private replayButton: HugeReplayButton;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.replayButton = new HugeReplayButton();\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-recommendation-overlay',\n hidden: true,\n components: [this.replayButton],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let clearRecommendations = () => {\n for (let component of this.getComponents().slice()) {\n if (component instanceof RecommendationItem) {\n this.removeComponent(component);\n }\n }\n this.updateComponents();\n this.getDomElement().removeClass(this.prefixCss('recommendations'));\n };\n\n let setupRecommendations = () => {\n clearRecommendations();\n\n const recommendations = uimanager.getConfig().recommendations;\n\n if (recommendations.length > 0) {\n let index = 1;\n for (let item of recommendations) {\n this.addComponent(new RecommendationItem({\n itemConfig: item,\n cssClasses: ['recommendation-item-' + (index++)],\n }));\n }\n this.updateComponents(); // create container DOM elements\n\n this.getDomElement().addClass(this.prefixCss('recommendations'));\n }\n };\n\n uimanager.getConfig().events.onUpdated.subscribe(setupRecommendations);\n // Remove recommendations and hide overlay when source is unloaded\n player.on(player.exports.PlayerEvent.SourceUnloaded, () => {\n clearRecommendations();\n this.hide();\n });\n // Display recommendations when playback has finished\n player.on(player.exports.PlayerEvent.PlaybackFinished, () => {\n this.show();\n });\n // Hide recommendations when playback starts, e.g. a restart\n player.on(player.exports.PlayerEvent.Play, () => {\n this.hide();\n });\n\n // Init on startup\n setupRecommendations();\n }\n}\n\n/**\n * Configuration interface for the {@link RecommendationItem}\n */\ninterface RecommendationItemConfig extends ComponentConfig {\n itemConfig: UIRecommendationConfig;\n}\n\n/**\n * An item of the {@link RecommendationOverlay}. Used only internally in {@link RecommendationOverlay}.\n */\nclass RecommendationItem extends Component<RecommendationItemConfig> {\n\n constructor(config: RecommendationItemConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-recommendation-item',\n itemConfig: null, // this must be passed in from outside\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n let config = this.config.itemConfig;\n\n let itemElement = new DOM('a', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'href': config.url,\n }, this).css({ 'background-image': `url(${config.thumbnail})` });\n\n let bgElement = new DOM('div', {\n 'class': this.prefixCss('background'),\n });\n itemElement.append(bgElement);\n\n let titleElement = new DOM('span', {\n 'class': this.prefixCss('title'),\n }).append(new DOM('span', {\n 'class': this.prefixCss('innertitle'),\n }).html(config.title));\n itemElement.append(titleElement);\n\n let timeElement = new DOM('span', {\n 'class': this.prefixCss('duration'),\n }).append(new DOM('span', {\n 'class': this.prefixCss('innerduration'),\n }).html(config.duration ? StringUtils.secondsToTime(config.duration) : ''));\n itemElement.append(timeElement);\n\n return itemElement;\n }\n}","import { ButtonConfig, Button } from './button';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { PlayerUtils } from '../playerutils';\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\n\n/**\n * A button to play/replay a video.\n *\n * @category Buttons\n */\nexport class ReplayButton extends Button<ButtonConfig> {\n\n constructor(config: ButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-replaybutton',\n text: i18n.getLocalizer('replay'),\n ariaLabel: i18n.getLocalizer('replay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n if (player.isLive()) {\n this.hide();\n }\n\n const liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n if (args.live) {\n this.hide();\n } else {\n this.show();\n }\n });\n\n this.onClick.subscribe(() => {\n if (!player.hasEnded()) {\n player.seek(0);\n // Not calling `play` will keep the play/pause state as is\n } else {\n // If playback has already ended, calling `play` will automatically restart from the beginning\n player.play('ui');\n }\n });\n }\n}\n","import { ExtendedPlayerAPI, GroupPlaybackSuspension, GroupPlaybackSuspensionReason } from './../groupplaybackapi';\nimport { Component, ComponentConfig } from './component';\nimport { DOM } from '../dom';\nimport { Event, EventDispatcher, NoArgs } from '../eventdispatcher';\nimport { SeekBarLabel } from './seekbarlabel';\nimport { UIInstanceManager, SeekPreviewArgs } from '../uimanager';\nimport { Timeout } from '../timeout';\nimport { PlayerUtils } from '../playerutils';\nimport TimeShiftAvailabilityChangedArgs = PlayerUtils.TimeShiftAvailabilityChangedArgs;\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\nimport { TimelineMarker } from '../uiconfig';\nimport { PlayerAPI, PlayerEventBase } from 'bitmovin-player';\nimport { StringUtils } from '../stringutils';\nimport { SeekBarType, SeekBarController } from './seekbarcontroller';\nimport { i18n } from '../localization/i18n';\nimport { BrowserUtils } from '../browserutils';\nimport { TimelineMarkersHandler } from './timelinemarkershandler';\nimport { getMinBufferLevel } from './seekbarbufferlevel';\n\n/**\n * Configuration interface for the {@link SeekBar} component.\n *\n * @category Configs\n */\nexport interface SeekBarConfig extends ComponentConfig {\n /**\n * The label above the seek position.\n */\n label?: SeekBarLabel;\n /**\n * Bar will be vertical instead of horizontal if set to true.\n */\n vertical?: boolean;\n /**\n * The interval in milliseconds in which the playback position on the seek bar will be updated. The shorter the\n * interval, the smoother it looks and the more resource intense it is. The update interval will be kept as steady\n * as possible to avoid jitter.\n * Set to -1 to disable smooth updating and update it on player TimeChanged events instead.\n * Default: 50 (50ms = 20fps).\n */\n smoothPlaybackPositionUpdateIntervalMs?: number;\n\n /**\n * Used for seekBar control increments and decrements\n */\n keyStepIncrements?: { leftRight: number, upDown: number };\n\n /**\n * Used to enable/disable snapping to markers on the seek bar when seeking near them.\n * Default: true\n */\n snappingEnabled?: boolean;\n\n /**\n * Defines tolerance for snapping to markers, if snapping to seek bar markers is enabled.\n */\n snappingRange?: number;\n\n /**\n * Used to enable/disable seek preview\n */\n enableSeekPreview?: boolean;\n}\n\n/**\n * Event argument interface for a seek preview event.\n */\nexport interface SeekPreviewEventArgs extends SeekPreviewArgs {\n /**\n * Tells if the seek preview event comes from a scrubbing.\n */\n scrubbing: boolean;\n}\n\n/**\n * @category Components\n */\nexport interface SeekBarMarker {\n marker: TimelineMarker;\n position: number;\n duration?: number;\n element?: DOM;\n}\n\n/**\n * A seek bar to seek within the player's media. It displays the current playback position, amount of buffed data, seek\n * target, and keeps status about an ongoing seek.\n *\n * The seek bar displays different 'bars':\n * - the playback position, i.e. the position in the media at which the player current playback pointer is positioned\n * - the buffer position, which usually is the playback position plus the time span that is already buffered ahead\n * - the seek position, used to preview to where in the timeline a seek will jump to\n *\n * @category Components\n */\nexport class SeekBar extends Component<SeekBarConfig> {\n\n public static readonly SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED = -1;\n\n /**\n * The CSS class that is added to the DOM element while the seek bar is in 'seeking' state.\n */\n private static readonly CLASS_SEEKING = 'seeking';\n\n private seekBar: DOM;\n private seekBarPlaybackPosition: DOM;\n private seekBarPlaybackPositionMarker: DOM;\n private seekBarBufferPosition: DOM;\n private seekBarSeekPosition: DOM;\n private seekBarBackdrop: DOM;\n\n private label: SeekBarLabel;\n\n private seekBarMarkersContainer: DOM;\n private timelineMarkersHandler: TimelineMarkersHandler;\n\n private uiBoundingRect: DOMRect;\n\n private player: PlayerAPI;\n private uiManager: UIInstanceManager;\n\n protected seekBarType: SeekBarType;\n\n protected isUiShown: boolean;\n\n /**\n * Buffer of the the current playback position. The position must be buffered in case the element\n * needs to be refreshed with {@link #refreshPlaybackPosition}.\n * @type {number}\n */\n private playbackPositionPercentage = 0;\n\n private smoothPlaybackPositionUpdater: Timeout;\n private pausedTimeshiftUpdater: Timeout;\n\n private isUserSeeking = false;\n\n private seekBarEvents = {\n /**\n * Fired when a scrubbing seek operation is started.\n */\n onSeek: new EventDispatcher<SeekBar, NoArgs>(),\n /**\n * Fired during a scrubbing seek to indicate that the seek preview (i.e. the video frame) should be updated.\n */\n onSeekPreview: new EventDispatcher<SeekBar, SeekPreviewEventArgs>(),\n /**\n * Fired when a scrubbing seek has finished or when a direct seek is issued.\n */\n onSeeked: new EventDispatcher<SeekBar, number>(),\n };\n\n constructor(config: SeekBarConfig = {}) {\n super(config);\n\n const keyStepIncrements = this.config.keyStepIncrements || {\n leftRight: 1,\n upDown: 5,\n };\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-seekbar',\n vertical: false,\n smoothPlaybackPositionUpdateIntervalMs: 50,\n keyStepIncrements,\n ariaLabel: i18n.getLocalizer('seekBar'),\n tabIndex: 0,\n snappingRange: 1,\n enableSeekPreview: true,\n snappingEnabled: true,\n }, this.config);\n\n this.label = this.config.label;\n }\n\n initialize(): void {\n super.initialize();\n\n if (this.hasLabel()) {\n this.getLabel().initialize();\n }\n }\n\n protected setAriaSliderMinMax(min: string, max: string) {\n this.getDomElement().attr('aria-valuemin', min);\n this.getDomElement().attr('aria-valuemax', max);\n }\n\n private setAriaSliderValues() {\n if (this.seekBarType === SeekBarType.Live) {\n const timeshiftValue = Math.ceil(this.player.getTimeShift()).toString();\n this.getDomElement().attr('aria-valuenow', timeshiftValue);\n this.getDomElement().attr('aria-valuetext', `${i18n.performLocalization(i18n.getLocalizer('seekBar.timeshift'))} ${i18n.performLocalization(i18n.getLocalizer('seekBar.value'))}: ${timeshiftValue}`);\n } else if (this.seekBarType === SeekBarType.Vod) {\n const ariaValueText = `${StringUtils.secondsToText(this.player.getCurrentTime())} ${i18n.performLocalization(i18n.getLocalizer('seekBar.durationText'))} ${StringUtils.secondsToText(this.player.getDuration())}`;\n this.getDomElement().attr('aria-valuenow', Math.floor(this.player.getCurrentTime()).toString());\n this.getDomElement().attr('aria-valuetext', ariaValueText);\n }\n }\n\n private getPlaybackPositionPercentage(): number {\n if (this.player.isLive()) {\n return 100 - (100 / this.player.getMaxTimeShift() * this.player.getTimeShift());\n }\n\n return 100 / this.player.getDuration() * this.getRelativeCurrentTime();\n }\n\n private updateBufferLevel(playbackPositionPercentage: number): void {\n\n let bufferLoadedPercentageLevel: number;\n if (this.player.isLive()) {\n // Always show full buffer for live streams\n bufferLoadedPercentageLevel = 100;\n } else {\n bufferLoadedPercentageLevel = playbackPositionPercentage + getMinBufferLevel(this.player);\n }\n\n this.setBufferPosition(bufferLoadedPercentageLevel);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager, configureSeek: boolean = true): void {\n super.configure(player, uimanager);\n\n this.player = player;\n this.uiManager = uimanager;\n\n // Apply scaling transform to the backdrop bar to have all bars rendered similarly\n // (the call must be up here to be executed for the volume slider as well)\n this.setPosition(this.seekBarBackdrop, 100);\n\n // Add seekbar controls to the seekbar\n const seekBarController = new SeekBarController(this.config.keyStepIncrements, player, uimanager.getConfig().volumeController);\n\n seekBarController.setSeekBarControls(this.getDomElement(), () => this.seekBarType);\n\n // The configureSeek flag can be used by subclasses to disable configuration as seek bar. E.g. the volume\n // slider is reusing this component but adds its own functionality, and does not need the seek functionality.\n // This is actually a hack, the proper solution would be for both seek bar and volume sliders to extend\n // a common base slider component and implement their functionality there.\n if (!configureSeek) {\n this.seekBarType = SeekBarType.Volume;\n\n return;\n }\n\n uimanager.onControlsShow.subscribe(() => {\n this.isUiShown = true;\n if (!player.isLive() && !this.smoothPlaybackPositionUpdater.isActive()) {\n playbackPositionHandler(null, true);\n this.smoothPlaybackPositionUpdater.start();\n }\n });\n\n uimanager.onControlsHide.subscribe(() => {\n this.isUiShown = false;\n if (this.smoothPlaybackPositionUpdater.isActive()) {\n this.smoothPlaybackPositionUpdater.clear();\n }\n });\n\n let isPlaying = false;\n let scrubbing = false;\n let isPlayerSeeking = false;\n let suspension: GroupPlaybackSuspension | undefined;\n\n // Update playback and buffer positions\n let playbackPositionHandler = (event: PlayerEventBase = null, forceUpdate: boolean = false) => {\n if (this.isUserSeeking) {\n // We caught a seek preview seek, do not update the seekbar\n return;\n }\n\n let playbackPositionPercentage = this.getPlaybackPositionPercentage();\n\n this.updateBufferLevel(playbackPositionPercentage);\n\n // The segment request finished is used to help the playback position move, when the smooth playback position is not enabled.\n // At the same time when the user is scrubbing, we also move the position of the seekbar to display a preview during scrubbing.\n // When the user is scrubbing we do not record this as a user seek operation, as the user has yet to finish their seek,\n // but we should not move the playback position to not create a jumping behaviour.\n if (scrubbing && event && event.type === player.exports.PlayerEvent.SegmentRequestFinished && playbackPositionPercentage !== this.playbackPositionPercentage) {\n playbackPositionPercentage = this.playbackPositionPercentage;\n }\n\n if (player.isLive()) {\n if (player.getMaxTimeShift() === 0) {\n // This case must be explicitly handled to avoid division by zero\n this.setPlaybackPosition(100);\n } else {\n if (!this.isSeeking()) {\n this.setPlaybackPosition(playbackPositionPercentage);\n }\n\n this.setAriaSliderMinMax(player.getMaxTimeShift().toString(), '0');\n }\n } else {\n // Update playback position only in paused state or in the initial startup state where player is neither\n // paused nor playing. Playback updates are handled in the Timeout below.\n const isInInitialStartupState = this.config.smoothPlaybackPositionUpdateIntervalMs === SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED\n || forceUpdate || player.isPaused();\n const isNeitherPausedNorPlaying = player.isPaused() === player.isPlaying();\n\n if ((isInInitialStartupState || isNeitherPausedNorPlaying) && !this.isSeeking()) {\n this.setPlaybackPosition(playbackPositionPercentage);\n }\n\n this.setAriaSliderMinMax('0', player.getDuration().toString());\n }\n\n if (this.isUiShown) {\n this.setAriaSliderValues();\n }\n };\n\n // Update seekbar upon these events\n // init playback position when the player is ready\n player.on(player.exports.PlayerEvent.Ready, playbackPositionHandler);\n // update playback position when it changes\n player.on(player.exports.PlayerEvent.TimeChanged, playbackPositionHandler);\n // update bufferlevel when buffering is complete\n player.on(player.exports.PlayerEvent.StallEnded, playbackPositionHandler);\n // update playback position when a timeshift has finished\n player.on(player.exports.PlayerEvent.TimeShifted, playbackPositionHandler);\n // update bufferlevel when a segment has been downloaded\n player.on(player.exports.PlayerEvent.SegmentRequestFinished, playbackPositionHandler);\n\n this.configureLivePausedTimeshiftUpdater(player, uimanager, playbackPositionHandler);\n\n // Seek handling\n let onPlayerSeek = () => {\n isPlayerSeeking = true;\n this.setSeeking(true);\n scrubbing = false;\n };\n\n let onPlayerSeeked = (event: PlayerEventBase = null) => {\n isPlayerSeeking = false;\n this.setSeeking(false);\n\n // update playback position when a seek has finished\n playbackPositionHandler(event, true);\n };\n\n let restorePlayingState = function () {\n // Continue playback after seek if player was playing when seek started\n if (isPlaying) {\n // use the same issuer here as in the pause on seek\n player.play('ui-seek');\n }\n };\n\n player.on(player.exports.PlayerEvent.Seek, onPlayerSeek);\n player.on(player.exports.PlayerEvent.Seeked, onPlayerSeeked);\n player.on(player.exports.PlayerEvent.TimeShift, onPlayerSeek);\n player.on(player.exports.PlayerEvent.TimeShifted, onPlayerSeeked);\n\n let isGroupPlaybackAPIAvailable = (player: PlayerAPI): player is ExtendedPlayerAPI => {\n return !!(player as ExtendedPlayerAPI).groupPlayback;\n };\n\n this.onSeek.subscribe((sender) => {\n // track seeking status so we can catch events from seek preview seeks\n this.isUserSeeking = true;\n // Notify UI manager of started seek\n uimanager.onSeek.dispatch(sender);\n\n if (isGroupPlaybackAPIAvailable(player) && player.groupPlayback.hasJoined() && !suspension) {\n suspension = player.groupPlayback.beginSuspension(GroupPlaybackSuspensionReason.UserIsScrubbing);\n }\n\n // Save current playback state before performing the seek\n if (!isPlayerSeeking) {\n isPlaying = player.isPlaying();\n\n // Pause playback while seeking\n if (isPlaying) {\n // use a different issuer here, as play/pause on seek is not \"really\" triggerd by the user\n player.pause('ui-seek');\n }\n }\n });\n\n this.onSeekPreview.subscribe((sender: SeekBar, args: SeekPreviewEventArgs) => {\n // Notify UI manager of seek preview\n uimanager.onSeekPreview.dispatch(sender, args);\n scrubbing = args.scrubbing;\n });\n\n // Set enableSeekPreview if set in the uimanager config\n if (typeof uimanager.getConfig().enableSeekPreview === 'boolean') {\n this.config.enableSeekPreview = uimanager.getConfig().enableSeekPreview;\n }\n\n // Rate-limited scrubbing seek\n if (this.config.enableSeekPreview) {\n this.onSeekPreview.subscribeRateLimited(this.seekWhileScrubbing, 200);\n }\n\n this.onSeeked.subscribe((sender, percentage) => {\n this.isUserSeeking = false;\n\n // Do the seek\n this.seek(percentage);\n\n // Notify UI manager of finished seek\n uimanager.onSeeked.dispatch(sender);\n\n // Continue playback after seek if player was playing when seek started\n restorePlayingState();\n\n if (isGroupPlaybackAPIAvailable(player) && player.groupPlayback.hasJoined() && suspension) {\n const proposedPlaybackTime = this.getTargetSeekPosition(percentage);\n player.groupPlayback.endSuspension(suspension, { proposedPlaybackTime });\n suspension = undefined;\n }\n });\n\n if (this.hasLabel()) {\n // Configure a seekbar label that is internal to the seekbar)\n this.getLabel().configure(player, uimanager);\n }\n\n // Hide seekbar for live sources without timeshift\n let isLive = false;\n let hasTimeShift = false;\n let switchVisibility = (isLive: boolean, hasTimeShift: boolean) => {\n if (isLive && !hasTimeShift) {\n this.hide();\n } else {\n this.show();\n }\n playbackPositionHandler(null, true);\n this.refreshPlaybackPosition();\n };\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n isLive = args.live;\n if (isLive && this.smoothPlaybackPositionUpdater != null) {\n this.smoothPlaybackPositionUpdater.clear();\n this.seekBarType = SeekBarType.Live;\n } else {\n this.seekBarType = SeekBarType.Vod;\n }\n switchVisibility(isLive, hasTimeShift);\n });\n let timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe((sender, args: TimeShiftAvailabilityChangedArgs) => {\n hasTimeShift = args.timeShiftAvailable;\n switchVisibility(isLive, hasTimeShift);\n });\n // Initial detection\n liveStreamDetector.detect();\n timeShiftDetector.detect();\n\n // Refresh the playback position when the player resized or the UI is configured. The playback position marker\n // is positioned absolutely and must therefore be updated when the size of the seekbar changes.\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n this.refreshPlaybackPosition();\n this.uiBoundingRect = this.uiManager.getUI().getDomElement().get(0).getBoundingClientRect();\n });\n // Additionally, when this code is called, the seekbar is not part of the UI yet and therefore does not have a size,\n // resulting in a wrong initial position of the marker. Refreshing it once the UI is configured solved this issue.\n uimanager.onConfigured.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n // It can also happen when a new source is loaded\n player.on(player.exports.PlayerEvent.SourceLoaded, () => {\n this.refreshPlaybackPosition();\n });\n // Add markers when a source is loaded or update when a marker is added or removed\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n playbackPositionHandler();\n });\n\n // Set the snappingRange if set in the uimanager config\n if (typeof uimanager.getConfig().seekbarSnappingRange === 'number') {\n this.config.snappingRange = uimanager.getConfig().seekbarSnappingRange;\n }\n\n if (typeof uimanager.getConfig().seekbarSnappingEnabled === 'boolean') {\n this.config.snappingEnabled = uimanager.getConfig().seekbarSnappingEnabled;\n }\n\n // Initialize seekbar\n playbackPositionHandler(); // Set the playback position\n this.setBufferPosition(0);\n this.setSeekPosition(0);\n if (this.config.smoothPlaybackPositionUpdateIntervalMs !== SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED) {\n this.configureSmoothPlaybackPositionUpdater(player, uimanager);\n }\n\n // Initialize markers\n this.initializeTimelineMarkers(player, uimanager);\n }\n\n private initializeTimelineMarkers(player: PlayerAPI, uimanager: UIInstanceManager): void {\n const timelineMarkerConfig = {\n cssPrefix: this.config.cssPrefix,\n snappingRange: this.config.snappingRange,\n };\n this.timelineMarkersHandler = new TimelineMarkersHandler(timelineMarkerConfig, () => this.seekBar.width(), this.seekBarMarkersContainer);\n this.timelineMarkersHandler.initialize(player, uimanager);\n }\n\n private seekWhileScrubbing = (sender: SeekBar, args: SeekPreviewEventArgs) => {\n if (args.scrubbing) {\n this.seek(args.position);\n }\n };\n\n private getTargetSeekPosition = (percentage: number) => {\n let target: number;\n if (this.player.isLive()) {\n const maxTimeShift = this.player.getMaxTimeShift();\n target = maxTimeShift - (maxTimeShift * (percentage / 100));\n } else {\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(this.player, 0);\n const relativeSeekTarget = this.player.getDuration() * (percentage / 100);\n target = relativeSeekTarget + seekableRangeStart;\n }\n\n return target;\n }\n\n private seek = (percentage: number) => {\n const targetPlaybackPosition = this.getTargetSeekPosition(percentage);\n if (this.player.isLive()) {\n this.player.timeShift(targetPlaybackPosition, 'ui');\n } else {\n this.player.seek(targetPlaybackPosition, 'ui');\n }\n };\n\n /**\n * Update seekbar while a live stream with DVR window is paused.\n * The playback position stays still and the position indicator visually moves towards the back.\n */\n private configureLivePausedTimeshiftUpdater(\n player: PlayerAPI,\n uimanager: UIInstanceManager,\n playbackPositionHandler: () => void,\n ): void {\n // Regularly update the playback position while the timeout is active\n this.pausedTimeshiftUpdater = new Timeout(1000, playbackPositionHandler, true);\n\n // Start updater when a live stream with timeshift window is paused\n player.on(player.exports.PlayerEvent.Paused, () => {\n if (player.isLive() && player.getMaxTimeShift() < 0) {\n this.pausedTimeshiftUpdater.start();\n }\n });\n\n // Stop updater when playback continues (no matter if the updater was started before)\n player.on(player.exports.PlayerEvent.Play, () => this.pausedTimeshiftUpdater.clear());\n }\n\n private configureSmoothPlaybackPositionUpdater(player: PlayerAPI, uimanager: UIInstanceManager): void {\n /*\n * Playback position update\n *\n * We do not update the position directly from the TimeChanged event, because it arrives very jittery and\n * results in a jittery position indicator since the CSS transition time is statically set.\n * To work around this issue, we maintain a local playback position that is updated in a stable regular interval\n * and kept in sync with the player.\n */\n let currentTimeSeekBar = 0;\n let currentTimePlayer = 0;\n let updateIntervalMs = 50;\n let currentTimeUpdateDeltaSecs = updateIntervalMs / 1000;\n\n this.smoothPlaybackPositionUpdater = new Timeout(updateIntervalMs, () => {\n if (this.isSeeking()) {\n return;\n }\n\n currentTimeSeekBar += currentTimeUpdateDeltaSecs;\n\n try {\n currentTimePlayer = this.getRelativeCurrentTime();\n } catch (error) {\n // Detect if the player has been destroyed and stop updating if so\n if (error instanceof player.exports.PlayerAPINotAvailableError) {\n this.smoothPlaybackPositionUpdater.clear();\n }\n\n // If the current time cannot be read it makes no sense to continue\n return;\n }\n\n // Sync currentTime of seekbar to player\n let currentTimeDelta = currentTimeSeekBar - currentTimePlayer;\n // If the delta is larger that 2 secs, directly jump the seekbar to the\n // player time instead of smoothly fast forwarding/rewinding.\n if (Math.abs(currentTimeDelta) > 2) {\n currentTimeSeekBar = currentTimePlayer;\n }\n // If currentTimeDelta is negative and below the adjustment threshold,\n // the player is ahead of the seekbar and we 'fast forward' the seekbar\n else if (currentTimeDelta <= -currentTimeUpdateDeltaSecs) {\n currentTimeSeekBar += currentTimeUpdateDeltaSecs;\n }\n // If currentTimeDelta is positive and above the adjustment threshold,\n // the player is behind the seekbar and we 'rewind' the seekbar\n else if (currentTimeDelta >= currentTimeUpdateDeltaSecs) {\n currentTimeSeekBar -= currentTimeUpdateDeltaSecs;\n }\n\n let playbackPositionPercentage = 100 / player.getDuration() * currentTimeSeekBar;\n this.setPlaybackPosition(playbackPositionPercentage);\n }, true);\n\n let startSmoothPlaybackPositionUpdater = () => {\n if (!player.isLive()) {\n currentTimeSeekBar = this.getRelativeCurrentTime();\n this.smoothPlaybackPositionUpdater.start();\n }\n };\n\n let stopSmoothPlaybackPositionUpdater = () => {\n this.smoothPlaybackPositionUpdater.clear();\n };\n\n player.on(player.exports.PlayerEvent.Play, startSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Playing, startSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Paused, stopSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.PlaybackFinished, stopSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Seeked, () => {\n currentTimeSeekBar = this.getRelativeCurrentTime();\n });\n player.on(player.exports.PlayerEvent.SourceUnloaded, stopSmoothPlaybackPositionUpdater);\n\n if (player.isPlaying()) {\n startSmoothPlaybackPositionUpdater();\n }\n }\n\n private getRelativeCurrentTime(): number {\n return PlayerUtils.getCurrentTimeRelativeToSeekableRange(this.player);\n }\n\n release(): void {\n super.release();\n\n if (this.smoothPlaybackPositionUpdater) { // object must not necessarily exist, e.g. in volume slider subclass\n this.smoothPlaybackPositionUpdater.clear();\n }\n\n if (this.pausedTimeshiftUpdater) {\n this.pausedTimeshiftUpdater.clear();\n }\n\n if (this.config.enableSeekPreview) {\n this.onSeekPreview.unsubscribe(this.seekWhileScrubbing);\n }\n }\n\n protected toDomElement(): DOM {\n if (this.config.vertical) {\n this.config.cssClasses.push('vertical');\n }\n\n let seekBarContainer = new DOM('div', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': 'slider',\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n 'tabindex': this.config.tabIndex.toString(),\n }, this);\n\n let seekBar = new DOM('div', {\n 'class': this.prefixCss('seekbar'),\n });\n this.seekBar = seekBar;\n\n // Indicator that shows the buffer fill level\n let seekBarBufferLevel = new DOM('div', {\n 'class': this.prefixCss('seekbar-bufferlevel'),\n });\n this.seekBarBufferPosition = seekBarBufferLevel;\n\n // Indicator that shows the current playback position\n let seekBarPlaybackPosition = new DOM('div', {\n 'class': this.prefixCss('seekbar-playbackposition'),\n });\n this.seekBarPlaybackPosition = seekBarPlaybackPosition;\n\n // A marker of the current playback position, e.g. a dot or line\n let seekBarPlaybackPositionMarker = new DOM('div', {\n 'class': this.prefixCss('seekbar-playbackposition-marker'),\n });\n this.seekBarPlaybackPositionMarker = seekBarPlaybackPositionMarker;\n\n // Indicator that show where a seek will go to\n let seekBarSeekPosition = new DOM('div', {\n 'class': this.prefixCss('seekbar-seekposition'),\n });\n this.seekBarSeekPosition = seekBarSeekPosition;\n\n // Indicator that shows the full seekbar\n let seekBarBackdrop = new DOM('div', {\n 'class': this.prefixCss('seekbar-backdrop'),\n });\n this.seekBarBackdrop = seekBarBackdrop;\n\n let seekBarChapterMarkersContainer = new DOM('div', {\n 'class': this.prefixCss('seekbar-markers'),\n });\n this.seekBarMarkersContainer = seekBarChapterMarkersContainer;\n\n seekBar.append(this.seekBarBackdrop, this.seekBarBufferPosition, this.seekBarSeekPosition,\n this.seekBarPlaybackPosition, this.seekBarMarkersContainer, this.seekBarPlaybackPositionMarker);\n\n let seeking = false;\n\n // Define handler functions so we can attach/remove them later\n let mouseTouchMoveHandler = (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n // Avoid propagation to VR handler\n if (this.player.vr != null) {\n e.stopPropagation();\n }\n\n const offset = this.getOffset(e);\n const targetPercentage = 100 * offset;\n const seekPositionPx = offset * this.seekBar.width();\n\n this.setSeekPosition(targetPercentage);\n this.setPlaybackPosition(targetPercentage);\n this.onSeekPreviewEvent(targetPercentage, seekPositionPx, true);\n };\n\n let mouseTouchUpHandler = (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n // Remove handlers, seek operation is finished\n new DOM(document).off('touchmove mousemove', mouseTouchMoveHandler);\n new DOM(document).off('touchend mouseup', mouseTouchUpHandler);\n\n let targetPercentage = 100 * this.getOffset(e);\n\n if (this.config.snappingEnabled) {\n const matchingMarker = this.timelineMarkersHandler?.getMarkerAtPosition(targetPercentage);\n targetPercentage = matchingMarker ? matchingMarker.position : targetPercentage;\n }\n\n this.setSeeking(false);\n seeking = false;\n\n // Fire seeked event\n this.onSeekedEvent(targetPercentage);\n };\n\n // A seek always start with a touchstart or mousedown directly on the seekbar.\n // To track a mouse seek also outside the seekbar (for touch events this works automatically),\n // so the user does not need to take care that the mouse always stays on the seekbar, we attach the mousemove\n // and mouseup handlers to the whole document. A seek is triggered when the user lifts the mouse key.\n // A seek mouse gesture is thus basically a click with a long time frame between down and up events.\n seekBar.on('touchstart mousedown', (e: MouseEvent | TouchEvent) => {\n let isTouchEvent = BrowserUtils.isTouchSupported && this.isTouchEvent(e);\n\n // Prevent selection of DOM elements (also prevents mousedown if current event is touchstart)\n e.preventDefault();\n // Avoid propagation to VR handler\n if (this.player.vr != null) {\n e.stopPropagation();\n }\n\n this.setSeeking(true); // Set seeking class on DOM element\n seeking = true; // Set seek tracking flag\n\n // Fire seeked event\n this.onSeekEvent();\n\n // Add handler to track the seek operation over the whole document\n new DOM(document).on(isTouchEvent ? 'touchmove' : 'mousemove', mouseTouchMoveHandler);\n new DOM(document).on(isTouchEvent ? 'touchend' : 'mouseup', mouseTouchUpHandler);\n });\n\n // Display seek target indicator when mouse hovers or finger slides over seekbar\n seekBar.on('touchmove mousemove', (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n if (seeking) {\n mouseTouchMoveHandler(e);\n }\n\n const offset = this.getOffset(e);\n const seekPositionPercentage = 100 * offset;\n const seekPositionPx = offset * this.seekBar.width();\n\n this.setSeekPosition(seekPositionPercentage);\n this.onSeekPreviewEvent(seekPositionPercentage, seekPositionPx, false);\n\n if (this.hasLabel() && this.getLabel().isHidden()) {\n this.getLabel().show();\n }\n });\n\n // Hide seek target indicator when mouse or finger leaves seekbar\n seekBar.on('touchend mouseleave', (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n this.setSeekPosition(0);\n\n if (this.hasLabel()) {\n this.getLabel().hide();\n }\n });\n\n seekBarContainer.append(seekBar);\n\n if (this.label) {\n seekBarContainer.append(this.label.getDomElement());\n }\n\n return seekBarContainer;\n }\n\n /**\n * Gets the horizontal offset of a mouse/touch event point from the left edge of the seek bar.\n * @param eventPageX the pageX coordinate of an event to calculate the offset from\n * @returns {number} a number in the range of [0, 1], where 0 is the left edge and 1 is the right edge\n */\n private getHorizontalOffset(eventPageX: number): number {\n let elementOffsetPx = this.seekBar.offset().left;\n let widthPx = this.seekBar.width();\n let offsetPx = eventPageX - elementOffsetPx;\n let offset = 1 / widthPx * offsetPx;\n\n return this.sanitizeOffset(offset);\n }\n\n /**\n * Gets the vertical offset of a mouse/touch event point from the bottom edge of the seek bar.\n * @param eventPageY the pageX coordinate of an event to calculate the offset from\n * @returns {number} a number in the range of [0, 1], where 0 is the bottom edge and 1 is the top edge\n */\n private getVerticalOffset(eventPageY: number): number {\n let elementOffsetPx = this.seekBar.offset().top;\n let widthPx = this.seekBar.height();\n let offsetPx = eventPageY - elementOffsetPx;\n let offset = 1 / widthPx * offsetPx;\n\n return 1 - this.sanitizeOffset(offset);\n }\n\n /**\n * Gets the mouse or touch event offset for the current configuration (horizontal or vertical).\n * @param e the event to calculate the offset from\n * @returns {number} a number in the range of [0, 1]\n * @see #getHorizontalOffset\n * @see #getVerticalOffset\n */\n private getOffset(e: MouseEvent | TouchEvent): number {\n if (BrowserUtils.isTouchSupported && this.isTouchEvent(e)) {\n if (this.config.vertical) {\n return this.getVerticalOffset(e.type === 'touchend' ? e.changedTouches[0].pageY : e.touches[0].pageY);\n } else {\n return this.getHorizontalOffset(e.type === 'touchend' ? e.changedTouches[0].pageX : e.touches[0].pageX);\n }\n }\n else if (e instanceof MouseEvent) {\n if (this.config.vertical) {\n return this.getVerticalOffset(e.pageY);\n } else {\n return this.getHorizontalOffset(e.pageX);\n }\n }\n else {\n if (console) {\n console.warn('invalid event');\n }\n return 0;\n }\n }\n\n /**\n * Sanitizes the mouse offset to the range of [0, 1].\n *\n * When tracking the mouse outside the seek bar, the offset can be outside the desired range and this method\n * limits it to the desired range. E.g. a mouse event left of the left edge of a seek bar yields an offset below\n * zero, but to display the seek target on the seek bar, we need to limit it to zero.\n *\n * @param offset the offset to sanitize\n * @returns {number} the sanitized offset.\n */\n private sanitizeOffset(offset: number) {\n // Since we track mouse moves over the whole document, the target can be outside the seek range,\n // and we need to limit it to the [0, 1] range.\n if (offset < 0) {\n offset = 0;\n } else if (offset > 1) {\n offset = 1;\n }\n\n return offset;\n }\n\n /**\n * Sets the position of the playback position indicator.\n * @param percent a number between 0 and 100 as returned by the player\n */\n setPlaybackPosition(percent: number) {\n this.playbackPositionPercentage = percent;\n\n // Set position of the bar\n this.setPosition(this.seekBarPlaybackPosition, percent);\n\n // Set position of the marker\n let totalSize = (this.config.vertical ? (this.seekBar.height() - this.seekBarPlaybackPositionMarker.height()) : this.seekBar.width());\n let px = (totalSize) / 100 * percent;\n if (this.config.vertical) {\n px = this.seekBar.height() - px - this.seekBarPlaybackPositionMarker.height();\n }\n\n let style = this.config.vertical ?\n // -ms-transform required for IE9\n // -webkit-transform required for Android 4.4 WebView\n {\n 'transform': 'translateY(' + px + 'px)',\n '-ms-transform': 'translateY(' + px + 'px)',\n '-webkit-transform': 'translateY(' + px + 'px)',\n } :\n {\n 'transform': 'translateX(' + px + 'px)',\n '-ms-transform': 'translateX(' + px + 'px)',\n '-webkit-transform': 'translateX(' + px + 'px)',\n };\n this.seekBarPlaybackPositionMarker.css(style);\n }\n\n /**\n * Refreshes the playback position. Can be used by subclasses to refresh the position when\n * the size of the component changes.\n */\n protected refreshPlaybackPosition() {\n this.setPlaybackPosition(this.playbackPositionPercentage);\n }\n\n /**\n * Sets the position until which media is buffered.\n * @param percent a number between 0 and 100\n */\n setBufferPosition(percent: number) {\n this.setPosition(this.seekBarBufferPosition, percent);\n }\n\n /**\n * Sets the position where a seek, if executed, would jump to.\n * @param percent a number between 0 and 100\n */\n setSeekPosition(percent: number) {\n this.setPosition(this.seekBarSeekPosition, percent);\n }\n\n /**\n * Set the actual position (width or height) of a DOM element that represent a bar in the seek bar.\n * @param element the element to set the position for\n * @param percent a number between 0 and 100\n */\n private setPosition(element: DOM, percent: number) {\n let scale = percent / 100;\n\n // When the scale is exactly 1 or very near 1 (and the browser internally rounds it to 1), browsers seem to render\n // the elements differently and the height gets slightly off, leading to mismatching heights when e.g. the buffer\n // level bar has a width of 1 and the playback position bar has a width < 1. A jittering buffer level around 1\n // leads to an even worse flickering effect.\n // Various changes in CSS styling and DOM hierarchy did not solve the issue so the workaround is to avoid a scale\n // of exactly 1.\n if (scale >= 0.99999 && scale <= 1.00001) {\n scale = 0.99999;\n }\n\n let style = this.config.vertical ?\n // -ms-transform required for IE9\n // -webkit-transform required for Android 4.4 WebView\n {\n 'transform': 'scaleY(' + scale + ')',\n '-ms-transform': 'scaleY(' + scale + ')',\n '-webkit-transform': 'scaleY(' + scale + ')',\n } :\n {\n 'transform': 'scaleX(' + scale + ')',\n '-ms-transform': 'scaleX(' + scale + ')',\n '-webkit-transform': 'scaleX(' + scale + ')',\n };\n element.css(style);\n }\n\n /**\n * Puts the seek bar into or out of seeking state by adding/removing a class to the DOM element. This can be used\n * to adjust the styling while seeking.\n *\n * @param seeking should be true when entering seek state, false when exiting the seek state\n */\n setSeeking(seeking: boolean) {\n if (seeking) {\n this.getDomElement().addClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n } else {\n this.getDomElement().removeClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n }\n }\n\n /**\n * Checks if the seek bar is currently in the seek state.\n * @returns {boolean} true if in seek state, else false\n */\n isSeeking(): boolean {\n return this.getDomElement().hasClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n }\n\n /**\n * Checks if the seek bar has a {@link SeekBarLabel}.\n * @returns {boolean} true if the seek bar has a label, else false\n */\n hasLabel(): boolean {\n return this.label != null;\n }\n\n /**\n * Gets the label of this seek bar.\n * @returns {SeekBarLabel} the label if this seek bar has a label, else null\n */\n getLabel(): SeekBarLabel | null {\n return this.label;\n }\n\n protected onSeekEvent() {\n this.seekBarEvents.onSeek.dispatch(this);\n }\n\n private updateLabelPosition = (pixelPosition: number) => {\n if (!this.uiBoundingRect) {\n this.uiBoundingRect = this.uiManager.getUI().getDomElement().get(0).getBoundingClientRect();\n }\n\n this.label.setPositionInBounds(pixelPosition, this.uiBoundingRect);\n };\n\n protected onSeekPreviewEvent(percentage: number, targetOffsetPx: number, scrubbing: boolean) {\n let snappedMarker = this.timelineMarkersHandler && this.timelineMarkersHandler.getMarkerAtPosition(percentage);\n\n let seekPositionPercentage = percentage;\n\n if (snappedMarker) {\n if (snappedMarker.duration > 0) {\n if (percentage < snappedMarker.position) {\n // Snap the position to the start of the interval if the seek is within the left snap margin\n // We know that we are within a snap margin when we are outside the marker interval but still\n // have a snappedMarker\n seekPositionPercentage = snappedMarker.position;\n } else if (percentage > snappedMarker.position + snappedMarker.duration) {\n // Snap the position to the end of the interval if the seek is within the right snap margin\n seekPositionPercentage = snappedMarker.position + snappedMarker.duration;\n }\n } else {\n // Position markers always snap to their marker position\n seekPositionPercentage = snappedMarker.position;\n }\n }\n\n if (this.label) {\n this.updateLabelPosition(targetOffsetPx);\n }\n\n this.seekBarEvents.onSeekPreview.dispatch(this, {\n scrubbing: scrubbing,\n position: seekPositionPercentage,\n marker: snappedMarker,\n });\n }\n\n protected onSeekedEvent(percentage: number) {\n this.seekBarEvents.onSeeked.dispatch(this, percentage);\n }\n\n /**\n * Gets the event that is fired when a scrubbing seek operation is started.\n * @returns {Event<SeekBar, NoArgs>}\n */\n get onSeek(): Event<SeekBar, NoArgs> {\n return this.seekBarEvents.onSeek.getEvent();\n }\n\n /**\n * Gets the event that is fired during a scrubbing seek (to indicate that the seek preview, i.e. the video frame,\n * should be updated), or during a normal seek preview when the seek bar is hovered (and the seek target,\n * i.e. the seek bar label, should be updated).\n * @returns {Event<SeekBar, SeekPreviewEventArgs>}\n */\n get onSeekPreview(): Event<SeekBar, SeekPreviewEventArgs> {\n return this.seekBarEvents.onSeekPreview.getEvent();\n }\n\n /**\n * Gets the event that is fired when a scrubbing seek has finished or when a direct seek is issued.\n * @returns {Event<SeekBar, number>}\n */\n get onSeeked(): Event<SeekBar, number> {\n return this.seekBarEvents.onSeeked.getEvent();\n }\n\n\n protected onShowEvent(): void {\n super.onShowEvent();\n\n // Refresh the position of the playback position when the seek bar becomes visible. To correctly set the position,\n // the DOM element must be fully initialized an have its size calculated, because the position is set as an absolute\n // value calculated from the size. This required size is not known when it is hidden.\n // For such cases, we refresh the position here in onShow because here it is guaranteed that the component knows\n // its size and can set the position correctly.\n this.refreshPlaybackPosition();\n }\n\n /**\n * Checks if TouchEvent is supported.\n * @returns {boolean} true if TouchEvent not undefined, else false\n */\n isTouchEvent(e: UIEvent): e is TouchEvent {\n return window.TouchEvent && e instanceof TouchEvent;\n }\n}\n","import {PlayerAPI} from 'bitmovin-player';\n\nexport function getMinBufferLevel(player: PlayerAPI): number {\n\n const playerDuration = player.getDuration();\n\n const videoBufferLength = player.getVideoBufferLength();\n const audioBufferLength = player.getAudioBufferLength();\n // Calculate the buffer length which is the smaller length of the audio and video buffers. If one of these\n // buffers is not available, we set it's value to MAX_VALUE to make sure that the other real value is taken\n // as the buffer length.\n let bufferLength = Math.min(\n videoBufferLength != null ? videoBufferLength : Number.MAX_VALUE,\n audioBufferLength != null ? audioBufferLength : Number.MAX_VALUE);\n // If both buffer lengths are missing, we set the buffer length to zero\n if (bufferLength === Number.MAX_VALUE) {\n bufferLength = 0;\n }\n\n return 100 / playerDuration * bufferLength;\n}\n","import { UIUtils } from '../uiutils';\nimport { DOM } from '../dom';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { VolumeController } from '../volumecontroller';\n\nexport enum SeekBarType {\n Vod,\n Live,\n Volume,\n}\n\ninterface Range {\n min: number;\n max: number;\n}\n\ninterface KeyStepIncrementsConfig {\n leftRight: number;\n upDown: number;\n}\n\nconst coerceValueIntoRange = (\n value: number,\n range: Range,\n cb: (value: number) => void,\n) => {\n if (value < range.min) {\n cb(range.min);\n } else if (value > range.max) {\n cb(range.max);\n } else {\n cb(value);\n }\n};\n\n/**\n * @category Utils\n */\nexport class SeekBarController {\n protected keyStepIncrements: KeyStepIncrementsConfig;\n protected player: PlayerAPI;\n protected volumeController: VolumeController;\n\n constructor(\n keyStepIncrements: KeyStepIncrementsConfig,\n player: PlayerAPI,\n volumeController: VolumeController,\n ) {\n this.keyStepIncrements = keyStepIncrements;\n this.player = player;\n this.volumeController = volumeController;\n }\n\n protected arrowKeyControls(\n currentValue: number,\n range: Range,\n valueUpdate: (value: number) => void,\n ) {\n const controlValue = Math.floor(currentValue);\n\n return {\n left: () => coerceValueIntoRange(controlValue - this.keyStepIncrements.leftRight, range, valueUpdate),\n right: () => coerceValueIntoRange(controlValue + this.keyStepIncrements.leftRight, range, valueUpdate),\n up: () => coerceValueIntoRange(controlValue + this.keyStepIncrements.upDown, range, valueUpdate),\n down: () => coerceValueIntoRange(controlValue - this.keyStepIncrements.upDown, range, valueUpdate),\n home: () => coerceValueIntoRange(range.min, range, valueUpdate),\n end: () => coerceValueIntoRange(range.max, range, valueUpdate),\n };\n }\n\n protected seekBarControls(type: SeekBarType) {\n if (type === SeekBarType.Live) {\n return this.arrowKeyControls(this.player.getTimeShift(), { min: this.player.getMaxTimeShift(), max: 0 }, this.player.timeShift);\n } else if (type === SeekBarType.Vod) {\n return this.arrowKeyControls(this.player.getCurrentTime(), { min: 0, max: this.player.getDuration() }, this.player.seek);\n } else if (type === SeekBarType.Volume && this.volumeController != null) {\n const volumeTransition = this.volumeController.startTransition();\n return this.arrowKeyControls(this.player.getVolume(), { min: 0, max: 100 }, volumeTransition.finish.bind(volumeTransition));\n }\n }\n\n public setSeekBarControls(domElement: DOM, type: () => SeekBarType) {\n domElement.on('keydown', (e: KeyboardEvent) => {\n const controls = this.seekBarControls(type());\n switch (e.keyCode) {\n case UIUtils.KeyCode.LeftArrow: {\n controls.left();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.RightArrow: {\n controls.right();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.UpArrow: {\n controls.up();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.DownArrow: {\n controls.down();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.Home: {\n controls.home();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.End: {\n controls.end();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.Space: {\n this.player.isPlaying() ? this.player.pause() : this.player.play();\n e.preventDefault();\n break;\n }\n }\n });\n }\n}","import {Container, ContainerConfig} from './container';\nimport {Label, LabelConfig} from './label';\nimport {Component, ComponentConfig} from './component';\nimport { UIInstanceManager } from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport {ImageLoader} from '../imageloader';\nimport {CssProperties} from '../dom';\nimport { PlayerAPI, Thumbnail } from 'bitmovin-player';\nimport { SeekBar, SeekPreviewEventArgs } from './seekbar';\nimport { PlayerUtils } from '../playerutils';\n\n/**\n * Configuration interface for a {@link SeekBarLabel}.\n *\n * @category Configs\n */\nexport interface SeekBarLabelConfig extends ContainerConfig {\n // nothing yet\n}\n\n/**\n * A label for a {@link SeekBar} that can display the seek target time, a thumbnail, and title (e.g. chapter title).\n *\n * @category Components\n */\nexport class SeekBarLabel extends Container<SeekBarLabelConfig> {\n\n private timeLabel: Label<LabelConfig>;\n private titleLabel: Label<LabelConfig>;\n private thumbnail: Component<ComponentConfig>;\n\n private thumbnailImageLoader: ImageLoader;\n\n private timeFormat: string;\n\n private appliedMarkerCssClasses: string[] = [];\n private player: PlayerAPI;\n private uiManager: UIInstanceManager;\n private readonly container: Container<ContainerConfig>;\n private readonly caret: Label<LabelConfig>;\n\n constructor(config: SeekBarLabelConfig = {}) {\n super(config);\n\n this.timeLabel = new Label({ cssClasses: ['seekbar-label-time'] });\n this.titleLabel = new Label({ cssClasses: ['seekbar-label-title'] });\n this.thumbnail = new Component({ cssClasses: ['seekbar-thumbnail'], role: 'img' });\n this.thumbnailImageLoader = new ImageLoader();\n\n this.container = new Container({\n components: [\n this.thumbnail,\n new Container({\n components: [this.titleLabel, this.timeLabel],\n cssClass: 'seekbar-label-metadata',\n }),\n ],\n cssClass: 'seekbar-label-inner',\n });\n\n this.caret = new Label({ cssClasses: ['seekbar-label-caret'] });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-seekbar-label',\n components: [this.container, this.caret],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.player = player;\n this.uiManager = uimanager;\n uimanager.onSeekPreview.subscribeRateLimited(this.handleSeekPreview, 100);\n\n let init = () => {\n // Set time format depending on source duration\n this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ?\n StringUtils.FORMAT_HHMMSS : StringUtils.FORMAT_MMSS;\n // Set initial state of title and thumbnail to handle sourceLoaded when switching to a live-stream\n this.setTitleText(null);\n this.setThumbnail(null);\n };\n\n uimanager.getConfig().events.onUpdated.subscribe(init);\n init();\n }\n\n private handleSeekPreview = (sender: SeekBar, args: SeekPreviewEventArgs) => {\n if (this.player.isLive()) {\n let maxTimeShift = this.player.getMaxTimeShift();\n let timeShiftPreview = maxTimeShift - maxTimeShift * (args.position / 100);\n\n this.setTime(timeShiftPreview);\n\n // In case of a live stream the player expects the time passed into the getThumbnail as a wallClockTime and not\n // as a relative timeShift value.\n const convertTimeShiftPreviewToWallClockTime = (targetTimeShift: number): number => {\n const currentTimeShift = this.player.getTimeShift();\n const currentTime = this.player.getCurrentTime();\n\n const wallClockTimeOfLiveEdge = currentTime - currentTimeShift;\n return wallClockTimeOfLiveEdge + targetTimeShift;\n };\n\n const wallClockTime = convertTimeShiftPreviewToWallClockTime(timeShiftPreview);\n this.setThumbnail(this.player.getThumbnail(wallClockTime));\n\n } else {\n let time = this.player.getDuration() * (args.position / 100);\n this.setTime(time);\n\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(this.player, 0);\n const absoluteSeekTarget = time + seekableRangeStart;\n this.setThumbnail(this.player.getThumbnail(absoluteSeekTarget));\n }\n\n if (args.marker) {\n this.setTitleText(args.marker.marker.title);\n } else {\n this.setTitleText(null);\n }\n\n // Remove CSS classes from previous marker\n if (this.appliedMarkerCssClasses.length > 0) {\n this.getDomElement().removeClass(this.appliedMarkerCssClasses.join(' '));\n this.appliedMarkerCssClasses = [];\n }\n\n // Add CSS classes of current marker\n if (args.marker) {\n const cssClasses = (args.marker.marker.cssClasses || []).map(cssClass => this.prefixCss(cssClass));\n this.getDomElement().addClass(cssClasses.join(' '));\n this.appliedMarkerCssClasses = cssClasses;\n }\n };\n\n public setPositionInBounds(seekPositionPx: number, bounds: DOMRect) {\n this.getDomElement().css('left', seekPositionPx + 'px');\n\n // Check parent container as it has a padding that needs to be considered\n const labelBounding = this.container.getDomElement().get(0).parentElement.getBoundingClientRect();\n\n let preventOverflowOffset = 0;\n if (labelBounding.right > bounds.right) {\n preventOverflowOffset = labelBounding.right - bounds.right;\n } else if (labelBounding.left < bounds.left) {\n preventOverflowOffset = labelBounding.left - bounds.left;\n }\n\n if (preventOverflowOffset !== 0) {\n this.getDomElement().css('left', seekPositionPx - preventOverflowOffset + 'px');\n\n this.caret.getDomElement().css('transform', `translateX(${preventOverflowOffset}px)`);\n } else {\n this.caret.getDomElement().css('transform', null);\n }\n }\n\n /**\n * Sets arbitrary text on the label.\n * @param text the text to show on the label\n */\n setText(text: string) {\n this.timeLabel.setText(text);\n }\n\n /**\n * Sets a time to be displayed on the label.\n * @param seconds the time in seconds to display on the label\n */\n setTime(seconds: number) {\n this.setText(StringUtils.secondsToTime(seconds, this.timeFormat));\n }\n\n /**\n * Sets the text on the title label.\n * @param text the text to show on the label\n */\n setTitleText(text = '') {\n this.titleLabel.setText(text);\n }\n\n /**\n * Sets or removes a thumbnail on the label.\n * @param thumbnail the thumbnail to display on the label or null to remove a displayed thumbnail\n */\n setThumbnail(thumbnail: Thumbnail = null) {\n let thumbnailElement = this.thumbnail.getDomElement();\n\n if (thumbnail == null) {\n thumbnailElement.css({\n 'background-image': null,\n 'display': null,\n 'width': null,\n 'height': null,\n });\n }\n else {\n // We use the thumbnail image loader to make sure the thumbnail is loaded and it's size is known before be can\n // calculate the CSS properties and set them on the element.\n this.thumbnailImageLoader.load(thumbnail.url, (url, width, height) => {\n // can be checked like that because x/y/w/h are either all present or none\n // https://www.w3.org/TR/media-frags/#naming-space\n if (thumbnail.x !== undefined) {\n thumbnailElement.css(this.thumbnailCssSprite(thumbnail, width, height));\n } else {\n thumbnailElement.css(this.thumbnailCssSingleImage(thumbnail, width, height));\n }\n });\n }\n }\n\n private thumbnailCssSprite(thumbnail: Thumbnail, width: number, height: number): CssProperties {\n let thumbnailCountX = width / thumbnail.width;\n let thumbnailCountY = height / thumbnail.height;\n\n let thumbnailIndexX = thumbnail.x / thumbnail.width;\n let thumbnailIndexY = thumbnail.y / thumbnail.height;\n\n let sizeX = 100 * thumbnailCountX;\n let sizeY = 100 * thumbnailCountY;\n\n let offsetX = 100 * thumbnailIndexX;\n let offsetY = 100 * thumbnailIndexY;\n\n let aspectRatio = 1 / thumbnail.width * thumbnail.height;\n\n // The thumbnail size is set by setting the CSS 'width' and 'padding-bottom' properties. 'padding-bottom' is\n // used because it is relative to the width and can be used to set the aspect ratio of the thumbnail.\n // A default value for width is set in the stylesheet and can be overwritten from there or anywhere else.\n return {\n 'display': 'inherit',\n 'background-image': `url(${thumbnail.url})`,\n 'padding-bottom': `${100 * aspectRatio}%`,\n 'background-size': `${sizeX}% ${sizeY}%`,\n 'background-position': `-${offsetX}% -${offsetY}%`,\n };\n }\n\n private thumbnailCssSingleImage(thumbnail: Thumbnail, width: number, height: number): CssProperties {\n let aspectRatio = 1 / width * height;\n\n return {\n 'display': 'inherit',\n 'background-image': `url(${thumbnail.url})`,\n 'padding-bottom': `${100 * aspectRatio}%`,\n 'background-size': `100% 100%`,\n 'background-position': `0 0`,\n };\n }\n\n release(): void {\n super.release();\n\n this.uiManager.onSeekPreview.unsubscribe(this.handleSeekPreview);\n }\n}\n","import { ListSelector, ListSelectorConfig } from './listselector';\nimport { DOM } from '../dom';\nimport { i18n } from '../localization/i18n';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { UIContainer } from './uicontainer';\nimport { PlayerUtils } from '../playerutils';\nimport { ViewMode } from './component';\n\nconst DocumentDropdownClosedEvents = [\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'pointermove',\n 'click',\n 'keydown',\n 'keypress',\n 'keyup',\n 'blur',\n];\n\nconst SelectDropdownClosedEvents = [\n 'change',\n 'keyup',\n 'mouseup',\n];\n\nconst DropdownOpenedEvents: [string, (event: Event) => boolean][] = [\n ['click', () => true],\n ['keydown', (event: KeyboardEvent) => [' ', 'ArrowUp', 'ArrowDown'].includes(event.key)],\n ['mousedown', () => true],\n];\n\nconst Timeout = 100;\n\n/**\n * A simple select box providing the possibility to select a single item out of a list of available items.\n *\n * DOM example:\n * <code>\n * <select class='ui-selectbox'>\n * <option value='key'>label</option>\n * ...\n * </select>\n * </code>\n *\n * @category Components\n */\n\nexport class SelectBox extends ListSelector<ListSelectorConfig> {\n private selectElement: DOM | undefined;\n private dropdownCloseListenerTimeoutId = 0;\n private removeDropdownCloseListeners = () => {};\n private uiContainer: UIContainer | undefined;\n private removeDropdownOpenedListeners = () => {};\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-selectbox',\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n this.selectElement = new DOM('select', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n }, this);\n\n this.onDisabled.subscribe(this.closeDropdown);\n this.onHide.subscribe(this.closeDropdown);\n this.addDropdownOpenedListeners();\n this.updateDomItems();\n\n this.selectElement.on('change', this.onChange);\n\n return this.selectElement;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager) {\n super.configure(player, uimanager);\n this.uiContainer = uimanager.getUI();\n this.uiContainer?.onPlayerStateChange().subscribe(this.onPlayerStateChange);\n }\n\n private readonly onChange = () => {\n let value = this.selectElement.val();\n this.onItemSelectedEvent(value, false);\n };\n\n private getSelectElement() {\n return this.selectElement?.get()?.[0];\n }\n\n protected updateDomItems(selectedValue: string = null) {\n if (this.selectElement === undefined) {\n return;\n }\n\n // Delete all children\n this.selectElement.empty();\n\n // Add updated children\n for (let item of this.items) {\n let optionElement = new DOM('option', {\n 'value': String(item.key),\n }).html(i18n.performLocalization(item.label));\n\n if (item.key === String(selectedValue)) { // convert selectedValue to string to catch 'null'/null case\n optionElement.attr('selected', 'selected');\n }\n\n this.selectElement.append(optionElement);\n }\n }\n\n protected onItemAddedEvent(value: string) {\n super.onItemAddedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemRemovedEvent(value: string) {\n super.onItemRemovedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemSelectedEvent(value: string, updateDomItems: boolean = true) {\n super.onItemSelectedEvent(value);\n if (updateDomItems) {\n this.updateDomItems(value);\n }\n }\n\n public readonly closeDropdown = () => {\n const select = this.getSelectElement();\n\n if (select === undefined) {\n return;\n }\n\n select.blur();\n };\n\n private readonly onPlayerStateChange = (_: UIContainer, state: PlayerUtils.PlayerState) => {\n if ([PlayerUtils.PlayerState.Idle, PlayerUtils.PlayerState.Finished].includes(state)) {\n this.closeDropdown();\n }\n };\n\n private onDropdownOpened = () => {\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n this.dropdownCloseListenerTimeoutId = window.setTimeout(() => this.addDropdownCloseListeners(), Timeout);\n this.onViewModeChangedEvent(ViewMode.Persistent);\n };\n\n private onDropdownClosed = () => {\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n this.removeDropdownCloseListeners();\n this.onViewModeChangedEvent(ViewMode.Temporary);\n };\n\n private addDropdownCloseListeners() {\n this.removeDropdownCloseListeners();\n\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n DocumentDropdownClosedEvents.forEach(event => document.addEventListener(event, this.onDropdownClosed, true));\n SelectDropdownClosedEvents.forEach(event => this.selectElement.on(event, this.onDropdownClosed, true));\n\n this.removeDropdownCloseListeners = () => {\n DocumentDropdownClosedEvents.forEach(event => document.removeEventListener(event, this.onDropdownClosed, true));\n SelectDropdownClosedEvents.forEach(event => this.selectElement.off(event, this.onDropdownClosed, true));\n };\n }\n\n private addDropdownOpenedListeners() {\n const removeListenerFunctions: (() => void)[] = [];\n\n this.removeDropdownOpenedListeners();\n\n for (const [event, filter] of DropdownOpenedEvents) {\n const listener = (event: Event) => {\n if (filter(event)) {\n this.onDropdownOpened();\n }\n };\n\n removeListenerFunctions.push(() => this.selectElement.off(event, listener, true));\n this.selectElement.on(event, listener, true);\n }\n\n this.removeDropdownOpenedListeners = () => {\n for (const remove of removeListenerFunctions) {\n remove();\n }\n };\n }\n\n release() {\n super.release();\n\n this.removeDropdownCloseListeners();\n this.removeDropdownOpenedListeners();\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n }\n}\n","import { Container, ContainerConfig } from './container';\nimport { SelectBox } from './selectbox';\nimport { UIInstanceManager } from '../uimanager';\nimport { Timeout } from '../timeout';\nimport { Event, EventDispatcher, NoArgs } from '../eventdispatcher';\nimport { SettingsPanelPage } from './settingspanelpage';\nimport { SettingsPanelItem } from './settingspanelitem';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { Component, ComponentConfig } from './component';\n\n/**\n * Configuration interface for a {@link SettingsPanel}.\n *\n * @category Configs\n */\nexport interface SettingsPanelConfig extends ContainerConfig {\n /**\n * The delay in milliseconds after which the settings panel will be hidden when there is no user interaction.\n * Set to -1 to disable automatic hiding.\n * Default: 3 seconds (3000)\n */\n hideDelay?: number;\n\n /**\n * Flag to specify if there should be an animation when switching SettingsPanelPages.\n * Default: true\n */\n pageTransitionAnimation?: boolean;\n}\n\nenum NavigationDirection {\n Forwards,\n Backwards,\n}\n\n/**\n * A panel containing a list of {@link SettingsPanelPage items}.\n *\n * To configure pages just pass them in the components array.\n *\n * Example:\n * let settingsPanel = new SettingsPanel({\n * hidden: true,\n * });\n *\n * let settingsPanelPage = new SettingsPanelPage({\n * components: […]\n * });\n *\n * let secondSettingsPanelPage = new SettingsPanelPage({\n * components: […]\n * });\n *\n * settingsPanel.addComponent(settingsPanelPage);\n * settingsPanel.addComponent(secondSettingsPanelPage);\n *\n * For an example how to navigate between pages @see SettingsPanelPageNavigatorButton\n *\n * @category Components\n */\nexport class SettingsPanel extends Container<SettingsPanelConfig> {\n\n private static readonly CLASS_ACTIVE_PAGE = 'active';\n\n // navigation handling\n private activePage: SettingsPanelPage;\n private navigationStack: SettingsPanelPage[] = [];\n\n private settingsPanelEvents = {\n onSettingsStateChanged: new EventDispatcher<SettingsPanel, NoArgs>(),\n };\n\n private hideTimeout: Timeout;\n\n constructor(config: SettingsPanelConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settings-panel',\n hideDelay: 3000,\n pageTransitionAnimation: true,\n } as SettingsPanelConfig, this.config);\n\n this.activePage = this.getRootPage();\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n uimanager.onControlsHide.subscribe(() => this.hideHoveredSelectBoxes());\n uimanager.onComponentViewModeChanged.subscribe((_, { mode }) => this.trackComponentViewMode(mode));\n\n if (config.hideDelay > -1) {\n this.hideTimeout = new Timeout(config.hideDelay, () => {\n this.hide();\n this.hideHoveredSelectBoxes();\n });\n this.getDomElement().on('mouseenter', () => {\n // On mouse enter clear the timeout\n this.hideTimeout.clear();\n });\n this.getDomElement().on('mouseleave', () => {\n // On mouse leave activate the timeout\n this.hideTimeout.reset();\n });\n this.getDomElement().on('focusin', () => {\n this.hideTimeout.clear();\n });\n this.getDomElement().on('focusout', () => {\n this.hideTimeout.reset();\n });\n }\n\n this.onHide.subscribe(() => {\n if (config.hideDelay > -1) {\n // Clear timeout when hidden from outside\n this.hideTimeout.clear();\n }\n\n // Since we don't reset the actual navigation here we need to simulate a onInactive event in case some panel\n // needs to do something when they become invisible / inactive.\n this.activePage.onInactiveEvent();\n });\n\n this.onShow.subscribe(() => {\n // Reset navigation when te panel gets visible to avoid a weird animation when hiding\n this.resetNavigation(true);\n // Since we don't need to navigate to the root page again we need to fire the onActive event when the settings\n // panel gets visible.\n this.activePage.onActiveEvent();\n\n if (config.hideDelay > -1) {\n // Activate timeout when shown\n this.hideTimeout.start();\n }\n });\n\n // pass event from root page through\n this.getRootPage().onSettingsStateChanged.subscribe(() => {\n this.onSettingsStateChangedEvent();\n });\n\n this.updateActivePageClass();\n }\n\n /**\n * Returns the current active / visible page\n * @return {SettingsPanelPage}\n */\n getActivePage(): SettingsPanelPage {\n return this.activePage;\n }\n\n /**\n * Sets the\n * @deprecated Use {@link setActivePage} instead\n * @param index\n */\n setActivePageIndex(index: number): void {\n this.setActivePage(this.getPages()[index]);\n }\n\n /**\n * Adds the passed page to the navigation stack and makes it visible.\n * Use {@link popSettingsPanelPage} to navigate backwards.\n *\n * Results in no-op if the target page is the current page.\n * @param targetPage\n */\n setActivePage(targetPage: SettingsPanelPage): void {\n if (targetPage === this.getActivePage()) {\n console.warn('Page is already the current one ... skipping navigation');\n return;\n }\n\n this.navigateToPage(\n targetPage,\n this.getActivePage(),\n NavigationDirection.Forwards,\n !(this.config as SettingsPanelConfig).pageTransitionAnimation,\n );\n }\n\n /**\n * Resets the navigation stack by navigating back to the root page and displaying it.\n */\n popToRootSettingsPanelPage(): void {\n this.resetNavigation((this.config as SettingsPanelConfig).pageTransitionAnimation);\n }\n\n /**\n * Removes the current page from the navigation stack and makes the previous one visible.\n * Results in a no-op if we are already on the root page.\n */\n popSettingsPanelPage() {\n if (this.navigationStack.length === 0) {\n console.warn('Already on the root page ... skipping navigation');\n return;\n }\n\n let targetPage = this.navigationStack[this.navigationStack.length - 2];\n // The root part isn't part of the navigation stack so handle it explicitly here\n if (!targetPage) {\n targetPage = this.getRootPage();\n }\n\n this.navigateToPage(\n targetPage,\n this.activePage,\n NavigationDirection.Backwards,\n !(this.config as SettingsPanelConfig).pageTransitionAnimation,\n );\n }\n\n /**\n * Checks if there are active settings within the root page of the settings panel.\n * An active setting is a setting that is visible and enabled, which the user can interact with.\n * @returns {boolean} true if there are active settings, false if the panel is functionally empty to a user\n */\n rootPageHasActiveSettings(): boolean {\n return this.getRootPage().hasActiveSettings();\n }\n\n /**\n * Return all configured pages\n * @returns {SettingsPanelPage[]}\n */\n getPages(): SettingsPanelPage[] {\n return <SettingsPanelPage[]>this.config.components.filter(component => component instanceof SettingsPanelPage);\n }\n\n get onSettingsStateChanged(): Event<SettingsPanel, NoArgs> {\n return this.settingsPanelEvents.onSettingsStateChanged.getEvent();\n }\n\n release(): void {\n super.release();\n if (this.hideTimeout) {\n this.hideTimeout.clear();\n }\n }\n\n // Support adding settingsPanelPages after initialization\n addComponent(component: Component<ComponentConfig>) {\n if (this.getPages().length === 0 && component instanceof SettingsPanelPage) {\n this.activePage = component;\n }\n super.addComponent(component);\n }\n\n protected suspendHideTimeout() {\n this.hideTimeout.suspend();\n }\n\n protected resumeHideTimeout() {\n this.hideTimeout.resume(true);\n }\n\n private updateActivePageClass(): void {\n this.getPages().forEach((page: SettingsPanelPage) => {\n if (page === this.activePage) {\n page.getDomElement().addClass(this.prefixCss(SettingsPanel.CLASS_ACTIVE_PAGE));\n } else {\n page.getDomElement().removeClass(this.prefixCss(SettingsPanel.CLASS_ACTIVE_PAGE));\n }\n });\n }\n\n private resetNavigation(resetNavigationOnShow: boolean): void {\n const sourcePage = this.getActivePage();\n const rootPage = this.getRootPage();\n if (sourcePage) {\n // Since the onInactiveEvent was already fired in the onHide we need to suppress it here\n if (!resetNavigationOnShow) {\n sourcePage.onInactiveEvent();\n }\n }\n this.navigationStack = [];\n this.animateNavigation(rootPage, sourcePage, resetNavigationOnShow);\n this.activePage = rootPage;\n this.updateActivePageClass();\n }\n\n private navigateToPage(\n targetPage: SettingsPanelPage,\n sourcePage: SettingsPanelPage,\n direction: NavigationDirection,\n skipAnimation: boolean,\n ): void {\n this.activePage = targetPage;\n\n if (direction === NavigationDirection.Forwards) {\n this.navigationStack.push(targetPage);\n } else {\n this.navigationStack.pop();\n }\n\n this.animateNavigation(targetPage, sourcePage, skipAnimation);\n\n this.updateActivePageClass();\n targetPage.onActiveEvent();\n sourcePage.onInactiveEvent();\n }\n\n /**\n * @param targetPage\n * @param sourcePage\n * @param skipAnimation This is just an internal flag if we want to have an animation. It is set true when we reset\n * the navigation within the onShow callback of the settingsPanel. In this case we don't want an actual animation but\n * the recalculation of the dimension of the settingsPanel.\n * This is independent of the pageTransitionAnimation flag.\n */\n private animateNavigation(targetPage: SettingsPanelPage, sourcePage: SettingsPanelPage, skipAnimation: boolean) {\n if (!(this.config as SettingsPanelConfig).pageTransitionAnimation) {\n return;\n }\n\n const settingsPanelDomElement = this.getDomElement();\n const settingsPanelHTMLElement = this.getDomElement().get(0);\n\n // get current dimension\n const settingsPanelWidth = settingsPanelHTMLElement.scrollWidth;\n const settingsPanelHeight = settingsPanelHTMLElement.scrollHeight;\n\n // calculate target size of the settings panel\n sourcePage.getDomElement().css('display', 'none');\n this.getDomElement().css({ width: '', height: '' }); // let css auto settings kick in again\n\n const targetPageHtmlElement = targetPage.getDomElement().get(0);\n // clone the targetPage DOM element so that we can calculate the width / height how they will be after\n // switching the page. We are using a clone to prevent (mostly styling) side-effects on the real DOM element\n const clone = targetPageHtmlElement.cloneNode(true) as HTMLElement;\n // append to parent so we get the 'real' size\n const containerWrapper = targetPageHtmlElement.parentNode;\n containerWrapper.appendChild(clone);\n // set clone visible\n clone.style.display = 'block';\n\n // collect target dimension\n const targetSettingsPanelWidth = settingsPanelHTMLElement.scrollWidth;\n const targetSettingsPanelHeight = settingsPanelHTMLElement.scrollHeight;\n\n // remove clone from the DOM\n clone.parentElement.removeChild(clone); // .remove() is not working in IE\n sourcePage.getDomElement().css('display', '');\n\n // set the values back to the current ones that the browser animates it (browsers don't animate 'auto' values)\n settingsPanelDomElement.css({\n width: settingsPanelWidth + 'px',\n height: settingsPanelHeight + 'px',\n });\n\n if (!skipAnimation) {\n // We need to force the browser to reflow between setting the width and height that we actually get a animation\n this.forceBrowserReflow();\n }\n\n // set the values to the target dimension\n settingsPanelDomElement.css({\n width: targetSettingsPanelWidth + 'px',\n height: targetSettingsPanelHeight + 'px',\n });\n }\n\n private forceBrowserReflow(): void {\n // Force the browser to reflow the layout\n // https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n this.getDomElement().get(0).offsetLeft;\n }\n\n /**\n * Workaround for IE, Firefox and Safari\n * when the settings panel fades out while an item of a select box is still hovered, the select box will not fade out\n * while the settings panel does. This would leave a floating select box, which is just weird\n */\n private hideHoveredSelectBoxes(): void {\n this.getComputedItems()\n .map(item => item['setting'])\n .filter(component => component instanceof SelectBox)\n .forEach((selectBox: SelectBox) => selectBox.closeDropdown());\n }\n\n // collect all items from all pages (see hideHoveredSelectBoxes)\n private getComputedItems(): SettingsPanelItem[] {\n const allItems: SettingsPanelItem[] = [];\n for (let page of this.getPages()) {\n allItems.push(...page.getItems());\n }\n return allItems;\n }\n\n private getRootPage(): SettingsPanelPage {\n return this.getPages()[0];\n }\n\n protected onSettingsStateChangedEvent() {\n this.settingsPanelEvents.onSettingsStateChanged.dispatch(this);\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {Component, ComponentConfig} from './component';\nimport {Event, EventDispatcher, NoArgs} from '../eventdispatcher';\nimport { Label, LabelConfig } from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {SelectBox} from './selectbox';\nimport {ListBox} from './listbox';\nimport {VideoQualitySelectBox} from './videoqualityselectbox';\nimport {AudioQualitySelectBox} from './audioqualityselectbox';\nimport {PlaybackSpeedSelectBox} from './playbackspeedselectbox';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { LocalizableText } from '../localization/i18n';\n\n/**\n * An item for a {@link SettingsPanelPage},\n * Containing an optional {@link Label} and a component that configures a setting.\n * If the components is a {@link SelectBox} it will handle the logic of displaying it or not\n *\n * @category Components\n */\nexport class SettingsPanelItem extends Container<ContainerConfig> {\n\n private label: Component<ComponentConfig>;\n private setting: Component<ComponentConfig>;\n\n private settingsPanelItemEvents = {\n onActiveChanged: new EventDispatcher<SettingsPanelItem, NoArgs>(),\n };\n\n constructor(label: LocalizableText | Component<ComponentConfig>, setting: Component<ComponentConfig>, config: ContainerConfig = {}) {\n super(config);\n\n this.setting = setting;\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settings-panel-item',\n role: 'menuitem',\n }, this.config);\n\n if (label !== null) {\n if (label instanceof Component) {\n this.label = label;\n } else {\n this.label = new Label({ text: label, for: this.setting.getConfig().id } as LabelConfig);\n }\n this.addComponent(this.label);\n }\n\n this.addComponent(this.setting);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n if (this.setting instanceof SelectBox || this.setting instanceof ListBox) {\n let handleConfigItemChanged = () => {\n if (!(this.setting instanceof SelectBox) && !(this.setting instanceof ListBox)) {\n return;\n }\n // The minimum number of items that must be available for the setting to be displayed\n // By default, at least two items must be available, else a selection is not possible\n let minItemsToDisplay = 2;\n // Audio/video quality select boxes contain an additional 'auto' mode, which in combination with a single\n // available quality also does not make sense\n if ((this.setting instanceof VideoQualitySelectBox && this.setting.hasAutoItem())\n || this.setting instanceof AudioQualitySelectBox) {\n minItemsToDisplay = 3;\n }\n\n if (this.setting.itemCount() < minItemsToDisplay) {\n // Hide the setting if no meaningful choice is available\n this.hide();\n } else if (this.setting instanceof PlaybackSpeedSelectBox\n && !uimanager.getConfig().playbackSpeedSelectionEnabled) {\n // Hide the PlaybackSpeedSelectBox if disabled in config\n this.hide();\n } else {\n this.show();\n }\n\n // Visibility might have changed and therefore the active state might have changed so we fire the event\n // TODO fire only when state has really changed (e.g. check if visibility has really changed)\n this.onActiveChangedEvent();\n\n this.getDomElement().attr('aria-haspopup', 'true');\n };\n\n this.setting.onItemAdded.subscribe(handleConfigItemChanged);\n this.setting.onItemRemoved.subscribe(handleConfigItemChanged);\n\n // Initialize hidden state\n handleConfigItemChanged();\n }\n }\n\n /**\n * Checks if this settings panel item is active, i.e. visible and enabled and a user can interact with it.\n * @returns {boolean} true if the panel is active, else false\n */\n isActive(): boolean {\n return this.isShown();\n }\n\n protected onActiveChangedEvent() {\n this.settingsPanelItemEvents.onActiveChanged.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the 'active' state of this item changes.\n * @see #isActive\n * @returns {Event<SettingsPanelItem, NoArgs>}\n */\n get onActiveChanged(): Event<SettingsPanelItem, NoArgs> {\n return this.settingsPanelItemEvents.onActiveChanged.getEvent();\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {SettingsPanelItem} from './settingspanelitem';\nimport {UIInstanceManager} from '../uimanager';\nimport {Event, EventDispatcher, NoArgs} from '../eventdispatcher';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { BrowserUtils } from '../browserutils';\n\n/**\n * A panel containing a list of {@link SettingsPanelItem items} that represent labelled settings.\n *\n * @category Components\n */\nexport class SettingsPanelPage extends Container<ContainerConfig> {\n\n private static readonly CLASS_LAST = 'last';\n\n private settingsPanelPageEvents = {\n onSettingsStateChanged: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n onActive: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n onInactive: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n };\n\n constructor(config: ContainerConfig) {\n super(config);\n\n this.config = this.mergeConfig<ContainerConfig>(config, {\n cssClass: 'ui-settings-panel-page',\n role: 'menu',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n // Fire event when the state of a settings-item has changed\n let settingsStateChangedHandler = () => {\n this.onSettingsStateChangedEvent();\n\n // Attach marker class to last visible item\n let lastShownItem = null;\n for (let component of this.getItems()) {\n component.getDomElement().removeClass(this.prefixCss(SettingsPanelPage.CLASS_LAST));\n if (component.isShown()) {\n lastShownItem = component;\n }\n }\n if (lastShownItem) {\n lastShownItem.getDomElement().addClass(this.prefixCss(SettingsPanelPage.CLASS_LAST));\n }\n };\n for (let component of this.getItems()) {\n component.onActiveChanged.subscribe(settingsStateChangedHandler);\n }\n }\n\n hasActiveSettings(): boolean {\n for (let component of this.getItems()) {\n if (component.isActive()) {\n return true;\n }\n }\n\n return false;\n }\n\n getItems(): SettingsPanelItem[] {\n return <SettingsPanelItem[]>this.config.components.filter(component => component instanceof SettingsPanelItem);\n }\n\n onSettingsStateChangedEvent() {\n this.settingsPanelPageEvents.onSettingsStateChanged.dispatch(this);\n }\n\n get onSettingsStateChanged(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onSettingsStateChanged.getEvent();\n }\n\n onActiveEvent() {\n const activeItems = this.getItems().filter((item) => item.isActive());\n\n this.settingsPanelPageEvents.onActive.dispatch(this);\n // Disable focus for iOS and iPadOS 13. They open select boxes automatically on focus and we want to avoid that.\n if (activeItems.length > 0 && !BrowserUtils.isIOS && !(BrowserUtils.isMacIntel && BrowserUtils.isTouchSupported)) {\n activeItems[0].getDomElement().focusToFirstInput();\n }\n }\n\n get onActive(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onActive.getEvent();\n }\n\n onInactiveEvent() {\n this.settingsPanelPageEvents.onInactive.dispatch(this);\n }\n\n get onInactive(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onInactive.getEvent();\n }\n}\n","import {UIInstanceManager} from '../uimanager';\nimport {SettingsPanelPageNavigatorButton, SettingsPanelPageNavigatorConfig} from './settingspanelpagenavigatorbutton';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * @category Buttons\n */\nexport class SettingsPanelPageBackButton extends SettingsPanelPageNavigatorButton {\n\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingspanelpagebackbutton',\n text: 'back',\n } as SettingsPanelPageNavigatorConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n this.popPage();\n });\n }\n}\n","import {Button, ButtonConfig} from './button';\nimport {SettingsPanel} from './settingspanel';\nimport {SettingsPanelPage} from './settingspanelpage';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\n\n/**\n * Configuration interface for a {@link SettingsPanelPageNavigatorButton}\n *\n * @category Configs\n */\nexport interface SettingsPanelPageNavigatorConfig extends ButtonConfig {\n /**\n * Container `SettingsPanel` where the navigation takes place\n */\n container: SettingsPanel;\n /**\n * Page where the button should navigate to\n * If empty it will navigate to the root page (not intended to use as navigate back behavior)\n */\n targetPage?: SettingsPanelPage;\n\n /**\n * WCAG20 standard: Establishes relationships between objects and their label(s)\n */\n ariaLabelledBy?: string;\n}\n\n/**\n * Can be used to navigate between SettingsPanelPages\n *\n * Example:\n * let settingPanelNavigationButton = new SettingsPanelPageNavigatorButton({\n * container: settingsPanel,\n * targetPage: settingsPanelPage,\n * });\n *\n * settingsPanelPage.addComponent(settingPanelNavigationButton);\n *\n * Don't forget to add the settingPanelNavigationButton to the settingsPanelPage.\n *\n * @category Buttons\n */\nexport class SettingsPanelPageNavigatorButton extends Button<SettingsPanelPageNavigatorConfig> {\n private readonly container: SettingsPanel;\n private readonly targetPage?: SettingsPanelPage;\n\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n this.config = this.mergeConfig(config, {} as SettingsPanelPageNavigatorConfig, this.config);\n\n this.container = (this.config as SettingsPanelPageNavigatorConfig).container;\n this.targetPage = (this.config as SettingsPanelPageNavigatorConfig).targetPage;\n }\n\n /**\n * navigate one level back\n */\n popPage() {\n this.container.popSettingsPanelPage();\n }\n\n /**\n * navigate to the target page\n */\n pushTargetPage() {\n this.container.setActivePage(this.targetPage);\n }\n}\n","import {UIInstanceManager} from '../uimanager';\nimport {SettingsPanelPageNavigatorButton, SettingsPanelPageNavigatorConfig} from './settingspanelpagenavigatorbutton';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Buttons\n */\nexport class SettingsPanelPageOpenButton extends SettingsPanelPageNavigatorButton {\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingspanelpageopenbutton',\n text: i18n.getLocalizer('open'),\n role: 'menuitem',\n } as SettingsPanelPageNavigatorConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.getDomElement().attr('aria-haspopup', 'true');\n this.getDomElement().attr('aria-owns', this.config.targetPage.getConfig().id);\n\n this.onClick.subscribe(() => {\n this.pushTargetPage();\n });\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {SettingsPanel} from './settingspanel';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport {ArrayUtils} from '../arrayutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link SettingsToggleButton}.\n *\n * @category Configs\n */\nexport interface SettingsToggleButtonConfig extends ToggleButtonConfig {\n /**\n * The settings panel whose visibility the button should toggle.\n */\n settingsPanel: SettingsPanel;\n\n /**\n * Decides if the button should be automatically hidden when the settings panel does not contain any active settings.\n * Default: true\n */\n autoHideWhenNoActiveSettings?: boolean;\n}\n\n/**\n * A button that toggles visibility of a settings panel.\n *\n * @category Buttons\n */\nexport class SettingsToggleButton extends ToggleButton<SettingsToggleButtonConfig> {\n\n private visibleSettingsPanels: SettingsPanel[] = [];\n\n constructor(config: SettingsToggleButtonConfig) {\n super(config);\n\n if (!config.settingsPanel) {\n throw new Error('Required SettingsPanel is missing');\n }\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingstogglebutton',\n text: i18n.getLocalizer('settings'),\n settingsPanel: null,\n autoHideWhenNoActiveSettings: true,\n role: 'pop-up button',\n }, <SettingsToggleButtonConfig>this.config);\n\n /**\n * WCAG20 standard defines which popup menu (element id) is owned by the button\n */\n this.getDomElement().attr('aria-owns', config.settingsPanel.getActivePage().getConfig().id);\n\n /**\n * WCAG20 standard defines that a button has a popup menu bound to it\n */\n this.getDomElement().attr('aria-haspopup', 'true');\n\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let settingsPanel = config.settingsPanel;\n\n this.onClick.subscribe(() => {\n // only hide other `SettingsPanel`s if a new one will be opened\n if (!settingsPanel.isShown()) {\n // Hide all open SettingsPanels before opening this button's panel\n // (We need to iterate a copy because hiding them will automatically remove themselves from the array\n // due to the subscribeOnce above)\n this.visibleSettingsPanels.slice().forEach(settingsPanel => settingsPanel.hide());\n }\n settingsPanel.toggleHidden();\n });\n settingsPanel.onShow.subscribe(() => {\n // Set toggle status to on when the settings panel shows\n this.on();\n });\n settingsPanel.onHide.subscribe(() => {\n // Set toggle status to off when the settings panel hides\n this.off();\n });\n\n // Ensure that only one `SettingPanel` is visible at once\n // Keep track of shown SettingsPanels\n uimanager.onComponentShow.subscribe((sender: Component<ComponentConfig>) => {\n if (sender instanceof SettingsPanel) {\n this.visibleSettingsPanels.push(sender);\n sender.onHide.subscribeOnce(() => ArrayUtils.remove(this.visibleSettingsPanels, sender));\n }\n });\n\n // Handle automatic hiding of the button if there are no settings for the user to interact with\n if (config.autoHideWhenNoActiveSettings) {\n // Setup handler to show/hide button when the settings change\n let settingsPanelItemsChangedHandler = () => {\n if (settingsPanel.rootPageHasActiveSettings()) {\n if (this.isHidden()) {\n this.show();\n }\n } else {\n if (this.isShown()) {\n this.hide();\n }\n }\n };\n // Wire the handler to the event\n settingsPanel.onSettingsStateChanged.subscribe(settingsPanelItemsChangedHandler);\n // Call handler for first init at startup\n settingsPanelItemsChangedHandler();\n }\n }\n}\n","import {Component, ComponentConfig} from './component';\n\n/**\n * A dummy component that just reserves some space and does nothing else.\n *\n * @category Components\n */\nexport class Spacer extends Component<ComponentConfig> {\n\n constructor(config: ComponentConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-spacer',\n }, this.config);\n }\n\n\n protected onShowEvent(): void {\n // disable event firing by overwriting and not calling super\n }\n\n protected onHideEvent(): void {\n // disable event firing by overwriting and not calling super\n }\n\n protected onHoverChangedEvent(hovered: boolean): void {\n // disable event firing by overwriting and not calling super\n }\n}","import {ListBox} from './listbox';\nimport {UIInstanceManager} from '../uimanager';\nimport {SubtitleSwitchHandler} from '../subtitleutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A element that is similar to a select box where the user can select a subtitle\n *\n * @category Components\n */\nexport class SubtitleListBox extends ListBox {\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new SubtitleSwitchHandler(player, this, uimanager);\n }\n}\n","import { Container, ContainerConfig } from './container';\nimport { UIInstanceManager } from '../uimanager';\nimport { Label, LabelConfig } from './label';\nimport { ComponentConfig, Component } from './component';\nimport { ControlBar } from './controlbar';\nimport { EventDispatcher } from '../eventdispatcher';\nimport { DOM, Size } from '../dom';\nimport { PlayerAPI, SubtitleCueEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { VttUtils } from '../vttutils';\nimport { VTTProperties } from 'bitmovin-player/types/subtitles/vtt/API';\n\ninterface SubtitleCropDetectionResult {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n}\n\n/**\n * Overlays the player to display subtitles.\n *\n * @category Components\n */\nexport class SubtitleOverlay extends Container<ContainerConfig> {\n\n private subtitleManager: ActiveSubtitleManager;\n private previewSubtitleActive: boolean;\n private previewSubtitle: SubtitleLabel;\n\n private preprocessLabelEventCallback = new EventDispatcher<SubtitleCueEvent, SubtitleLabel>();\n private subtitleContainerManager: SubtitleRegionContainerManager;\n\n private static readonly CLASS_CONTROLBAR_VISIBLE = 'controlbar-visible';\n private static readonly CLASS_CEA_608 = 'cea608';\n\n // The number of rows in a cea608 grid\n private static readonly CEA608_NUM_ROWS = 15;\n // The number of columns in a cea608 grid\n private static readonly CEA608_NUM_COLUMNS = 32;\n // The offset in percent for one row (which is also the height of a row)\n private static readonly CEA608_ROW_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_ROWS;\n // The offset in percent for one column (which is also the width of a column)\n private static readonly CEA608_COLUMN_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_COLUMNS;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.previewSubtitleActive = false;\n this.previewSubtitle = new SubtitleLabel({ text: i18n.getLocalizer('subtitle.example') });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitle-overlay',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let subtitleManager = new ActiveSubtitleManager();\n this.subtitleManager = subtitleManager;\n\n this.subtitleContainerManager = new SubtitleRegionContainerManager(this);\n\n player.on(player.exports.PlayerEvent.CueEnter, (event: SubtitleCueEvent) => {\n const label = this.generateLabel(event);\n subtitleManager.cueEnter(event, label);\n\n this.preprocessLabelEventCallback.dispatch(event, label);\n\n if (this.previewSubtitleActive) {\n this.subtitleContainerManager.removeLabel(this.previewSubtitle);\n }\n\n this.show();\n\n this.subtitleContainerManager.addLabel(label, this.getDomElement().size());\n this.updateComponents();\n\n if (uimanager.getConfig().forceSubtitlesIntoViewContainer) {\n this.handleSubtitleCropping(label);\n }\n });\n\n player.on(player.exports.PlayerEvent.CueUpdate, (event: SubtitleCueEvent) => {\n const label = this.generateLabel(event);\n const labelToReplace = subtitleManager.cueUpdate(event, label);\n\n this.preprocessLabelEventCallback.dispatch(event, label);\n\n if (labelToReplace) {\n this.subtitleContainerManager.replaceLabel(labelToReplace, label);\n }\n\n if (uimanager.getConfig().forceSubtitlesIntoViewContainer) {\n this.handleSubtitleCropping(label);\n }\n });\n\n player.on(player.exports.PlayerEvent.CueExit, (event: SubtitleCueEvent) => {\n let labelToRemove = subtitleManager.cueExit(event);\n\n if (labelToRemove) {\n this.subtitleContainerManager.removeLabel(labelToRemove);\n this.updateComponents();\n }\n\n if (!subtitleManager.hasCues) {\n if (!this.previewSubtitleActive) {\n this.hide();\n } else {\n this.subtitleContainerManager.addLabel(this.previewSubtitle);\n this.updateComponents();\n }\n }\n });\n\n let subtitleClearHandler = () => {\n this.hide();\n this.subtitleContainerManager.clear();\n subtitleManager.clear();\n this.removeComponents();\n this.updateComponents();\n };\n\n const clearInactiveCues = () => {\n const removedActiveCues = subtitleManager.clearInactiveCues(player.getCurrentTime());\n removedActiveCues.forEach(toRemove => {\n this.subtitleContainerManager.removeLabel(toRemove.label);\n });\n };\n\n player.on(player.exports.PlayerEvent.AudioChanged, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.SubtitleDisabled, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.Seeked, clearInactiveCues);\n player.on(player.exports.PlayerEvent.TimeShifted, clearInactiveCues);\n player.on(player.exports.PlayerEvent.PlaybackFinished, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.SourceUnloaded, subtitleClearHandler);\n\n uimanager.onComponentShow.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof ControlBar) {\n this.getDomElement().addClass(this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE));\n }\n });\n uimanager.onComponentHide.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof ControlBar) {\n this.getDomElement().removeClass(this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE));\n }\n });\n\n this.configureCea608Captions(player, uimanager);\n // Init\n subtitleClearHandler();\n }\n\n detectCroppedSubtitleLabel(\n labelElement: HTMLElement,\n ): SubtitleCropDetectionResult {\n const parent = this.getDomElement().get(0);\n\n const childRect = labelElement.getBoundingClientRect();\n const parentRect = parent.getBoundingClientRect();\n\n return {\n top: childRect.top < parentRect.top,\n right: childRect.right > parentRect.right,\n bottom: childRect.bottom > parentRect.bottom,\n left: childRect.left < parentRect.left,\n };\n }\n\n handleSubtitleCropping(label: SubtitleLabel) {\n const labelDomElement = label.getDomElement();\n const cropDetection = this.detectCroppedSubtitleLabel(\n labelDomElement.get(0),\n );\n\n if (cropDetection.top) {\n labelDomElement.css('top', '0');\n labelDomElement.removeCss('bottom');\n }\n\n if (cropDetection.right) {\n labelDomElement.css('right', '0');\n labelDomElement.removeCss('left');\n }\n\n if (cropDetection.bottom) {\n labelDomElement.css('bottom', '0');\n labelDomElement.removeCss('top');\n }\n\n if (cropDetection.left) {\n labelDomElement.css('left', '0');\n labelDomElement.removeCss('right');\n }\n }\n\n generateLabel(event: SubtitleCueEvent): SubtitleLabel {\n // Sanitize cue data (must be done before the cue ID is generated in subtitleManager.cueEnter / update)\n if (event.position) {\n // Sometimes the positions are undefined, we assume them to be zero\n event.position.row = event.position.row || 0;\n event.position.column = event.position.column || 0;\n }\n\n const label = new SubtitleLabel({\n // Prefer the HTML subtitle text if set, else try generating a image tag as string from the image attribute,\n // else use the plain text\n text: event.html || ActiveSubtitleManager.generateImageTagText(event.image) || event.text,\n vtt: event.vtt,\n region: event.region,\n regionStyle: event.regionStyle,\n });\n\n return label;\n }\n\n configureCea608Captions(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // The calculated font size\n let fontSize = 0;\n // The required letter spacing spread the text characters evenly across the grid\n let fontLetterSpacing = 0;\n // Flag telling if a font size calculation is required of if the current values are valid\n let fontSizeCalculationRequired = true;\n // Flag telling if the CEA-608 mode is enabled\n let enabled = false;\n\n const updateCEA608FontSize = () => {\n const dummyLabel = new SubtitleLabel({ text: 'X' });\n dummyLabel.getDomElement().css({\n // By using a large font size we do not need to use multiple letters and can get still an\n // accurate measurement even though the returned size is an integer value\n 'font-size': '200px',\n 'line-height': '200px',\n 'visibility': 'hidden',\n });\n this.addComponent(dummyLabel);\n this.updateComponents();\n this.show();\n\n const dummyLabelCharWidth = dummyLabel.getDomElement().width();\n const dummyLabelCharHeight = dummyLabel.getDomElement().height();\n const fontSizeRatio = dummyLabelCharWidth / dummyLabelCharHeight;\n\n this.removeComponent(dummyLabel);\n this.updateComponents();\n if (!this.subtitleManager.hasCues) {\n this.hide();\n }\n\n // We subtract 1px here to avoid line breaks at the right border of the subtitle overlay that can happen\n // when texts contain whitespaces. It's probably some kind of pixel rounding issue in the browser's\n // layouting, but the actual reason could not be determined. Aiming for a target width - 1px would work in\n // most browsers, but Safari has a \"quantized\" font size rendering with huge steps in between so we need\n // to subtract some more pixels to avoid line breaks there as well.\n const subtitleOverlayWidth = this.getDomElement().width() - 10;\n const subtitleOverlayHeight = this.getDomElement().height();\n\n // The size ratio of the letter grid\n const fontGridSizeRatio = (dummyLabelCharWidth * SubtitleOverlay.CEA608_NUM_COLUMNS) /\n (dummyLabelCharHeight * SubtitleOverlay.CEA608_NUM_ROWS);\n // The size ratio of the available space for the grid\n const subtitleOverlaySizeRatio = subtitleOverlayWidth / subtitleOverlayHeight;\n\n if (subtitleOverlaySizeRatio > fontGridSizeRatio) {\n // When the available space is wider than the text grid, the font size is simply\n // determined by the height of the available space.\n fontSize = subtitleOverlayHeight / SubtitleOverlay.CEA608_NUM_ROWS;\n\n // Calculate the additional letter spacing required to evenly spread the text across the grid's width\n const gridSlotWidth = subtitleOverlayWidth / SubtitleOverlay.CEA608_NUM_COLUMNS;\n const fontCharWidth = fontSize * fontSizeRatio;\n fontLetterSpacing = gridSlotWidth - fontCharWidth;\n } else {\n // When the available space is not wide enough, texts would vertically overlap if we take\n // the height as a base for the font size, so we need to limit the height. We do that\n // by determining the font size by the width of the available space.\n fontSize = subtitleOverlayWidth / SubtitleOverlay.CEA608_NUM_COLUMNS / fontSizeRatio;\n fontLetterSpacing = 0;\n }\n\n // Update font-size of all active subtitle labels\n for (let label of this.getComponents()) {\n if (label instanceof SubtitleLabel) {\n label.getDomElement().css({\n 'font-size': `${fontSize}px`,\n 'letter-spacing': `${fontLetterSpacing}px`,\n });\n }\n }\n };\n\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n if (enabled) {\n updateCEA608FontSize();\n } else {\n fontSizeCalculationRequired = true;\n }\n });\n\n this.preprocessLabelEventCallback.subscribe((event: SubtitleCueEvent, label: SubtitleLabel) => {\n const isCEA608 = event.position != null;\n if (!isCEA608) {\n // Skip all non-CEA608 cues\n return;\n }\n\n if (!enabled) {\n enabled = true;\n this.getDomElement().addClass(this.prefixCss(SubtitleOverlay.CLASS_CEA_608));\n\n // We conditionally update the font size by this flag here to avoid updating every time a subtitle\n // is added into an empty overlay. Because we reset the overlay when all subtitles are gone, this\n // would trigger an unnecessary update every time, but it's only required under certain conditions,\n // e.g. after the player size has changed.\n if (fontSizeCalculationRequired) {\n updateCEA608FontSize();\n fontSizeCalculationRequired = false;\n }\n }\n\n label.getDomElement().css({\n 'left': `${event.position.column * SubtitleOverlay.CEA608_COLUMN_OFFSET}%`,\n 'top': `${event.position.row * SubtitleOverlay.CEA608_ROW_OFFSET}%`,\n 'font-size': `${fontSize}px`,\n 'letter-spacing': `${fontLetterSpacing}px`,\n });\n });\n\n const reset = () => {\n this.getDomElement().removeClass(this.prefixCss(SubtitleOverlay.CLASS_CEA_608));\n enabled = false;\n };\n\n player.on(player.exports.PlayerEvent.CueExit, () => {\n if (!this.subtitleManager.hasCues) {\n // Disable CEA-608 mode when all subtitles are gone (to allow correct formatting and\n // display of other types of subtitles, e.g. the formatting preview subtitle)\n reset();\n }\n });\n\n player.on(player.exports.PlayerEvent.SourceUnloaded, reset);\n player.on(player.exports.PlayerEvent.SubtitleEnabled, reset);\n player.on(player.exports.PlayerEvent.SubtitleDisabled, reset);\n }\n\n enablePreviewSubtitleLabel(): void {\n if (!this.subtitleManager.hasCues) {\n this.previewSubtitleActive = true;\n this.subtitleContainerManager.addLabel(this.previewSubtitle);\n this.updateComponents();\n this.show();\n }\n }\n\n removePreviewSubtitleLabel(): void {\n if (this.previewSubtitleActive) {\n this.previewSubtitleActive = false;\n this.subtitleContainerManager.removeLabel(this.previewSubtitle);\n this.updateComponents();\n }\n }\n}\n\ninterface ActiveSubtitleCue {\n event: SubtitleCueEvent;\n label: SubtitleLabel;\n}\n\ninterface ActiveSubtitleCueMap {\n [id: string]: ActiveSubtitleCue[];\n}\n\ninterface SubtitleLabelConfig extends LabelConfig {\n vtt?: VTTProperties;\n region?: string;\n regionStyle?: string;\n}\n\nexport class SubtitleLabel extends Label<SubtitleLabelConfig> {\n\n constructor(config: SubtitleLabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitle-label',\n }, this.config);\n }\n\n get vtt(): VTTProperties {\n return this.config.vtt;\n }\n\n get region(): string {\n return this.config.region;\n }\n\n get regionStyle(): string {\n return this.config.regionStyle;\n }\n}\n\nclass ActiveSubtitleManager {\n\n private activeSubtitleCueMap: ActiveSubtitleCueMap;\n private activeSubtitleCueCount: number;\n\n constructor() {\n this.activeSubtitleCueMap = {};\n this.activeSubtitleCueCount = 0;\n }\n\n /**\n * Calculates a unique ID for a subtitle cue, which is needed to associate an CueEnter with its CueExit\n * event so we can remove the correct subtitle in CueExit when multiple subtitles are active at the same time.\n * The start time plus the text should make a unique identifier, and in the only case where a collision\n * can happen, two similar texts will be displayed at a similar time and a similar position (or without position).\n * The start time should always be known, because it is required to schedule the CueEnter event. The end time\n * must not necessarily be known and therefore cannot be used for the ID.\n * @param event\n * @return {string}\n */\n private static calculateId(event: SubtitleCueEvent): string {\n let id = event.start + '-' + event.text;\n\n if (event.position) {\n id += '-' + event.position.row + '-' + event.position.column;\n }\n\n return id;\n }\n\n cueEnter(event: SubtitleCueEvent, label: SubtitleLabel): void {\n this.addCueToMap(event, label);\n }\n\n cueUpdate(event: SubtitleCueEvent, label: SubtitleLabel): SubtitleLabel | undefined {\n const labelToReplace = this.popCueFromMap(event);\n\n if (labelToReplace) {\n this.addCueToMap(event, label);\n return labelToReplace;\n }\n\n return undefined;\n }\n\n private addCueToMap(event: SubtitleCueEvent, label: SubtitleLabel): void {\n let id = ActiveSubtitleManager.calculateId(event);\n\n // Create array for id if it does not exist\n this.activeSubtitleCueMap[id] = this.activeSubtitleCueMap[id] || [];\n\n // Add cue\n this.activeSubtitleCueMap[id].push({ event, label });\n this.activeSubtitleCueCount++;\n }\n\n private popCueFromMap(event: SubtitleCueEvent): SubtitleLabel | undefined {\n let id = ActiveSubtitleManager.calculateId(event);\n let activeSubtitleCues = this.activeSubtitleCueMap[id];\n\n if (activeSubtitleCues && activeSubtitleCues.length > 0) {\n // Remove cue\n /* We apply the FIFO approach here and remove the oldest cue from the associated id. When there are multiple cues\n * with the same id, there is no way to know which one of the cues is to be deleted, so we just hope that FIFO\n * works fine. Theoretically it can happen that two cues with colliding ids are removed at different times, in\n * the wrong order. This rare case has yet to be observed. If it ever gets an issue, we can take the unstable\n * cue end time (which can change between CueEnter and CueExit IN CueUpdate) and use it as an\n * additional hint to try and remove the correct one of the colliding cues.\n */\n let activeSubtitleCue = activeSubtitleCues.shift();\n this.activeSubtitleCueCount--;\n\n return activeSubtitleCue.label;\n }\n }\n\n /**\n * Removes all active cues which don't enclose the given time\n * @param time the time for which subtitles should remain\n */\n public clearInactiveCues(time: number): ActiveSubtitleCue[] {\n const removedCues: ActiveSubtitleCue[] = [];\n Object.keys(this.activeSubtitleCueMap).forEach(key => {\n const activeCues = this.activeSubtitleCueMap[key];\n activeCues.forEach(cue => {\n if (time < cue.event.start || time > cue.event.end) {\n this.popCueFromMap(cue.event);\n removedCues.push(cue);\n }\n });\n });\n return removedCues;\n }\n\n static generateImageTagText(imageData: string): string | undefined {\n if (!imageData) {\n return;\n }\n\n const imgTag = new DOM('img', {\n src: imageData,\n });\n imgTag.css('width', '100%');\n return imgTag.get(0).outerHTML; // return the html as string\n }\n\n /**\n * Returns the label associated with an already added cue.\n * @param event\n * @return {SubtitleLabel}\n */\n getCues(event: SubtitleCueEvent): SubtitleLabel[] | undefined {\n let id = ActiveSubtitleManager.calculateId(event);\n let activeSubtitleCues = this.activeSubtitleCueMap[id];\n if (activeSubtitleCues && activeSubtitleCues.length > 0) {\n return activeSubtitleCues.map((cue) => cue.label);\n }\n }\n\n /**\n * Removes the subtitle cue from the manager and returns the label that should be removed from the subtitle overlay,\n * or null if there is no associated label existing (e.g. because all labels have been {@link #clear cleared}.\n * @param event\n * @return {SubtitleLabel|null}\n */\n cueExit(event: SubtitleCueEvent): SubtitleLabel {\n return this.popCueFromMap(event);\n }\n\n /**\n * Returns the number of active subtitle cues.\n * @return {number}\n */\n get cueCount(): number {\n // We explicitly count the cues to save an Array.reduce on every cueCount call (which can happen frequently)\n return this.activeSubtitleCueCount;\n }\n\n /**\n * Returns true if there are active subtitle cues, else false.\n * @return {boolean}\n */\n get hasCues(): boolean {\n return this.cueCount > 0;\n }\n\n /**\n * Removes all subtitle cues from the manager.\n */\n clear(): void {\n this.activeSubtitleCueMap = {};\n this.activeSubtitleCueCount = 0;\n }\n}\n\nexport class SubtitleRegionContainerManager {\n private subtitleRegionContainers: { [regionName: string]: SubtitleRegionContainer } = {};\n\n /**\n * @param subtitleOverlay Reference to the subtitle overlay for adding and removing the containers.\n */\n constructor(private subtitleOverlay: SubtitleOverlay) {\n this.subtitleOverlay = subtitleOverlay;\n }\n\n private getRegion(label: SubtitleLabel): { regionContainerId: string, regionName: string } {\n if (label.vtt) {\n return {\n regionContainerId: label.vtt.region && label.vtt.region.id ? label.vtt.region.id : 'vtt',\n regionName: 'vtt',\n };\n }\n\n return {\n regionContainerId: label.region || 'default',\n regionName: label.region || 'default',\n };\n }\n\n /**\n * Creates and wraps a subtitle label into a container div based on the subtitle region.\n * If the subtitle has positioning information it is added to the container.\n * @param label The subtitle label to wrap\n */\n addLabel(label: SubtitleLabel, overlaySize?: Size): void {\n const { regionContainerId, regionName } = this.getRegion(label);\n const cssClasses = [`subtitle-position-${regionName}`];\n\n if (label.vtt && label.vtt.region) {\n cssClasses.push(`vtt-region-${label.vtt.region.id}`);\n }\n\n if (!this.subtitleRegionContainers[regionContainerId]) {\n const regionContainer = new SubtitleRegionContainer({\n cssClasses,\n });\n\n this.subtitleRegionContainers[regionContainerId] = regionContainer;\n\n if (label.regionStyle) {\n regionContainer.getDomElement().attr('style', label.regionStyle);\n } else if (label.vtt && !label.vtt.region) {\n /**\n * If there is no region present to wrap the Cue Box, the Cue box becomes the\n * region itself. Therefore the positioning values have to come from the box.\n */\n regionContainer.getDomElement().css('position', 'static');\n } else {\n // getDomElement needs to be called at least once to ensure the component exists\n regionContainer.getDomElement();\n }\n\n for (const regionContainerId in this.subtitleRegionContainers) {\n this.subtitleOverlay.addComponent(this.subtitleRegionContainers[regionContainerId]);\n }\n }\n\n this.subtitleRegionContainers[regionContainerId].addLabel(label, overlaySize);\n }\n\n replaceLabel(previousLabel: SubtitleLabel, newLabel: SubtitleLabel): void {\n const { regionContainerId } = this.getRegion(previousLabel);\n\n this.subtitleRegionContainers[regionContainerId].removeLabel(previousLabel);\n this.subtitleRegionContainers[regionContainerId].addLabel(newLabel);\n }\n\n /**\n * Removes a subtitle label from a container.\n */\n removeLabel(label: SubtitleLabel): void {\n let regionContainerId;\n\n if (label.vtt) {\n regionContainerId = label.vtt.region && label.vtt.region.id ? label.vtt.region.id : 'vtt';\n } else {\n regionContainerId = label.region || 'default';\n }\n\n this.subtitleRegionContainers[regionContainerId].removeLabel(label);\n\n // Remove container if no more labels are displayed\n if (this.subtitleRegionContainers[regionContainerId].isEmpty()) {\n this.subtitleOverlay.removeComponent(this.subtitleRegionContainers[regionContainerId]);\n delete this.subtitleRegionContainers[regionContainerId];\n }\n }\n\n /**\n * Removes all subtitle containers.\n */\n clear(): void {\n for (const regionName in this.subtitleRegionContainers) {\n this.subtitleOverlay.removeComponent(this.subtitleRegionContainers[regionName]);\n }\n\n this.subtitleRegionContainers = {};\n }\n}\n\nexport class SubtitleRegionContainer extends Container<ContainerConfig> {\n private labelCount = 0;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'subtitle-region-container',\n }, this.config);\n }\n\n addLabel(labelToAdd: SubtitleLabel, overlaySize?: Size) {\n this.labelCount++;\n\n if (labelToAdd.vtt) {\n if (labelToAdd.vtt.region && overlaySize) {\n VttUtils.setVttRegionStyles(this, labelToAdd.vtt.region, overlaySize);\n }\n\n VttUtils.setVttCueBoxStyles(labelToAdd, overlaySize);\n }\n\n this.addComponent(labelToAdd);\n this.updateComponents();\n }\n\n removeLabel(labelToRemove: SubtitleLabel): void {\n this.labelCount--;\n this.removeComponent(labelToRemove);\n this.updateComponents();\n }\n\n public isEmpty(): boolean {\n return this.labelCount === 0;\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport {SubtitleSwitchHandler} from '../subtitleutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between available subtitle and caption tracks.\n *\n * @category Components\n */\nexport class SubtitleSelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitleselectbox'],\n ariaLabel: i18n.getLocalizer('subtitle.select'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new SubtitleSwitchHandler(player, this, uimanager);\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background colors.\n *\n * @category Components\n */\nexport class BackgroundColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsbackgroundcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.backgroundColor.isSet() && this.settingsManager.backgroundOpacity.isSet()) {\n this.toggleOverlayClass(\n 'bgcolor-' + this.settingsManager.backgroundColor.value + this.settingsManager.backgroundOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.backgroundColor.value = key;\n });\n\n this.settingsManager.backgroundColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.backgroundColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.backgroundOpacity.clear();\n } else if (!this.settingsManager.backgroundOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.backgroundOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.backgroundOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.backgroundColor.isSet()) {\n this.selectItem(this.settingsManager.backgroundColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background opacity.\n *\n * @category Components\n */\nexport class BackgroundOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsbackgroundopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n this.addItem('0', i18n.getLocalizer('percent', { value: 0 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.backgroundOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.backgroundOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.backgroundColor.clear();\n } else if (!this.settingsManager.backgroundColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.backgroundColor.value = 'black';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.backgroundOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.backgroundOpacity.isSet()) {\n this.selectItem(this.settingsManager.backgroundOpacity.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different character edge.\n *\n * @category Components\n */\nexport class CharacterEdgeSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingscharacteredgeselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('raised', i18n.getLocalizer('settings.subtitles.characterEdge.raised'));\n this.addItem('depressed', i18n.getLocalizer('settings.subtitles.characterEdge.depressed'));\n this.addItem('uniform', i18n.getLocalizer('settings.subtitles.characterEdge.uniform'));\n this.addItem('dropshadowed', i18n.getLocalizer('settings.subtitles.characterEdge.dropshadowed'));\n\n this.settingsManager.characterEdge.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('characteredge-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.characterEdge.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.characterEdge.isSet()) {\n this.selectItem(this.settingsManager.characterEdge.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.fontColor.isSet() && this.settingsManager.fontOpacity.isSet()) {\n this.toggleOverlayClass(\n 'fontcolor-' + this.settingsManager.fontColor.value + this.settingsManager.fontOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontColor.value = key;\n });\n\n this.settingsManager.fontColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.fontColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.fontOpacity.clear();\n } else if (!this.settingsManager.fontOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.fontOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.fontOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.fontColor.isSet()) {\n this.selectItem(this.settingsManager.fontColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font family.\n *\n * @category Components\n */\nexport class FontFamilySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontfamilyselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('monospacedserif', i18n.getLocalizer('settings.subtitles.font.family.monospacedserif'));\n this.addItem('proportionalserif', i18n.getLocalizer('settings.subtitles.font.family.proportionalserif'));\n this.addItem('monospacedsansserif', i18n.getLocalizer('settings.subtitles.font.family.monospacedsansserif'));\n this.addItem('proportionalsansserif', i18n.getLocalizer('settings.subtitles.font.family.proportionalsansserif'));\n this.addItem('casual', i18n.getLocalizer('settings.subtitles.font.family.casual'));\n this.addItem('cursive', i18n.getLocalizer('settings.subtitles.font.family.cursive'));\n this.addItem('smallcapital', i18n.getLocalizer('settings.subtitles.font.family.smallcapital'));\n\n this.settingsManager.fontFamily.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('fontfamily-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontFamily.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.fontFamily.isSet()) {\n this.selectItem(this.settingsManager.fontFamily.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.fontOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.fontColor.clear();\n } else if (!this.settingsManager.fontColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.fontColor.value = 'white';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.fontOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.fontOpacity.isSet()) {\n this.selectItem(this.settingsManager.fontOpacity.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontSizeSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontsizeselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('150', i18n.getLocalizer('percent', { value: 150 }));\n this.addItem('200', i18n.getLocalizer('percent', { value: 200 }));\n this.addItem('300', i18n.getLocalizer('percent', { value: 300 }));\n this.addItem('400', i18n.getLocalizer('percent', { value: 400 }));\n\n this.settingsManager.fontSize.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('fontsize-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontSize.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.fontSize.isSet()) {\n this.selectItem(this.settingsManager.fontSize.value);\n }\n }\n}\n","import {SubtitleOverlay} from '../subtitleoverlay';\nimport {ListSelectorConfig} from '../listselector';\nimport {SelectBox} from '../selectbox';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../../uimanager';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingSelectBoxConfig extends ListSelectorConfig {\n overlay: SubtitleOverlay;\n}\n\n/**\n * Base class for all subtitles settings select box\n *\n * @category Components\n **/\nexport class SubtitleSettingSelectBox extends SelectBox {\n\n protected settingsManager?: SubtitleSettingsManager;\n protected overlay: SubtitleOverlay;\n private currentCssClass: string;\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.overlay = config.overlay;\n }\n\n /**\n * Removes a previously set class and adds the passed in class.\n * @param cssClass The new class to replace the previous class with or null to just remove the previous class\n */\n protected toggleOverlayClass(cssClass: string): void {\n // Remove previous class if existing\n if (this.currentCssClass) {\n this.overlay.getDomElement().removeClass(this.currentCssClass);\n this.currentCssClass = null;\n }\n\n // Add new class if specified. If the new class is null, we don't add anything.\n if (cssClass) {\n this.currentCssClass = this.prefixCss(cssClass);\n this.overlay.getDomElement().addClass(this.currentCssClass);\n }\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n this.settingsManager = uimanager.getSubtitleSettingsManager();\n }\n}\n","import {LabelConfig} from '../label';\nimport {Container, ContainerConfig} from '../container';\nimport {DOM} from '../../dom';\nimport {SettingsPanelPageOpenButton} from '../settingspanelpageopenbutton';\nimport { LocalizableText, i18n } from '../../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingsLabelConfig extends LabelConfig {\n opener: SettingsPanelPageOpenButton;\n}\n\n/**\n * @category Components\n */\nexport class SubtitleSettingsLabel extends Container<ContainerConfig> {\n\n private opener: SettingsPanelPageOpenButton;\n\n private text: LocalizableText;\n\n private for: string;\n\n constructor(config: SubtitleSettingsLabelConfig) {\n super(config);\n\n this.opener = config.opener;\n this.text = config.text;\n this.for = config.for;\n\n this.config = this.mergeConfig(<ContainerConfig>config, {\n cssClass: 'ui-label',\n components: [\n this.opener,\n ],\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n let labelElement = new DOM('label', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'for': this.for,\n }, this).append(\n new DOM('span', {}).html(i18n.performLocalization(this.text)),\n this.opener.getDomElement(),\n );\n\n return labelElement;\n }\n}\n","import { StorageUtils } from '../../storageutils';\nimport { Component, ComponentConfig } from '../component';\nimport { EventDispatcher, Event } from '../../eventdispatcher';\n\ninterface SubtitleSettings {\n fontColor?: string;\n fontOpacity?: string;\n fontFamily?: string;\n fontSize?: string;\n characterEdge?: string;\n backgroundColor?: string;\n backgroundOpacity?: string;\n windowColor?: string;\n windowOpacity?: string;\n}\n\ninterface Properties {\n [name: string]: SubtitleSettingsProperty<string>;\n}\n\n/**\n * @category Utils\n */\nexport class SubtitleSettingsManager {\n private userSettings: SubtitleSettings;\n private localStorageKey: string;\n\n private _properties: Properties = {\n fontColor: new SubtitleSettingsProperty<string>(this),\n fontOpacity: new SubtitleSettingsProperty<string>(this),\n fontFamily: new SubtitleSettingsProperty<string>(this),\n fontSize: new SubtitleSettingsProperty<string>(this),\n characterEdge: new SubtitleSettingsProperty<string>(this),\n backgroundColor: new SubtitleSettingsProperty<string>(this),\n backgroundOpacity: new SubtitleSettingsProperty<string>(this),\n windowColor: new SubtitleSettingsProperty<string>(this),\n windowOpacity: new SubtitleSettingsProperty<string>(this),\n };\n\n constructor() {\n this.userSettings = {};\n this.localStorageKey =\n DummyComponent.instance().prefixCss('subtitlesettings');\n }\n\n public reset(): void {\n for (let propertyName in this._properties) {\n this._properties[propertyName].clear();\n }\n }\n\n public get fontColor(): SubtitleSettingsProperty<string> {\n return this._properties.fontColor;\n }\n\n public get fontOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.fontOpacity;\n }\n\n public get fontFamily(): SubtitleSettingsProperty<string> {\n return this._properties.fontFamily;\n }\n\n public get fontSize(): SubtitleSettingsProperty<string> {\n return this._properties.fontSize;\n }\n\n public get characterEdge(): SubtitleSettingsProperty<string> {\n return this._properties.characterEdge;\n }\n\n public get backgroundColor(): SubtitleSettingsProperty<string> {\n return this._properties.backgroundColor;\n }\n\n public get backgroundOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.backgroundOpacity;\n }\n\n public get windowColor(): SubtitleSettingsProperty<string> {\n return this._properties.windowColor;\n }\n\n public get windowOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.windowOpacity;\n }\n\n public initialize() {\n for (let propertyName in this._properties) {\n this._properties[propertyName].onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n (<any>this.userSettings)[propertyName] = property.value;\n } else {\n // Delete the property from the settings object if unset to avoid serialization of null values\n delete (<any>this.userSettings)[propertyName];\n }\n\n // Save the settings object when a property has changed\n this.save();\n });\n }\n\n this.load();\n }\n\n /**\n * Saves the settings to local storage.\n */\n public save(): void {\n StorageUtils.setObject(this.localStorageKey, this.userSettings);\n }\n\n /**\n * Loads the settings from local storage\n */\n public load(): void {\n this.userSettings =\n StorageUtils.getObject<SubtitleSettings>(this.localStorageKey) || {};\n\n // Apply the loaded settings\n for (let property in this.userSettings) {\n this._properties[property].value = (<any>this.userSettings)[property];\n }\n }\n}\n\n/**\n * A dummy component whose sole purpose is to expose the {@link #prefixCss} method to the\n * {@link SubtitleSettingsManager}.\n */\nclass DummyComponent extends Component<ComponentConfig> {\n private static _instance: DummyComponent;\n\n public static instance(): DummyComponent {\n if (!DummyComponent._instance) {\n DummyComponent._instance = new DummyComponent();\n }\n\n return DummyComponent._instance;\n }\n\n public prefixCss(cssClassOrId: string): string {\n return super.prefixCss(cssClassOrId);\n }\n}\n\nexport class SubtitleSettingsProperty<T> {\n private _manager: SubtitleSettingsManager;\n private _onChanged: EventDispatcher<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n >;\n private _value: T;\n\n constructor(manager: SubtitleSettingsManager) {\n this._manager = manager;\n this._onChanged = new EventDispatcher<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n >();\n }\n\n public isSet(): boolean {\n return this._value != null;\n }\n\n public clear(): void {\n this._value = null;\n this.onChangedEvent(null);\n }\n\n public get value(): T {\n return this._value;\n }\n\n public set value(value: T) {\n if (typeof value === 'string' && value === 'null') {\n value = null;\n }\n\n this._value = value;\n this.onChangedEvent(value);\n }\n\n protected onChangedEvent(value: T) {\n this._onChanged.dispatch(this._manager, this);\n }\n\n public get onChanged(): Event<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n > {\n return this._onChanged.getEvent();\n }\n}\n","import {SettingsPanelPage} from '../settingspanelpage';\nimport {SettingsPanel} from '../settingspanel';\nimport {SubtitleOverlay} from '../subtitleoverlay';\nimport {ContainerConfig} from '../container';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport {Component, ComponentConfig} from '../component';\nimport {FontSizeSelectBox} from './fontsizeselectbox';\nimport {FontFamilySelectBox} from './fontfamilyselectbox';\nimport {FontColorSelectBox} from './fontcolorselectbox';\nimport {FontOpacitySelectBox} from './fontopacityselectbox';\nimport {CharacterEdgeSelectBox} from './characteredgeselectbox';\nimport {BackgroundColorSelectBox} from './backgroundcolorselectbox';\nimport {BackgroundOpacitySelectBox} from './backgroundopacityselectbox';\nimport {WindowColorSelectBox} from './windowcolorselectbox';\nimport {WindowOpacitySelectBox} from './windowopacityselectbox';\nimport {SubtitleSettingsResetButton} from './subtitlesettingsresetbutton';\nimport {UIInstanceManager} from '../../uimanager';\nimport {SettingsPanelPageBackButton} from '../settingspanelpagebackbutton';\nimport {SettingsPanelItem} from '../settingspanelitem';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingsPanelPageConfig extends ContainerConfig {\n settingsPanel: SettingsPanel;\n overlay: SubtitleOverlay;\n}\n\n/**\n * @category Components\n */\nexport class SubtitleSettingsPanelPage extends SettingsPanelPage {\n\n private readonly overlay: SubtitleOverlay;\n private readonly settingsPanel: SettingsPanel;\n\n constructor(config: SubtitleSettingsPanelPageConfig) {\n super(config);\n\n this.overlay = config.overlay;\n this.settingsPanel = config.settingsPanel;\n\n\n this.config = this.mergeConfig(config, {\n components: <Component<ComponentConfig>[]>[\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.size'), new FontSizeSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.family'), new FontFamilySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.color'), new FontColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.opacity'), new FontOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.characterEdge'), new CharacterEdgeSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.background.color'), new BackgroundColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.background.opacity'), new BackgroundOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.window.color'), new WindowColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.window.opacity'), new WindowOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(new SettingsPanelPageBackButton({\n container: this.settingsPanel,\n text: i18n.getLocalizer('back'),\n }), new SubtitleSettingsResetButton({}), {\n role: 'menubar',\n }),\n ],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onActive.subscribe(() => {\n this.overlay.enablePreviewSubtitleLabel();\n });\n\n this.onInactive.subscribe(() => {\n this.overlay.removePreviewSubtitleLabel();\n });\n }\n}","import {UIInstanceManager} from '../../uimanager';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport {Button, ButtonConfig} from '../button';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A button that resets all subtitle settings to their defaults.\n *\n * @category Buttons\n */\nexport class SubtitleSettingsResetButton extends Button<ButtonConfig> {\n\n private settingsManager: SubtitleSettingsManager;\n\n constructor(config: ButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitlesettingsresetbutton',\n text: i18n.getLocalizer('reset'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n this.settingsManager = uimanager.getSubtitleSettingsManager();\n\n this.onClick.subscribe(() => {\n this.settingsManager.reset();\n });\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background colors.\n *\n * @category Components\n */\nexport class WindowColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingswindowcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.windowColor.isSet() && this.settingsManager.windowOpacity.isSet()) {\n this.toggleOverlayClass(\n 'windowcolor-' + this.settingsManager.windowColor.value + this.settingsManager.windowOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.windowColor.value = key;\n });\n\n this.settingsManager.windowColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.windowColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.windowOpacity.clear();\n } else if (!this.settingsManager.windowOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.windowOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.windowOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.windowColor.isSet()) {\n this.selectItem(this.settingsManager.windowColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background opacity.\n *\n * @category Components\n */\nexport class WindowOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingswindowopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n this.addItem('0', i18n.getLocalizer('percent', { value: 0 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.windowOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.windowOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.windowColor.clear();\n } else if (!this.settingsManager.windowColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.windowColor.value = 'black';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.windowOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.windowOpacity.isSet()) {\n this.selectItem(this.settingsManager.windowOpacity.value);\n }\n }\n}\n","import { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { DOM } from '../dom';\nimport { ComponentConfig } from './component';\nimport { TimelineMarker } from '../uiconfig';\nimport { SeekBarMarker } from './seekbar';\nimport { PlayerUtils } from '../playerutils';\nimport { Timeout } from '../timeout';\n\n/**\n * @category Configs\n */\nexport interface MarkersConfig extends ComponentConfig {\n /**\n * Used for seekBar marker snapping range percentage\n */\n snappingRange?: number;\n}\n\nexport class TimelineMarkersHandler {\n private markersContainer: DOM;\n private timelineMarkers: SeekBarMarker[];\n private player: PlayerAPI;\n private uimanager: UIInstanceManager;\n private pausedTimeshiftUpdater: Timeout;\n private getSeekBarWidth: () => number;\n protected config: MarkersConfig;\n\n constructor(config: MarkersConfig, getSeekBarWidth: () => number, markersContainer: DOM) {\n this.config = config;\n this.getSeekBarWidth = getSeekBarWidth;\n this.markersContainer = markersContainer;\n this.timelineMarkers = [];\n }\n\n public initialize(player: PlayerAPI, uimanager: UIInstanceManager) {\n this.player = player;\n this.uimanager = uimanager;\n this.configureMarkers();\n }\n\n private configureMarkers(): void {\n // Remove markers when unloaded\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, () => this.clearMarkers());\n this.player.on(this.player.exports.PlayerEvent.AdBreakStarted, () => this.clearMarkers());\n this.player.on(this.player.exports.PlayerEvent.AdBreakFinished, () => this.updateMarkers());\n // Update markers when the size of the seekbar changes\n this.player.on(this.player.exports.PlayerEvent.PlayerResized, () => this.updateMarkersDOM());\n\n this.player.on(this.player.exports.PlayerEvent.SourceLoaded, () => {\n if (this.player.isLive()) {\n // Update marker position as timeshift range changes\n this.player.on(this.player.exports.PlayerEvent.TimeChanged, () => this.updateMarkers());\n // Update marker postion when paused as timeshift range changes\n this.configureLivePausedTimeshiftUpdater(() => this.updateMarkers());\n }\n });\n this.uimanager.getConfig().events.onUpdated.subscribe(() => this.updateMarkers());\n this.uimanager.onRelease.subscribe(() => this.uimanager.getConfig().events.onUpdated.unsubscribe(() => this.updateMarkers()));\n\n // Init markers at startup\n this.updateMarkers();\n }\n\n public getMarkerAtPosition(percentage: number): SeekBarMarker | null {\n const snappingRange = this.config.snappingRange;\n\n const matchingMarker = this.timelineMarkers.find(marker => {\n const hasDuration = marker.duration > 0;\n // Handle interval markers\n const intervalMarkerMatch =\n hasDuration &&\n percentage >= marker.position - snappingRange &&\n percentage <= marker.position + marker.duration + snappingRange;\n\n // Handle position markers\n const positionMarkerMatch =\n percentage >= marker.position - snappingRange &&\n percentage <= marker.position + snappingRange;\n\n return intervalMarkerMatch || positionMarkerMatch;\n });\n\n return matchingMarker || null;\n }\n\n private clearMarkers(): void {\n this.timelineMarkers = [];\n this.markersContainer.empty();\n }\n\n private removeMarkerFromConfig(marker: TimelineMarker): void {\n this.uimanager.getConfig().metadata.markers = this.uimanager.getConfig().metadata.markers.filter(_marker => marker !== _marker);\n }\n\n private filterRemovedMarkers(): void {\n this.timelineMarkers = this.timelineMarkers.filter(seekbarMarker => {\n const matchingMarker = this.uimanager.getConfig().metadata.markers.find(_marker => seekbarMarker.marker === _marker);\n if (!matchingMarker) {\n this.removeMarkerFromDOM(seekbarMarker);\n }\n return matchingMarker;\n });\n }\n\n private removeMarkerFromDOM(marker: SeekBarMarker): void {\n if (marker.element) {\n marker.element.remove();\n }\n }\n\n private updateMarkers(): void {\n if (!shouldProcessMarkers(this.player, this.uimanager)) {\n this.clearMarkers();\n return;\n }\n\n this.filterRemovedMarkers();\n\n this.uimanager.getConfig().metadata.markers.forEach(marker => {\n const { markerPosition, markerDuration } = getMarkerPositions(this.player, marker);\n\n if (shouldRemoveMarker(markerPosition, markerDuration)) {\n this.removeMarkerFromConfig(marker);\n } else if (markerPosition <= 100) {\n const matchingMarker = this.timelineMarkers.find(seekbarMarker => seekbarMarker.marker === marker);\n\n if (matchingMarker) {\n matchingMarker.position = markerPosition;\n matchingMarker.duration = markerDuration;\n\n this.updateMarkerDOM(matchingMarker);\n } else {\n const newMarker: SeekBarMarker = { marker, position: markerPosition, duration: markerDuration };\n this.timelineMarkers.push(newMarker);\n\n this.createMarkerDOM(newMarker);\n }\n }\n });\n }\n\n private getMarkerCssProperties(marker: SeekBarMarker): { [propertyName: string]: string } {\n const seekBarWidthPx = this.getSeekBarWidth();\n\n const positionInPx = (seekBarWidthPx / 100) * (marker.position < 0 ? 0 : marker.position);\n const cssProperties: { [propertyName: string]: string } = {\n 'transform': `translateX(${positionInPx}px)`,\n };\n\n if (marker.duration > 0) {\n const markerWidthPx = Math.round(seekBarWidthPx / 100 * marker.duration);\n cssProperties['width'] = `${markerWidthPx}px`;\n }\n\n return cssProperties;\n }\n\n private updateMarkerDOM(marker: SeekBarMarker): void {\n marker.element.css(this.getMarkerCssProperties(marker));\n }\n\n private createMarkerDOM(marker: SeekBarMarker): void {\n const markerClasses = ['seekbar-marker'].concat(marker.marker.cssClasses || [])\n .map(cssClass => this.prefixCss(cssClass));\n\n const markerElement = new DOM('div', {\n 'class': markerClasses.join(' '),\n 'data-marker-time': String(marker.marker.time),\n 'data-marker-title': String(marker.marker.title),\n }).css(this.getMarkerCssProperties(marker));\n\n if (marker.marker.imageUrl) {\n const removeImage = () => {\n imageElement.remove();\n };\n\n const imageElement = new DOM('img', {\n 'class': this.prefixCss('seekbar-marker-image'),\n 'src': marker.marker.imageUrl,\n }).on('error', removeImage);\n\n markerElement.append(imageElement);\n }\n\n marker.element = markerElement;\n this.markersContainer.append(markerElement);\n }\n\n private updateMarkersDOM(): void {\n this.timelineMarkers.forEach(marker => {\n if (marker.element) {\n this.updateMarkerDOM(marker);\n } else {\n this.createMarkerDOM(marker);\n }\n });\n }\n\n private configureLivePausedTimeshiftUpdater(\n handler: () => void,\n ): void {\n // Regularly update the marker position while the timeout is active\n this.pausedTimeshiftUpdater = new Timeout(1000, handler, true);\n\n this.player.on(this.player.exports.PlayerEvent.Paused, () => {\n if (this.player.isLive() && this.player.getMaxTimeShift() < 0) {\n this.pausedTimeshiftUpdater.start();\n }\n });\n\n // Stop updater when playback continues (no matter if the updater was started before)\n this.player.on(this.player.exports.PlayerEvent.Play, () => this.pausedTimeshiftUpdater.clear());\n this.player.on(this.player.exports.PlayerEvent.Destroy, () => this.pausedTimeshiftUpdater.clear());\n }\n\n protected prefixCss(cssClassOrId: string): string {\n return this.config.cssPrefix + '-' + cssClassOrId;\n }\n}\n\nfunction getMarkerPositions(player: PlayerAPI, marker: TimelineMarker) {\n const duration = getDuration(player);\n\n const markerPosition = 100 / duration * getMarkerTime(marker, player, duration); // convert absolute time to percentage\n let markerDuration = 100 / duration * marker.duration;\n\n if (markerPosition < 0 && !isNaN(markerDuration)) {\n // Shrink marker duration for on live streams as they reach end\n markerDuration = markerDuration + markerPosition;\n }\n\n if (100 - markerPosition < markerDuration) {\n // Shrink marker if it overflows timeline\n markerDuration = 100 - markerPosition;\n }\n\n return { markerDuration, markerPosition };\n}\n\nfunction getMarkerTime(marker: TimelineMarker, player: PlayerAPI, duration: number): number {\n if (!player.isLive()) {\n return marker.time;\n }\n\n return duration - (PlayerUtils.getSeekableRangeRespectingLive(player).end - marker.time);\n}\n\nfunction getDuration(player: PlayerAPI): number {\n if (!player.isLive()) {\n return player.getDuration();\n }\n const { start, end } = PlayerUtils.getSeekableRangeRespectingLive(player);\n\n return end - start;\n}\n\nfunction shouldRemoveMarker(markerPosition: number, markerDuration: number): boolean {\n return (markerDuration < 0 || isNaN(markerDuration)) && markerPosition < 0;\n}\n\nfunction shouldProcessMarkers(player: PlayerAPI, uimanager: UIInstanceManager): boolean {\n // Don't generate timeline markers if we don't yet have a duration\n // The duration check is for buggy platforms where the duration is not available instantly (Chrome on Android 4.3)\n const validToProcess = player.getDuration() !== Infinity || player.isLive();\n const hasMarkers = uimanager.getConfig().metadata.markers.length > 0;\n\n return validToProcess && hasMarkers;\n}\n","import {Container, ContainerConfig} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {MetadataLabel, MetadataLabelContent} from './metadatalabel';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for a {@link TitleBar}.\n *\n * @category Configs\n */\nexport interface TitleBarConfig extends ContainerConfig {\n /**\n * Specifies if the title bar should stay hidden when no metadata label contains any text. Does not make a lot\n * of sense if the title bar contains other components than just MetadataLabels (like in the default configuration).\n * Default: false\n */\n keepHiddenWithoutMetadata?: boolean;\n}\n\n/**\n * Displays a title bar containing a label with the title of the video.\n *\n * @category Components\n */\nexport class TitleBar extends Container<TitleBarConfig> {\n\n constructor(config: TitleBarConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-titlebar',\n hidden: true,\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n new MetadataLabel({ content: MetadataLabelContent.Description }),\n ],\n keepHiddenWithoutMetadata: false,\n }, <TitleBarConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let shouldBeShown = !this.isHidden();\n let hasMetadataText = true; // Flag to track if any metadata label contains text\n\n let checkMetadataTextAndUpdateVisibility = () => {\n hasMetadataText = false;\n\n // Iterate through metadata labels and check if at least one of them contains text\n for (let component of this.getComponents()) {\n if (component instanceof MetadataLabel) {\n if (!component.isEmpty()) {\n hasMetadataText = true;\n break;\n }\n }\n }\n\n if (this.isShown()) {\n // Hide a visible titlebar if it does not contain any text and the hidden flag is set\n if (config.keepHiddenWithoutMetadata && !hasMetadataText) {\n this.hide();\n }\n } else if (shouldBeShown) {\n // Show a hidden titlebar if it should actually be shown\n this.show();\n }\n };\n\n // Listen to text change events to update the hasMetadataText flag when the metadata dynamically changes\n for (let component of this.getComponents()) {\n if (component instanceof MetadataLabel) {\n component.onTextChanged.subscribe(checkMetadataTextAndUpdateVisibility);\n }\n }\n\n uimanager.onControlsShow.subscribe(() => {\n shouldBeShown = true;\n if (!(config.keepHiddenWithoutMetadata && !hasMetadataText)) {\n this.show();\n }\n });\n uimanager.onControlsHide.subscribe(() => {\n shouldBeShown = false;\n this.hide();\n });\n\n // init\n checkMetadataTextAndUpdateVisibility();\n }\n}","import {Button, ButtonConfig} from './button';\nimport {NoArgs, EventDispatcher, Event} from '../eventdispatcher';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { LocalizableText } from '../localization/i18n';\n\n/**\n * Configuration interface for a toggle button component.\n *\n * @category Configs\n */\nexport interface ToggleButtonConfig extends ButtonConfig {\n /**\n * The CSS class that marks the on-state of the button.\n */\n onClass?: string;\n /**\n * The CSS class that marks the off-state of the button.\n */\n offClass?: string;\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n *\n * It is recommended to use `onAriaLabel` and `offAriaLabel` for toggle buttons\n * as the component can then update them as the button is used.\n *\n * If both `ariaLabel` and `onAriaLabel` are set, `onAriaLabel` is used.\n */\n ariaLabel?: LocalizableText;\n /**\n * The aria label that marks the on-state of the button.\n */\n onAriaLabel?: LocalizableText;\n /**\n * The aria label that marks the off-state of the button.\n */\n offAriaLabel?: LocalizableText;\n /**\n * The text as string or as localize callback on the button.\n */\n text?: LocalizableText;\n}\n\n/**\n * A button that can be toggled between 'on' and 'off' states.\n *\n * @category Components\n */\nexport class ToggleButton<Config extends ToggleButtonConfig> extends Button<Config> {\n\n private onState: boolean;\n\n private toggleButtonEvents = {\n onToggle: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n onToggleOn: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n onToggleOff: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n };\n\n constructor(config: Config) {\n super(config);\n\n const defaultConfig: ToggleButtonConfig = {\n cssClass: 'ui-togglebutton',\n onClass: 'on',\n offClass: 'off',\n };\n\n if (config.onAriaLabel) {\n config.ariaLabel = config.onAriaLabel;\n }\n\n this.config = this.mergeConfig(config, defaultConfig as Config, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n const config = this.getConfig();\n this.getDomElement().addClass(this.prefixCss(config.offClass));\n }\n\n /**\n * Toggles the button to the 'on' state.\n */\n on() {\n if (this.isOff()) {\n const config = this.getConfig();\n\n this.onState = true;\n this.getDomElement().removeClass(this.prefixCss(config.offClass));\n this.getDomElement().addClass(this.prefixCss(config.onClass));\n\n this.onToggleEvent();\n this.onToggleOnEvent();\n\n this.setAriaAttr('pressed', 'true');\n\n if (this.config.onAriaLabel) {\n this.setAriaLabel(this.config.onAriaLabel);\n }\n }\n }\n\n /**\n * Toggles the button to the 'off' state.\n */\n off() {\n if (this.isOn()) {\n const config = this.getConfig();\n\n this.onState = false;\n this.getDomElement().removeClass(this.prefixCss(config.onClass));\n this.getDomElement().addClass(this.prefixCss(config.offClass));\n\n this.onToggleEvent();\n this.onToggleOffEvent();\n\n this.setAriaAttr('pressed', 'false');\n\n if (this.config.offAriaLabel) {\n this.setAriaLabel(this.config.offAriaLabel);\n }\n }\n }\n\n /**\n * Toggle the button 'on' if it is 'off', or 'off' if it is 'on'.\n */\n toggle() {\n if (this.isOn()) {\n this.off();\n } else {\n this.on();\n }\n }\n\n /**\n * Checks if the toggle button is in the 'on' state.\n * @returns {boolean} true if button is 'on', false if 'off'\n */\n isOn(): boolean {\n return this.onState;\n }\n\n /**\n * Checks if the toggle button is in the 'off' state.\n * @returns {boolean} true if button is 'off', false if 'on'\n */\n isOff(): boolean {\n return !this.isOn();\n }\n\n protected onClickEvent() {\n super.onClickEvent();\n\n // Fire the toggle event together with the click event\n // (they are technically the same, only the semantics are different)\n this.onToggleEvent();\n }\n\n protected onToggleEvent() {\n this.toggleButtonEvents.onToggle.dispatch(this);\n }\n\n protected onToggleOnEvent() {\n this.toggleButtonEvents.onToggleOn.dispatch(this);\n }\n\n protected onToggleOffEvent() {\n this.toggleButtonEvents.onToggleOff.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the button is toggled.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggle(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggle.getEvent();\n }\n\n /**\n * Gets the event that is fired when the button is toggled 'on'.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggleOn(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggleOn.getEvent();\n }\n\n /**\n * Gets the event that is fired when the button is toggled 'off'.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggleOff(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggleOff.getEvent();\n }\n}","import {Component, ComponentConfig} from './component';\nimport {DOM} from '../dom';\n\n/**\n * Animated analog TV static noise.\n *\n * @category Components\n */\nexport class TvNoiseCanvas extends Component<ComponentConfig> {\n\n private canvas: DOM;\n\n private canvasElement: HTMLCanvasElement;\n private canvasContext: CanvasRenderingContext2D;\n private canvasWidth = 160;\n private canvasHeight = 90;\n private interferenceHeight = 50;\n private lastFrameUpdate: number = 0;\n private frameInterval: number = 60;\n private useAnimationFrame: boolean = !!window.requestAnimationFrame;\n private noiseAnimationWindowPos: number;\n private frameUpdateHandlerId: number;\n\n constructor(config: ComponentConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-tvnoisecanvas',\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n return this.canvas = new DOM('canvas', { 'class': this.getCssClasses() }, this);\n }\n\n start(): void {\n this.canvasElement = <HTMLCanvasElement>this.canvas.get(0);\n this.canvasContext = this.canvasElement.getContext('2d');\n this.noiseAnimationWindowPos = -this.canvasHeight;\n this.lastFrameUpdate = 0;\n\n this.canvasElement.width = this.canvasWidth;\n this.canvasElement.height = this.canvasHeight;\n\n this.renderFrame();\n }\n\n stop(): void {\n if (this.useAnimationFrame) {\n cancelAnimationFrame(this.frameUpdateHandlerId);\n } else {\n clearTimeout(this.frameUpdateHandlerId);\n }\n }\n\n private renderFrame(): void {\n // This code has been copied from the player controls.js and simplified\n\n if (this.lastFrameUpdate + this.frameInterval > new Date().getTime()) {\n // It's too early to render the next frame\n this.scheduleNextRender();\n return;\n }\n\n let currentPixelOffset;\n let canvasWidth = this.canvasWidth;\n let canvasHeight = this.canvasHeight;\n\n // Create texture\n let noiseImage = this.canvasContext.createImageData(canvasWidth, canvasHeight);\n\n // Fill texture with noise\n for (let y = 0; y < canvasHeight; y++) {\n for (let x = 0; x < canvasWidth; x++) {\n currentPixelOffset = (canvasWidth * y * 4) + x * 4;\n noiseImage.data[currentPixelOffset] = Math.random() * 255;\n if (y < this.noiseAnimationWindowPos || y > this.noiseAnimationWindowPos + this.interferenceHeight) {\n noiseImage.data[currentPixelOffset] *= 0.85;\n }\n noiseImage.data[currentPixelOffset + 1] = noiseImage.data[currentPixelOffset];\n noiseImage.data[currentPixelOffset + 2] = noiseImage.data[currentPixelOffset];\n noiseImage.data[currentPixelOffset + 3] = 50;\n }\n }\n\n // Put texture onto canvas\n this.canvasContext.putImageData(noiseImage, 0, 0);\n\n this.lastFrameUpdate = new Date().getTime();\n this.noiseAnimationWindowPos += 7;\n if (this.noiseAnimationWindowPos > canvasHeight) {\n this.noiseAnimationWindowPos = -canvasHeight;\n }\n\n this.scheduleNextRender();\n }\n\n private scheduleNextRender(): void {\n if (this.useAnimationFrame) {\n this.frameUpdateHandlerId = window.requestAnimationFrame(this.renderFrame.bind(this));\n } else {\n this.frameUpdateHandlerId = window.setTimeout(this.renderFrame.bind(this), this.frameInterval);\n }\n }\n}","import { Container, ContainerConfig } from './container';\nimport { UIInstanceManager } from '../uimanager';\nimport { DOM, HTMLElementWithComponent } from '../dom';\nimport { Timeout } from '../timeout';\nimport { PlayerUtils } from '../playerutils';\nimport { CancelEventArgs, Event as UiEvent, EventDispatcher } from '../eventdispatcher';\nimport { PlayerAPI, PlayerResizedEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { Button, ButtonConfig } from './button';\n\n/**\n * Configuration interface for a {@link UIContainer}.\n *\n * @category Configs\n */\nexport interface UIContainerConfig extends ContainerConfig {\n /**\n * The delay in milliseconds after which the control bar will be hidden when there is no user interaction.\n * Set to -1 for the UI to be always shown.\n * Default: 5 seconds (5000)\n */\n hideDelay?: number;\n /**\n * An array of player states in which the UI will not be hidden, no matter what the {@link hideDelay} is.\n */\n hidePlayerStateExceptions?: PlayerUtils.PlayerState[];\n /**\n * The HTML element on which user interaction events (e.g. mouse and touch events) will be tracked to detect\n * interaction with the UI. These basically trigger showing and hiding of the UI.\n * Default: the UI container itself\n */\n userInteractionEventSource?: HTMLElement;\n\n /**\n * Specify whether the UI should be hidden immediatly if the mouse leaves the userInteractionEventSource.\n * If false or not set it will wait for the hideDelay.\n * Default: false\n */\n hideImmediatelyOnMouseLeave?: boolean;\n}\n\n/**\n * The base container that contains all of the UI. The UIContainer is passed to the {@link UIManager} to build and\n * setup the UI.\n *\n * @category Containers\n */\nexport class UIContainer extends Container<UIContainerConfig> {\n\n private static readonly STATE_PREFIX = 'player-state-';\n\n private static readonly FULLSCREEN = 'fullscreen';\n private static readonly BUFFERING = 'buffering';\n private static readonly REMOTE_CONTROL = 'remote-control';\n private static readonly CONTROLS_SHOWN = 'controls-shown';\n private static readonly CONTROLS_HIDDEN = 'controls-hidden';\n\n private uiHideTimeout: Timeout;\n private playerStateChange: EventDispatcher<UIContainer, PlayerUtils.PlayerState>;\n\n private userInteractionEventSource: DOM;\n private userInteractionEvents: { name: string, handler: EventListenerOrEventListenerObject }[];\n private hidingPrevented: () => boolean;\n\n public hideUi: () => void = () => {};\n public showUi: () => void = () => {};\n\n constructor(config: UIContainerConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, <UIContainerConfig>{\n cssClass: 'ui-uicontainer',\n role: 'region',\n ariaLabel: i18n.getLocalizer('player'),\n hideDelay: 5000,\n hideImmediatelyOnMouseLeave: false,\n }, this.config);\n\n this.playerStateChange = new EventDispatcher<UIContainer, PlayerUtils.PlayerState>();\n this.hidingPrevented = () => false;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n const config = this.getConfig();\n\n if (config.userInteractionEventSource) {\n this.userInteractionEventSource = new DOM(config.userInteractionEventSource);\n } else {\n this.userInteractionEventSource = this.getDomElement();\n }\n\n super.configure(player, uimanager);\n\n this.configureUIShowHide(player, uimanager);\n this.configurePlayerStates(player, uimanager);\n }\n\n private configureUIShowHide(player: PlayerAPI, uimanager: UIInstanceManager): void {\n let config = this.getConfig();\n\n if (config.hideDelay === -1) {\n uimanager.onConfigured.subscribe(() => uimanager.onControlsShow.dispatch(this));\n return;\n }\n\n let isUiShown = false;\n let isSeeking = false;\n let isFirstTouch = true;\n let playerState: PlayerUtils.PlayerState;\n\n this.hidingPrevented = (): boolean => {\n return config.hidePlayerStateExceptions && config.hidePlayerStateExceptions.indexOf(playerState) > -1;\n };\n\n this.showUi = () => {\n if (!isUiShown) {\n // Let subscribers know that they should reveal themselves\n uimanager.onControlsShow.dispatch(this);\n isUiShown = true;\n }\n // Don't trigger timeout while seeking (it will be triggered once the seek is finished) or casting\n if (!isSeeking && !player.isCasting() && !this.hidingPrevented()) {\n this.uiHideTimeout.start();\n }\n };\n\n this.hideUi = () => {\n // Hide the UI only if it is shown, and if not casting\n if (isUiShown && !player.isCasting()) {\n // Issue a preview event to check if we are good to hide the controls\n let previewHideEventArgs = <CancelEventArgs>{};\n uimanager.onPreviewControlsHide.dispatch(this, previewHideEventArgs);\n\n if (!previewHideEventArgs.cancel) {\n // If the preview wasn't canceled, let subscribers know that they should now hide themselves\n uimanager.onControlsHide.dispatch(this);\n isUiShown = false;\n } else {\n // If the hide preview was canceled, continue to show UI\n this.showUi();\n }\n }\n };\n\n // Timeout to defer UI hiding by the configured delay time\n this.uiHideTimeout = new Timeout(config.hideDelay, this.hideUi);\n\n this.userInteractionEvents = [{\n // On touch displays, the first touch reveals the UI\n name: 'touchend',\n handler: (e) => {\n const shouldPreventDefault = ((e: Event): Boolean => {\n const findButtonComponent = ((element: HTMLElementWithComponent): Button<ButtonConfig> | null => {\n if (\n !element\n || element === this.userInteractionEventSource.get(0)\n || element.component instanceof UIContainer\n ) {\n return null;\n }\n\n if (element.component && element.component instanceof Button) {\n return element.component;\n } else {\n return findButtonComponent(element.parentElement);\n }\n });\n\n const buttonComponent = findButtonComponent(e.target as HTMLElementWithComponent);\n return !(buttonComponent && buttonComponent.getConfig().acceptsTouchWithUiHidden);\n });\n\n if (!isUiShown) {\n // Only if the UI is hidden, we prevent other actions (except for the first touch) and reveal the UI\n // instead. The first touch is not prevented to let other listeners receive the event and trigger an\n // initial action, e.g. the huge playback button can directly start playback instead of requiring a double\n // tap which 1. reveals the UI and 2. starts playback.\n if (isFirstTouch && !player.isPlaying()) {\n isFirstTouch = false;\n } else {\n // On touch input devices, the first touch is expected to display the UI controls and not be propagated to\n // other components.\n // When buttons are always visible this causes UX problems, as the first touch is not recognized.\n // This is the case for the {@link AdSkipButton} and {@link AdClickOverlay}.\n // To prevent UX issues where the buttons need to be touched twice, we do not prevent the first touch event.\n if (shouldPreventDefault(e)) {\n e.preventDefault();\n }\n }\n this.showUi();\n }\n },\n }, {\n // When the mouse enters, we show the UI\n name: 'mouseenter',\n handler: () => {\n this.showUi();\n },\n }, {\n // When the mouse moves within, we show the UI\n name: 'mousemove',\n handler: () => {\n this.showUi();\n },\n }, {\n name: 'focusin',\n handler: () => {\n this.showUi();\n },\n }, {\n name: 'keydown',\n handler: () => {\n this.showUi();\n },\n }, {\n // When the mouse leaves, we can prepare to hide the UI, except a seek is going on\n name: 'mouseleave',\n handler: () => {\n // When a seek is going on, the seek scrub pointer may exit the UI area while still seeking, and we do not\n // hide the UI in such cases\n if (!isSeeking && !this.hidingPrevented()) {\n if (this.config.hideImmediatelyOnMouseLeave) {\n this.hideUi();\n } else {\n this.uiHideTimeout.start();\n }\n }\n },\n }];\n\n this.userInteractionEvents.forEach((event) => this.userInteractionEventSource.on(event.name, event.handler));\n\n uimanager.onSeek.subscribe(() => {\n this.uiHideTimeout.clear(); // Don't hide UI while a seek is in progress\n isSeeking = true;\n });\n uimanager.onSeeked.subscribe(() => {\n isSeeking = false;\n if (!this.hidingPrevented()) {\n this.uiHideTimeout.start(); // Re-enable UI hide timeout after a seek\n }\n });\n uimanager.onComponentViewModeChanged.subscribe((_, { mode }) => this.trackComponentViewMode(mode));\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n this.showUi(); // Show UI when a Cast session has started (UI will then stay permanently on during the session)\n });\n this.playerStateChange.subscribe((_, state) => {\n playerState = state;\n if (this.hidingPrevented()) {\n // Entering a player state that prevents hiding and forces the controls to be shown\n this.uiHideTimeout.clear();\n this.showUi();\n } else {\n // Entering a player state that allows hiding\n this.uiHideTimeout.start();\n }\n });\n }\n\n private configurePlayerStates(player: PlayerAPI, uimanager: UIInstanceManager): void {\n let container = this.getDomElement();\n\n // Convert player states into CSS class names\n let stateClassNames = <any>[];\n for (let state in PlayerUtils.PlayerState) {\n if (isNaN(Number(state))) {\n let enumName = PlayerUtils.PlayerState[<any>PlayerUtils.PlayerState[state]];\n stateClassNames[PlayerUtils.PlayerState[state]] =\n this.prefixCss(UIContainer.STATE_PREFIX + enumName.toLowerCase());\n }\n }\n\n let removeStates = () => {\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Idle]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Prepared]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Playing]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Paused]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Finished]);\n };\n\n const updateState = (state: PlayerUtils.PlayerState) => {\n removeStates();\n container.addClass(stateClassNames[state]);\n this.playerStateChange.dispatch(this, state);\n };\n\n player.on(player.exports.PlayerEvent.SourceLoaded, () => {\n updateState(PlayerUtils.PlayerState.Prepared);\n });\n player.on(player.exports.PlayerEvent.Play, () => {\n updateState(PlayerUtils.PlayerState.Playing);\n });\n player.on(player.exports.PlayerEvent.Playing, () => {\n updateState(PlayerUtils.PlayerState.Playing);\n });\n player.on(player.exports.PlayerEvent.Paused, () => {\n updateState(PlayerUtils.PlayerState.Paused);\n });\n player.on(player.exports.PlayerEvent.PlaybackFinished, () => {\n updateState(PlayerUtils.PlayerState.Finished);\n });\n player.on(player.exports.PlayerEvent.SourceUnloaded, () => {\n updateState(PlayerUtils.PlayerState.Idle);\n });\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n updateState(PlayerUtils.getState(player));\n });\n\n // Fullscreen marker class\n player.on(player.exports.PlayerEvent.ViewModeChanged, () => {\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n container.addClass(this.prefixCss(UIContainer.FULLSCREEN));\n } else {\n container.removeClass(this.prefixCss(UIContainer.FULLSCREEN));\n }\n });\n // Init fullscreen state\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n container.addClass(this.prefixCss(UIContainer.FULLSCREEN));\n }\n\n // Buffering marker class\n player.on(player.exports.PlayerEvent.StallStarted, () => {\n container.addClass(this.prefixCss(UIContainer.BUFFERING));\n });\n player.on(player.exports.PlayerEvent.StallEnded, () => {\n container.removeClass(this.prefixCss(UIContainer.BUFFERING));\n });\n // Init buffering state\n if (player.isStalled()) {\n container.addClass(this.prefixCss(UIContainer.BUFFERING));\n }\n\n // RemoteControl marker class\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n });\n player.on(player.exports.PlayerEvent.CastStopped, () => {\n container.removeClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n });\n // Init RemoteControl state\n if (player.isCasting()) {\n container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n }\n\n // Controls visibility marker class\n uimanager.onControlsShow.subscribe(() => {\n container.removeClass(this.prefixCss(UIContainer.CONTROLS_HIDDEN));\n container.addClass(this.prefixCss(UIContainer.CONTROLS_SHOWN));\n });\n uimanager.onControlsHide.subscribe(() => {\n container.removeClass(this.prefixCss(UIContainer.CONTROLS_SHOWN));\n container.addClass(this.prefixCss(UIContainer.CONTROLS_HIDDEN));\n });\n\n // Layout size classes\n let updateLayoutSizeClasses = (width: number, height: number) => {\n container.removeClass(this.prefixCss('layout-max-width-400'));\n container.removeClass(this.prefixCss('layout-max-width-600'));\n container.removeClass(this.prefixCss('layout-max-width-800'));\n container.removeClass(this.prefixCss('layout-max-width-1200'));\n\n if (width <= 400) {\n container.addClass(this.prefixCss('layout-max-width-400'));\n } else if (width <= 600) {\n container.addClass(this.prefixCss('layout-max-width-600'));\n } else if (width <= 800) {\n container.addClass(this.prefixCss('layout-max-width-800'));\n } else if (width <= 1200) {\n container.addClass(this.prefixCss('layout-max-width-1200'));\n }\n };\n player.on(player.exports.PlayerEvent.PlayerResized, (e: PlayerResizedEvent) => {\n // Convert strings (with \"px\" suffix) to ints\n let width = Math.round(Number(e.width.substring(0, e.width.length - 2)));\n let height = Math.round(Number(e.height.substring(0, e.height.length - 2)));\n\n updateLayoutSizeClasses(width, height);\n });\n // Init layout state\n updateLayoutSizeClasses(new DOM(player.getContainer()).width(), new DOM(player.getContainer()).height());\n }\n\n release(): void {\n // Explicitly unsubscribe user interaction event handlers because they could be attached to an external element\n // that isn't owned by the UI and therefore not removed on release.\n if (this.userInteractionEvents) {\n this.userInteractionEvents.forEach((event) => this.userInteractionEventSource.off(event.name, event.handler));\n }\n\n super.release();\n\n if (this.uiHideTimeout) {\n this.uiHideTimeout.clear();\n }\n }\n\n onPlayerStateChange(): UiEvent<UIContainer, PlayerUtils.PlayerState> {\n return this.playerStateChange.getEvent();\n }\n\n protected suspendHideTimeout() {\n this.uiHideTimeout.suspend();\n }\n\n protected resumeHideTimeout() {\n this.uiHideTimeout.resume(!this.hidingPrevented());\n }\n\n protected toDomElement(): DOM {\n let container = super.toDomElement();\n\n // Detect flexbox support (not supported in IE9)\n if (document && typeof document.createElement('p').style.flex !== 'undefined') {\n container.addClass(this.prefixCss('flexbox'));\n } else {\n container.addClass(this.prefixCss('no-flexbox'));\n }\n\n return container;\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between 'auto' and the available video qualities.\n *\n * @category Components\n */\nexport class VideoQualitySelectBox extends SelectBox {\n\n private hasAuto: boolean;\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-videoqualityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let selectCurrentVideoQuality = () => {\n this.selectItem(player.getVideoQuality().id);\n };\n\n let updateVideoQualities = () => {\n let videoQualities = player.getAvailableVideoQualities();\n\n this.clearItems();\n\n // Progressive streams do not support automatic quality selection\n this.hasAuto = player.getStreamType() !== 'progressive';\n\n if (this.hasAuto) {\n // Add entry for automatic quality switching (default setting)\n this.addItem('auto', i18n.getLocalizer('auto'));\n }\n\n // Add video qualities\n for (let videoQuality of videoQualities) {\n this.addItem(videoQuality.id, videoQuality.label);\n }\n\n // Select initial quality\n selectCurrentVideoQuality();\n };\n\n this.onItemSelected.subscribe((sender: VideoQualitySelectBox, value: string) => {\n player.setVideoQuality(value);\n });\n\n // Update qualities when source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, updateVideoQualities);\n // Update qualities when the period within a source changes\n player.on(player.exports.PlayerEvent.PeriodSwitched, updateVideoQualities);\n // Update quality selection when quality is changed (from outside)\n player.on(player.exports.PlayerEvent.VideoQualityChanged, selectCurrentVideoQuality);\n\n if ((player.exports.PlayerEvent as any).VideoQualityAdded) {\n // Update qualities when their availability changed\n // TODO: remove any cast after next player release\n player.on((player.exports.PlayerEvent as any).VideoQualityAdded, updateVideoQualities);\n player.on((player.exports.PlayerEvent as any).VideoQualityRemoved, updateVideoQualities);\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(updateVideoQualities);\n }\n\n /**\n * Returns true if the select box contains an 'auto' item for automatic quality selection mode.\n * @return {boolean}\n */\n hasAutoItem(): boolean {\n return this.hasAuto;\n }\n}","import {Container, ContainerConfig} from './container';\nimport {VolumeSlider} from './volumeslider';\nimport {VolumeToggleButton} from './volumetogglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for a {@link VolumeControlButton}.\n *\n * @category Configs\n */\nexport interface VolumeControlButtonConfig extends ContainerConfig {\n /**\n * The delay after which the volume slider will be hidden when there is no user interaction.\n * Care must be taken that the delay is long enough so users can reach the slider from the toggle button, e.g. by\n * mouse movement. If the delay is too short, the sliders disappears before the mouse pointer has reached it and\n * the user is not able to use it.\n * Default: 500ms\n */\n hideDelay?: number;\n /**\n * Specifies if the volume slider should be vertically or horizontally aligned.\n * Default: true\n */\n vertical?: boolean;\n}\n\n/**\n * A composite volume control that consists of and internally manages a volume control button that can be used\n * for muting, and a (depending on the CSS style, e.g. slide-out) volume control bar.\n *\n * @category Buttons\n */\nexport class VolumeControlButton extends Container<VolumeControlButtonConfig> {\n\n private volumeToggleButton: VolumeToggleButton;\n private volumeSlider: VolumeSlider;\n\n private volumeSliderHideTimeout: Timeout;\n\n constructor(config: VolumeControlButtonConfig = {}) {\n super(config);\n\n this.volumeToggleButton = new VolumeToggleButton();\n this.volumeSlider = new VolumeSlider({\n vertical: config.vertical != null ? config.vertical : true,\n hidden: true,\n });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-volumecontrolbutton',\n components: [this.volumeToggleButton, this.volumeSlider],\n hideDelay: 500,\n }, <VolumeControlButtonConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let volumeToggleButton = this.getVolumeToggleButton();\n let volumeSlider = this.getVolumeSlider();\n\n this.volumeSliderHideTimeout = new Timeout(this.getConfig().hideDelay, () => {\n volumeSlider.hide();\n });\n\n /*\n * Volume Slider visibility handling\n *\n * The volume slider shall be visible while the user hovers the mute toggle button, while the user hovers the\n * volume slider, and while the user slides the volume slider. If none of these situations are true, the slider\n * shall disappear.\n */\n let volumeSliderHovered = false;\n volumeToggleButton.getDomElement().on('mouseenter', () => {\n // Show volume slider when mouse enters the button area\n if (volumeSlider.isHidden()) {\n volumeSlider.show();\n }\n // Avoid hiding of the slider when button is hovered\n this.volumeSliderHideTimeout.clear();\n });\n volumeToggleButton.getDomElement().on('mouseleave', () => {\n // Hide slider delayed when button is left\n this.volumeSliderHideTimeout.reset();\n });\n volumeSlider.getDomElement().on('mouseenter', () => {\n // When the slider is entered, cancel the hide timeout activated by leaving the button\n this.volumeSliderHideTimeout.clear();\n volumeSliderHovered = true;\n });\n volumeSlider.getDomElement().on('mouseleave', () => {\n // When mouse leaves the slider, only hide it if there is no slide operation in progress\n if (volumeSlider.isSeeking()) {\n this.volumeSliderHideTimeout.clear();\n } else {\n this.volumeSliderHideTimeout.reset();\n }\n volumeSliderHovered = false;\n });\n volumeSlider.onSeeked.subscribe(() => {\n // When a slide operation is done and the slider not hovered (mouse outside slider), hide slider delayed\n if (!volumeSliderHovered) {\n this.volumeSliderHideTimeout.reset();\n }\n });\n }\n\n release(): void {\n super.release();\n this.volumeSliderHideTimeout.clear();\n }\n\n /**\n * Provides access to the internally managed volume toggle button.\n * @returns {VolumeToggleButton}\n */\n getVolumeToggleButton(): VolumeToggleButton {\n return this.volumeToggleButton;\n }\n\n /**\n * Provides access to the internally managed volume silder.\n * @returns {VolumeSlider}\n */\n getVolumeSlider(): VolumeSlider {\n return this.volumeSlider;\n }\n}","import { SeekBar, SeekBarConfig, SeekPreviewEventArgs } from './seekbar';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { VolumeTransition } from '../volumecontroller';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link VolumeSlider} component.\n *\n * @category Configs\n */\nexport interface VolumeSliderConfig extends SeekBarConfig {\n /**\n * Specifies if the volume slider should be automatically hidden when volume control is prohibited by the\n * browser or platform. This currently only applies to iOS.\n * Default: true\n */\n hideIfVolumeControlProhibited?: boolean;\n}\n\n/**\n * A simple volume slider component to adjust the player's volume setting.\n *\n * @category Components\n */\nexport class VolumeSlider extends SeekBar {\n private volumeTransition: VolumeTransition;\n\n constructor(config: VolumeSliderConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <VolumeSliderConfig>{\n cssClass: 'ui-volumeslider',\n hideIfVolumeControlProhibited: true,\n ariaLabel: i18n.getLocalizer('settings.audio.volume'),\n tabIndex: 0,\n }, this.config);\n }\n\n private setVolumeAriaSliderValues(value: number) {\n this.getDomElement().attr('aria-valuenow', Math.ceil(value).toString());\n this.getDomElement().attr('aria-valuetext', `${i18n.performLocalization(i18n.getLocalizer('seekBar.value'))}: ${Math.ceil(value)}`);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager, false);\n\n this.setAriaSliderMinMax('0', '100');\n\n let config = <VolumeSliderConfig>this.getConfig();\n\n const volumeController = uimanager.getConfig().volumeController;\n\n if (config.hideIfVolumeControlProhibited && !this.detectVolumeControlAvailability()) {\n this.hide();\n\n // We can just return from here, because the user will never interact with the control and any configured\n // functionality would only eat resources for no reason.\n return;\n }\n\n volumeController.onChanged.subscribe((_, args) => {\n if (args.muted) {\n this.setVolumeAriaSliderValues(0);\n this.setPlaybackPosition(0);\n } else {\n this.setPlaybackPosition(args.volume);\n this.setVolumeAriaSliderValues(args.volume);\n }\n });\n\n this.onSeek.subscribe(() => {\n this.volumeTransition = volumeController.startTransition();\n });\n\n this.onSeekPreview.subscribeRateLimited(this.updateVolumeWhileScrubbing, 50);\n this.onSeeked.subscribe((sender, percentage) => {\n if (this.volumeTransition) {\n this.volumeTransition.finish(percentage);\n }\n });\n\n // Update the volume slider marker when the player resized, a source is loaded,\n // or the UI is configured. Check the seekbar for a detailed description.\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n this.refreshPlaybackPosition();\n });\n uimanager.onConfigured.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n uimanager.onComponentShow.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n uimanager.onComponentHide.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n // Init volume bar\n volumeController.onChangedEvent();\n }\n\n private updateVolumeWhileScrubbing = (sender: VolumeSlider, args: SeekPreviewEventArgs) => {\n if (args.scrubbing && this.volumeTransition) {\n this.volumeTransition.update(args.position);\n }\n };\n\n private detectVolumeControlAvailability(): boolean {\n /*\n * \"On iOS devices, the audio level is always under the user’s physical control. The volume property is not\n * settable in JavaScript. Reading the volume property always returns 1.\"\n * https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html\n */\n // as muted autoplay gets paused as soon as we unmute it, we may not touch the volume of the actual player so we\n // probe a dummy audio element\n const dummyVideoElement = document.createElement('video');\n // try setting the volume to 0.7 and if it's still 1 we are on a volume control restricted device\n dummyVideoElement.volume = 0.7;\n return dummyVideoElement.volume !== 1;\n }\n\n release(): void {\n super.release();\n\n this.onSeekPreview.unsubscribe(this.updateVolumeWhileScrubbing);\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles audio muting.\n *\n * @category Buttons\n */\nexport class VolumeToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n const defaultConfig: ToggleButtonConfig = {\n cssClass: 'ui-volumetogglebutton',\n text: i18n.getLocalizer('settings.audio.mute'),\n onClass: 'muted',\n offClass: 'unmuted',\n ariaLabel: i18n.getLocalizer('settings.audio.mute'),\n };\n\n this.config = this.mergeConfig(config, defaultConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const volumeController = uimanager.getConfig().volumeController;\n\n volumeController.onChanged.subscribe((_, args) => {\n if (args.muted) {\n this.on();\n } else {\n this.off();\n }\n\n const volumeLevelTens = Math.ceil(args.volume / 10);\n this.getDomElement().data(this.prefixCss('volume-level-tens'), String(volumeLevelTens));\n });\n\n this.onClick.subscribe(() => {\n volumeController.toggleMuted();\n });\n\n // Startup init\n volumeController.onChangedEvent();\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI, PlayerEventBase, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles the video view between normal/mono and VR/stereo.\n *\n * @category Buttons\n */\nexport class VRToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-vrtogglebutton',\n text: i18n.getLocalizer('vr'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let isVRConfigured = () => {\n // VR availability cannot be checked through getVRStatus() because it is asynchronously populated and not\n // available at UI initialization. As an alternative, we check the VR settings in the config.\n // TODO use getVRStatus() through isVRStereoAvailable() once the player has been rewritten and the status is\n // available in Ready\n const source = player.getSource();\n return source && Boolean(source.vr);\n };\n\n let isVRStereoAvailable = () => {\n const source = player.getSource();\n return player.vr && Boolean(source.vr);\n };\n\n let vrStateHandler = (ev: PlayerEventBase) => {\n if (ev.type === player.exports.PlayerEvent.Warning\n && (ev as WarningEvent).code !== player.exports.WarningCode.VR_RENDERING_ERROR) {\n return;\n }\n\n if (isVRConfigured() && isVRStereoAvailable()) {\n this.show(); // show button in case it is hidden\n\n if (player.vr && player.vr.getStereo()) {\n this.on();\n } else {\n this.off();\n }\n } else {\n this.hide(); // hide button if no stereo mode available\n }\n };\n\n let vrButtonVisibilityHandler = () => {\n if (isVRConfigured()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n player.on(player.exports.PlayerEvent.VRStereoChanged, vrStateHandler);\n player.on(player.exports.PlayerEvent.Warning, vrStateHandler);\n // Hide button when VR source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, vrButtonVisibilityHandler);\n uimanager.getConfig().events.onUpdated.subscribe(vrButtonVisibilityHandler);\n\n this.onClick.subscribe(() => {\n if (!isVRStereoAvailable()) {\n if (console) {\n console.log('No VR content');\n }\n } else {\n if (player.vr && player.vr.getStereo()) {\n player.vr.setStereo(false);\n } else {\n player.vr.setStereo(true);\n }\n }\n });\n\n // Set startup visibility\n vrButtonVisibilityHandler();\n }\n}","import {ClickOverlay, ClickOverlayConfig} from './clickoverlay';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link ClickOverlay}.\n *\n * @category Configs\n */\nexport interface WatermarkConfig extends ClickOverlayConfig {\n // nothing yet\n}\n\n/**\n * A watermark overlay with a clickable logo.\n *\n * @category Components\n */\nexport class Watermark extends ClickOverlay {\n\n constructor(config: WatermarkConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-watermark',\n url: 'http://bitmovin.com',\n role: 'link',\n text: 'logo',\n ariaLabel: i18n.getLocalizer('watermarkLink'),\n }, <WatermarkConfig>this.config);\n }\n}","import {VRToggleButton} from './components/vrtogglebutton';\nimport {SettingsToggleButton} from './components/settingstogglebutton';\nimport {VolumeSlider} from './components/volumeslider';\nimport {PlaybackTimeLabel, PlaybackTimeLabelMode} from './components/playbacktimelabel';\nimport {AirPlayToggleButton} from './components/airplaytogglebutton';\nimport {ErrorMessageOverlay} from './components/errormessageoverlay';\nimport {ControlBar} from './components/controlbar';\nimport {CastToggleButton} from './components/casttogglebutton';\nimport {FullscreenToggleButton} from './components/fullscreentogglebutton';\nimport {RecommendationOverlay} from './components/recommendationoverlay';\nimport {PlaybackSpeedSelectBox} from './components/playbackspeedselectbox';\nimport {AudioQualitySelectBox} from './components/audioqualityselectbox';\nimport {CastStatusOverlay} from './components/caststatusoverlay';\nimport {UIContainer} from './components/uicontainer';\nimport {Watermark} from './components/watermark';\nimport {SubtitleOverlay} from './components/subtitleoverlay';\nimport {SettingsPanel} from './components/settingspanel';\nimport {SeekBarLabel} from './components/seekbarlabel';\nimport {PlaybackToggleOverlay} from './components/playbacktoggleoverlay';\nimport {PictureInPictureToggleButton} from './components/pictureinpicturetogglebutton';\nimport {Spacer} from './components/spacer';\nimport {Container} from './components/container';\nimport {VolumeToggleButton} from './components/volumetogglebutton';\nimport {PlaybackToggleButton} from './components/playbacktogglebutton';\nimport {SeekBar} from './components/seekbar';\nimport {VideoQualitySelectBox} from './components/videoqualityselectbox';\nimport {UIConditionContext, UIManager} from './uimanager';\nimport {TitleBar} from './components/titlebar';\nimport {BufferingOverlay} from './components/bufferingoverlay';\nimport {SubtitleListBox} from './components/subtitlelistbox';\nimport {AudioTrackListBox} from './components/audiotracklistbox';\nimport {SettingsPanelItem} from './components/settingspanelitem';\nimport {SettingsPanelPage} from './components/settingspanelpage';\nimport { UIFactory } from './uifactory';\nimport { UIConfig } from './uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { QuickSeekButton } from './main';\n\nexport namespace DemoFactory {\n\n export function buildDemoWithSeparateAudioSubtitlesButtons(player: PlayerAPI, config: UIConfig = {}): UIManager {\n // show smallScreen UI only on mobile/handheld devices\n let smallScreenSwitchWidth = 600;\n\n return new UIManager(player, [{\n ui: UIFactory.modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isMobile && context.documentWidth < smallScreenSwitchWidth\n && context.isAd && context.adRequiresUi;\n },\n }, {\n ui: UIFactory.modernAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n }, {\n ui: UIFactory.modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return context.isMobile && context.documentWidth < smallScreenSwitchWidth;\n },\n }, {\n ui: modernUIWithSeparateAudioSubtitlesButtons(),\n }], config);\n }\n\n function modernUIWithSeparateAudioSubtitlesButtons() {\n let subtitleOverlay = new SubtitleOverlay();\n\n let settingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem('Video Quality', new VideoQualitySelectBox()),\n new SettingsPanelItem('Speed', new PlaybackSpeedSelectBox()),\n new SettingsPanelItem('Audio Quality', new AudioQualitySelectBox()),\n ],\n }),\n ],\n hidden: true,\n });\n\n let subtitleListBox = new SubtitleListBox();\n let subtitleSettingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem(null, subtitleListBox),\n ],\n }),\n ],\n hidden: true,\n });\n\n let audioTrackListBox = new AudioTrackListBox();\n let audioTrackSettingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem(null, audioTrackListBox),\n ],\n }),\n ],\n hidden: true,\n });\n\n let controlBar = new ControlBar({\n components: [\n audioTrackSettingsPanel,\n subtitleSettingsPanel,\n settingsPanel,\n new Container({\n components: [\n new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.CurrentTime, hideInLivePlayback: true }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.TotalTime, cssClasses: ['text-right'] }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n new Container({\n components: [\n new PlaybackToggleButton(),\n new QuickSeekButton({ seekSeconds: -10 }),\n new QuickSeekButton({ seekSeconds: 10 }),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new CastToggleButton(),\n new VRToggleButton(),\n new SettingsToggleButton({\n settingsPanel: audioTrackSettingsPanel,\n cssClass: 'ui-audiotracksettingstogglebutton',\n }),\n new SettingsToggleButton({\n settingsPanel: subtitleSettingsPanel,\n cssClass: 'ui-subtitlesettingstogglebutton',\n }),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new CastStatusOverlay(),\n controlBar,\n new TitleBar(),\n new RecommendationOverlay(),\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n });\n }\n}","import { Component, ComponentConfig } from './components/component';\n\nexport interface Offset {\n left: number;\n top: number;\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface CssProperties {\n [propertyName: string]: string;\n}\n\n/**\n * Extends the {@link HTMLElement} interface with a component attribute to store the associated component.\n */\nexport interface HTMLElementWithComponent extends HTMLElement {\n component?: Component<ComponentConfig>;\n}\n\n/**\n * Simple DOM manipulation and DOM element event handling modeled after jQuery (as replacement for jQuery).\n *\n * Like jQuery, DOM operates on single elements and lists of elements. For example: creating an element returns a DOM\n * instance with a single element, selecting elements returns a DOM instance with zero, one, or many elements. Similar\n * to jQuery, setters usually affect all elements, while getters operate on only the first element.\n * Also similar to jQuery, most methods (except getters) return the DOM instance facilitating easy chaining of method\n * calls.\n *\n * Built with the help of: http://youmightnotneedjquery.com/\n */\nexport class DOM {\n\n private document: Document;\n\n /**\n * The list of elements that the instance wraps. Take care that not all methods can operate on the whole list,\n * getters usually just work on the first element.\n */\n private elements: HTMLElementWithComponent[];\n\n /**\n * Creates a DOM element.\n * @param tagName the tag name of the DOM element\n * @param attributes a list of attributes of the element\n * @param component the {@link Component} the DOM element is associated with\n */\n constructor(tagName: string, attributes: {[name: string]: string}, component?: Component<ComponentConfig>);\n /**\n * Selects all elements from the DOM that match the specified selector.\n * @param selector the selector to match DOM elements with\n */\n constructor(selector: string);\n /**\n * Wraps a plain HTMLElement with a DOM instance.\n * @param element the HTMLElement to wrap with DOM\n */\n constructor(element: HTMLElement);\n /**\n * Wraps a list of plain HTMLElements with a DOM instance.\n * @param elements the HTMLElements to wrap with DOM\n */\n constructor(elements: HTMLElement[]);\n /**\n * Wraps the document with a DOM instance. Useful to attach event listeners to the document.\n * @param document the document to wrap\n */\n constructor(document: Document);\n constructor(\n something: string | HTMLElement | HTMLElement[] | Document,\n attributes?: {[name: string]: string},\n component?: Component<ComponentConfig>,\n ) {\n this.document = document; // Set the global document to the local document field\n\n if (something instanceof Array) {\n if (something.length > 0 && something[0] instanceof HTMLElement) {\n let elements = something as HTMLElementWithComponent[];\n this.elements = elements;\n }\n }\n else if (something instanceof HTMLElement) {\n let element = something as HTMLElementWithComponent;\n this.elements = [element];\n }\n else if (something instanceof Document) {\n // When a document is passed in, we do not do anything with it, but by setting this.elements to null\n // we give the event handling method a means to detect if the events should be registered on the document\n // instead of elements.\n this.elements = null;\n }\n else if (attributes) {\n let tagName = something;\n let element = document.createElement(tagName) as HTMLElementWithComponent;\n\n for (let attributeName in attributes) {\n let attributeValue = attributes[attributeName];\n if (attributeValue != null) {\n element.setAttribute(attributeName, attributeValue);\n }\n }\n\n if (component) {\n element.component = component;\n }\n\n this.elements = [element];\n }\n else {\n let selector = something;\n this.elements = this.findChildElements(selector) as HTMLElementWithComponent[];\n }\n }\n\n /**\n * Gets the number of elements that this DOM instance currently holds.\n * @returns {number} the number of elements\n */\n get length(): number {\n return this.elements ? this.elements.length : 0;\n }\n\n /**\n * Gets the HTML elements that this DOM instance currently holds.\n * @returns {HTMLElement[]} the raw HTML elements\n */\n get(): HTMLElementWithComponent[];\n /**\n * Gets an HTML element from the list elements that this DOM instance currently holds.\n * @param index The zero-based index into the element list. Can be negative to return an element from the end,\n * e.g. -1 returns the last element.\n */\n get(index: number): HTMLElementWithComponent;\n get(index?: number): HTMLElementWithComponent | HTMLElementWithComponent[] {\n if (index === undefined) {\n return this.elements;\n } else if (!this.elements || index >= this.elements.length || index < -this.elements.length) {\n return undefined;\n } else if (index < 0) {\n return this.elements[this.elements.length - index];\n } else {\n return this.elements[index];\n }\n }\n\n /**\n * A shortcut method for iterating all elements. Shorts this.elements.forEach(...) to this.forEach(...).\n * @param handler the handler to execute an operation on an element\n */\n private forEach(handler: (element: HTMLElement) => void): void {\n if (!this.elements) {\n return;\n }\n this.elements.forEach((element) => {\n handler(element);\n });\n }\n\n private findChildElementsOfElement(element: HTMLElement | Document, selector: string): HTMLElement[] {\n let childElements = element.querySelectorAll(selector);\n\n // Convert NodeList to Array\n // https://toddmotto.com/a-comprehensive-dive-into-nodelists-arrays-converting-nodelists-and-understanding-the-dom/\n return [].slice.call(childElements);\n }\n\n private findChildElements(selector: string): HTMLElement[] {\n let allChildElements = <HTMLElement[]>[];\n\n if (this.elements) {\n this.forEach((element) => {\n allChildElements = allChildElements.concat(this.findChildElementsOfElement(element, selector));\n });\n }\n else {\n return this.findChildElementsOfElement(document, selector);\n }\n\n return allChildElements;\n }\n\n /**\n * Finds all child elements of all elements matching the supplied selector.\n * @param selector the selector to match with child elements\n * @returns {DOM} a new DOM instance representing all matched children\n */\n find(selector: string): DOM {\n let allChildElements = this.findChildElements(selector) as HTMLElementWithComponent[];\n return new DOM(allChildElements);\n }\n\n /**\n * Focuses to the first input element\n */\n focusToFirstInput() {\n const inputElements = this.findChildElements('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n if (inputElements.length > 0) {\n inputElements[0].focus();\n }\n }\n\n /**\n * Focuses to the first input element\n */\n scrollTo(x: number, y: number) {\n this.elements[0].scrollTo(x, y);\n }\n\n /**\n * Returns a string of the inner HTML content of the first element.\n */\n html(): string;\n /**\n * Sets the inner HTML content of all elements.\n * @param content a string of plain text or HTML markup\n */\n html(content: string): DOM;\n html(content?: string): string | DOM {\n if (arguments.length > 0) {\n return this.setHtml(content);\n }\n else {\n return this.getHtml();\n }\n }\n\n private getHtml(): string | null {\n return this.elements[0].innerHTML;\n }\n\n private setHtml(content: string): DOM {\n if (content === undefined || content == null) {\n // Set to empty string to avoid innerHTML getting set to 'undefined' (all browsers) or 'null' (IE9)\n content = '';\n }\n\n this.forEach((element) => {\n element.innerHTML = content;\n });\n\n return this;\n }\n\n /**\n * Clears the inner HTML of all elements (deletes all children).\n * @returns {DOM}\n */\n empty(): DOM {\n this.forEach((element) => {\n element.innerHTML = '';\n });\n return this;\n }\n\n /**\n * Returns the current value of the first form element, e.g. the selected value of a select box or the text if an\n * input field.\n * @returns {string} the value of a form element\n */\n val(): string {\n let element = this.elements[0];\n\n if (element instanceof HTMLSelectElement || element instanceof HTMLInputElement) {\n return element.value;\n }\n else {\n // TODO add support for missing form elements\n throw new Error(`val() not supported for ${typeof element}`);\n }\n }\n\n /**\n * Returns the value of an attribute on the first element.\n * @param attribute\n */\n attr(attribute: string): string | null;\n /**\n * Sets an attribute on all elements.\n * @param attribute the name of the attribute\n * @param value the value of the attribute\n */\n attr(attribute: string, value: string): DOM;\n attr(attribute: string, value?: string): string | null | DOM {\n if (arguments.length > 1) {\n return this.setAttr(attribute, value);\n }\n else {\n return this.getAttr(attribute);\n }\n }\n\n /**\n * Removes the attribute of the element.\n * @param attribute\n */\n removeAttr(attribute: string) {\n this.forEach((element) => {\n element.removeAttribute(attribute);\n });\n }\n\n private getAttr(attribute: string): string | null {\n return this.elements[0].getAttribute(attribute);\n }\n\n private setAttr(attribute: string, value: string): DOM {\n this.forEach((element) => {\n element.setAttribute(attribute, value);\n });\n return this;\n }\n\n /**\n * Returns the value of a data element on the first element.\n * @param dataAttribute the name of the data attribute without the 'data-' prefix\n */\n data(dataAttribute: string): string | null;\n /**\n * Sets a data attribute on all elements.\n * @param dataAttribute the name of the data attribute without the 'data-' prefix\n * @param value the value of the data attribute\n */\n data(dataAttribute: string, value: string): DOM;\n data(dataAttribute: string, value?: string): string | null | DOM {\n if (arguments.length > 1) {\n return this.setData(dataAttribute, value);\n }\n else {\n return this.getData(dataAttribute);\n }\n }\n\n private getData(dataAttribute: string): string | null {\n return this.elements[0].getAttribute('data-' + dataAttribute);\n }\n\n private setData(dataAttribute: string, value: string): DOM {\n this.forEach((element) => {\n element.setAttribute('data-' + dataAttribute, value);\n });\n return this;\n }\n\n /**\n * Appends one or more DOM elements as children to all elements.\n * @param childElements the chrild elements to append\n * @returns {DOM}\n */\n append(...childElements: DOM[]): DOM {\n this.forEach((element) => {\n childElements.forEach((childElement) => {\n childElement.elements.forEach((_, index) => {\n element.appendChild(childElement.elements[index]);\n });\n });\n });\n return this;\n }\n\n /**\n * Removes all elements from the DOM.\n */\n remove(): void {\n this.forEach((element) => {\n let parent = element.parentNode;\n if (parent) {\n parent.removeChild(element);\n }\n });\n }\n\n /**\n * Returns the offset of the first element from the document's top left corner.\n * @returns {Offset}\n */\n offset(): Offset {\n let element = this.elements[0];\n let elementRect = element.getBoundingClientRect();\n let htmlRect = document.body.parentElement.getBoundingClientRect();\n\n // Virtual viewport scroll handling (e.g. pinch zoomed viewports in mobile browsers or desktop Chrome/Edge)\n // 'normal' zooms and virtual viewport zooms (aka layout viewport) result in different\n // element.getBoundingClientRect() results:\n // - with normal scrolls, the clientRect decreases with an increase in scroll(Top|Left)/page(X|Y)Offset\n // - with pinch zoom scrolls, the clientRect stays the same while scroll/pageOffset changes\n // This means, that the combination of clientRect + scroll/pageOffset does not work to calculate the offset\n // from the document's upper left origin when pinch zoom is used.\n // To work around this issue, we do not use scroll/pageOffset but get the clientRect of the html element and\n // subtract it from the element's rect, which always results in the offset from the document origin.\n // NOTE: the current way of offset calculation was implemented specifically to track event positions on the\n // seek bar, and it might break compatibility with jQuery's offset() method. If this ever turns out to be a\n // problem, this method should be reverted to the old version and the offset calculation moved to the seek bar.\n\n return {\n top: elementRect.top - htmlRect.top,\n left: elementRect.left - htmlRect.left,\n };\n }\n\n /**\n * Returns the width of the first element.\n * @returns {number} the width of the first element\n */\n width(): number {\n // TODO check if this is the same as jQuery's width() (probably not)\n return this.elements[0].offsetWidth;\n }\n\n /**\n * Returns the height of the first element.\n * @returns {number} the height of the first element\n */\n height(): number {\n // TODO check if this is the same as jQuery's height() (probably not)\n return this.elements[0].offsetHeight;\n }\n\n /**\n * Returns the size of the first element.\n * @return {Size} the size of the first element\n */\n size(): Size {\n return { width: this.width(), height: this.height() };\n }\n\n /**\n * Attaches an event handler to one or more events on all elements.\n * @param eventName the event name (or multiple names separated by space) to listen to\n * @param eventHandler the event handler to call when the event fires\n * @param options the options for this event handler\n * @returns {DOM}\n */\n on(eventName: string, eventHandler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): DOM {\n let events = eventName.split(' ');\n\n events.forEach((event) => {\n if (this.elements == null) {\n this.document.addEventListener(event, eventHandler, options);\n }\n else {\n this.forEach((element) => {\n element.addEventListener(event, eventHandler, options);\n });\n }\n });\n\n return this;\n }\n\n /**\n * Removes an event handler from one or more events on all elements.\n * @param eventName the event name (or multiple names separated by space) to remove the handler from\n * @param eventHandler the event handler to remove\n * @param options the options for this event handler\n * @returns {DOM}\n */\n off(eventName: string, eventHandler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): DOM {\n let events = eventName.split(' ');\n\n events.forEach((event) => {\n if (this.elements == null) {\n this.document.removeEventListener(event, eventHandler, options);\n }\n else {\n this.forEach((element) => {\n element.removeEventListener(event, eventHandler, options);\n });\n }\n });\n\n return this;\n }\n\n /**\n * Adds the specified class(es) to all elements.\n * @param className the class(es) to add, multiple classes separated by space\n * @returns {DOM}\n */\n addClass(className: string): DOM {\n this.forEach((element) => {\n if (element.classList) {\n const classNames = className.split(' ')\n .filter(className => className.length > 0);\n\n if (classNames.length > 0) {\n element.classList.add(...classNames);\n }\n }\n else {\n element.className += ' ' + className;\n }\n });\n\n return this;\n }\n\n /**\n * Removed the specified class(es) from all elements.\n * @param className the class(es) to remove, multiple classes separated by space\n * @returns {DOM}\n */\n removeClass(className: string): DOM {\n this.forEach((element) => {\n if (element.classList) {\n const classNames = className.split(' ')\n .filter(className => className.length > 0);\n\n if (classNames.length > 0) {\n element.classList.remove(...classNames);\n }\n }\n else {\n element.className = element.className.replace(\n new RegExp('(^|\\\\b)' + className.split(' ').join('|') + '(\\\\b|$)', 'gi'), ' ');\n }\n });\n\n return this;\n }\n\n /**\n * Checks if any of the elements has the specified class.\n * @param className the class name to check\n * @returns {boolean} true if one of the elements has the class attached, else if no element has it attached\n */\n hasClass(className: string): boolean {\n let hasClass = false;\n\n this.forEach((element) => {\n if (element.classList) {\n if (element.classList.contains(className)) {\n // Since we are inside a handler, we can't just 'return true'. Instead, we save it to a variable\n // and return it at the end of the function body.\n hasClass = true;\n }\n }\n else {\n if (new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className)) {\n // See comment above\n hasClass = true;\n }\n }\n });\n\n return hasClass;\n }\n\n /**\n * Returns the value of a CSS property of the first element.\n * @param propertyName the name of the CSS property to retrieve the value of\n */\n css(propertyName: string): string | null;\n /**\n * Sets the value of a CSS property on all elements.\n * @param propertyName the name of the CSS property to set the value for\n * @param value the value to set for the given CSS property\n */\n css(propertyName: string, value: string): DOM;\n /**\n * Sets a collection of CSS properties and their values on all elements.\n * @param propertyValueCollection an object containing pairs of property names and their values\n */\n css(propertyValueCollection: CssProperties): DOM;\n css(propertyNameOrCollection: string | CssProperties, value?: string): string | null | DOM {\n if (typeof propertyNameOrCollection === 'string') {\n let propertyName = propertyNameOrCollection;\n\n if (arguments.length === 2) {\n return this.setCss(propertyName, value);\n }\n else {\n return this.getCss(propertyName);\n }\n }\n else {\n let propertyValueCollection = propertyNameOrCollection;\n return this.setCssCollection(propertyValueCollection);\n }\n }\n\n /**\n * Removes an inline CSS property if it exists\n * @param propertyName name of the property to remove\n * @param elementIndex index of the element whose CSS property should get removed\n */\n removeCss(propertyName: string, elementIndex = 0): string {\n return this.elements[elementIndex].style.removeProperty(propertyName);\n }\n\n private getCss(propertyName: string): string | null {\n return getComputedStyle(this.elements[0])[<any>propertyName];\n }\n\n private setCss(propertyName: string, value: string): DOM {\n this.forEach((element) => {\n // <any> cast to resolve TS7015: http://stackoverflow.com/a/36627114/370252\n element.style[<any>propertyName] = value;\n });\n return this;\n }\n\n private setCssCollection(ruleValueCollection: {[ruleName: string]: string}): DOM {\n this.forEach((element) => {\n // http://stackoverflow.com/a/34490573/370252\n Object.assign(element.style, ruleValueCollection);\n });\n\n return this;\n }\n}\n","import {ErrorMessageMap, ErrorMessageTranslator} from './components/errormessageoverlay';\nimport { ErrorEvent } from 'bitmovin-player';\nimport { MobileV3PlayerErrorEvent, MobileV3SourceErrorEvent } from './mobilev3playerapi';\n\n/**\n * @category Utils\n */\nexport namespace ErrorUtils {\n\n export const defaultErrorMessages: ErrorMessageMap = {\n 1000: 'Error is unknown',\n 1001: 'The player API is not available after a call to PlayerAPI.destroy.',\n 1100: 'General setup error',\n 1101: 'There was an error when inserting the HTML video element',\n 1102: 'No configuration was provided',\n 1103: 'The license is not valid',\n 1104: 'The the domain-locked player is not authorized to playback on this domain',\n 1105: 'The domain is not allowlisted',\n 1106: 'The license server URL is invalid',\n 1107: 'The impression server URL is invalid',\n 1108: 'Could not initialize a rendering engine',\n 1109: 'The used flash version does not support playback',\n 1110: 'Native Flash is not authorized by a valid Adobe token',\n 1111: 'Flash doesn\\'t have sufficient resources',\n 1112: 'Flash container API not available',\n 1113: 'Protocol not supported. This site has been loaded using \"file\" protocol, but unfortunately this is not supported. Please load the page using a web server (using http or https)',\n 1200: 'General source error',\n 1201: 'No valid source was provided',\n 1202: 'The downloaded manifest is invalid',\n 1203: 'There was no technology detected to playback the provided source',\n 1204: 'The stream type is not supported',\n 1205: 'The forced technology is not supported',\n 1206: 'No stream found for supported technologies.',\n 1207: 'The downloaded segment is empty',\n 1208: 'The manifest could not be loaded',\n 1209: 'Progressive stream type not supported or the stream has an error',\n 1210: 'HLS stream has an error',\n 1211: 'The encryption method is not supported',\n 1300: 'General playback error',\n 1301: 'Video decoder or demuxer had an error with the content',\n 1302: 'General error if Flash renderer has an error',\n 1303: 'Flash doesn\\'t have sufficient resources',\n 1304: 'The transmuxer could not be initialized',\n 1400: 'Network error while downloading',\n 1401: 'The manifest download timed out',\n 1402: 'The segment download timed out',\n 1403: 'The progressive stream download timed out',\n 1404: 'The Certificate could not be loaded',\n 2000: 'General DRM error',\n 2001: 'Required DRM configuration is missing',\n 2002: 'The licensing server URL is missing',\n 2003: 'License request failed',\n 2004: 'Key or KeyId is missing',\n 2005: 'Key size is not supported',\n 2006: 'Unable to instantiate a key system supporting the required combinations',\n 2007: 'Unable to create or initialize key session',\n 2008: 'The MediaKey object could not be created/initialized',\n 2009: 'Key error',\n 2010: 'The key system is not supported',\n 2011: 'The certificate is not valid',\n 2012: 'Invalid header key/value pair for PlayReady license request',\n 2013: 'Content cannot be played back because the output is restricted on this machine',\n 2014: 'DRM error for the Flash renderer',\n 2100: 'General VR error',\n 2101: 'Player technology not compatible with VR playback',\n 3000: 'General module error',\n 3001: 'The definition of the module is invalid (e.g. incomplete).',\n 3002: 'The module definition specifies dependencies but the module is not provided via a function for deferred loading.',\n 3003: 'A module cannot be loaded because it has not been added to the player core.',\n 3004: 'A module cannot be loaded because one or more dependencies are missing.',\n 3100: 'An Advertising module error has occurred. Refer to the attached AdvertisingError.',\n };\n\n export const defaultMobileV3ErrorMessageTranslator = (error: MobileV3PlayerErrorEvent | MobileV3SourceErrorEvent) => {\n return error.message;\n };\n\n export const defaultWebErrorMessageTranslator: ErrorMessageTranslator = (error: ErrorEvent) => {\n const errorMessage = ErrorUtils.defaultErrorMessages[error.code];\n\n if (errorMessage) {\n // Use the error message text if there is one\n return `${errorMessage}\\n(${error.name})`; // default error message style\n } else {\n // Fallback to error code/name if no message is defined\n return `${error.code} ${error.name}`;\n }\n };\n}\n","import {ArrayUtils} from './arrayutils';\nimport { Timeout } from './timeout';\n/**\n * Function interface for event listeners on the {@link EventDispatcher}.\n */\nexport interface EventListener<Sender, Args> {\n (sender: Sender, args: Args): void;\n}\n\n/**\n * Empty type for creating {@link EventDispatcher event dispatchers} that do not carry any arguments.\n */\nexport interface NoArgs {\n}\n\n/**\n * Event args for an event that can be canceled.\n */\nexport interface CancelEventArgs extends NoArgs {\n /**\n * Gets or sets a flag whether the event should be canceled.\n */\n cancel?: boolean;\n}\n\n/**\n * Public interface that represents an event. Can be used to subscribe to and unsubscribe from events.\n */\nexport interface Event<Sender, Args> {\n /**\n * Subscribes an event listener to this event dispatcher.\n * @param listener the listener to add\n */\n subscribe(listener: EventListener<Sender, Args>): void;\n\n /**\n * Subscribes an event listener to this event dispatcher that is only called once.\n * @param listener the listener to add\n */\n subscribeOnce(listener: EventListener<Sender, Args>): void;\n\n /**\n * Subscribes an event listener to this event dispatcher that will be called at a limited rate with a minimum\n * interval of the specified milliseconds.\n * @param listener the listener to add\n * @param rateMs the rate in milliseconds to which calling of the listeners should be limited\n */\n subscribeRateLimited(listener: EventListener<Sender, Args>, rateMs: number): void;\n\n /**\n * Unsubscribes a subscribed event listener from this dispatcher.\n * @param listener the listener to remove\n * @returns {boolean} true if the listener was successfully unsubscribed, false if it isn't subscribed on this\n * dispatcher\n */\n unsubscribe(listener: EventListener<Sender, Args>): boolean;\n}\n\n/**\n * Event dispatcher to subscribe and trigger events. Each event should have its own dispatcher.\n */\nexport class EventDispatcher<Sender, Args> implements Event<Sender, Args> {\n\n private listeners: EventListenerWrapper<Sender, Args>[] = [];\n\n constructor() {\n }\n\n /**\n * {@inheritDoc}\n */\n subscribe(listener: EventListener<Sender, Args>) {\n this.listeners.push(new EventListenerWrapper(listener));\n }\n\n /**\n * {@inheritDoc}\n */\n subscribeOnce(listener: EventListener<Sender, Args>) {\n this.listeners.push(new EventListenerWrapper(listener, true));\n }\n\n /**\n * {@inheritDoc}\n */\n subscribeRateLimited(listener: EventListener<Sender, Args>, rateMs: number) {\n this.listeners.push(new RateLimitedEventListenerWrapper(listener, rateMs));\n }\n\n /**\n * {@inheritDoc}\n */\n unsubscribe(listener: EventListener<Sender, Args>): boolean {\n // Iterate through listeners, compare with parameter, and remove if found\n // NOTE: In case we ever remove all matching listeners instead of just the first, we need to reverse-iterate here\n for (let i = 0; i < this.listeners.length; i++) {\n let subscribedListener = this.listeners[i];\n if (subscribedListener.listener === listener) {\n subscribedListener.clear();\n ArrayUtils.remove(this.listeners, subscribedListener);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Removes all listeners from this dispatcher.\n */\n unsubscribeAll(): void {\n // In case of RateLimitedEventListenerWrapper we need to make sure that the timeout callback won't be called\n for (let listener of this.listeners) {\n listener.clear();\n }\n\n this.listeners = [];\n }\n\n /**\n * Dispatches an event to all subscribed listeners.\n * @param sender the source of the event\n * @param args the arguments for the event\n */\n dispatch(sender: Sender, args: Args = null) {\n let listenersToRemove = [];\n\n // Call every listener\n // We iterate over a copy of the array of listeners to avoid the case where events are not fired on listeners when\n // listeners are unsubscribed from within the event handlers during a dispatch (because the indices change and\n // listeners are shifted within the array).\n // This means that listener x+1 will still be called if unsubscribed from within the handler of listener x, as well\n // as listener y+1 will not be called when subscribed from within the handler of listener y.\n // Array.slice(0) is the fastest array copy method according to: https://stackoverflow.com/a/21514254/370252\n const listeners = this.listeners.slice(0);\n for (let listener of listeners) {\n listener.fire(sender, args);\n\n if (listener.isOnce()) {\n listenersToRemove.push(listener);\n }\n }\n\n // Remove one-time listener\n for (let listenerToRemove of listenersToRemove) {\n ArrayUtils.remove(this.listeners, listenerToRemove);\n }\n }\n\n /**\n * Returns the event that this dispatcher manages and on which listeners can subscribe and unsubscribe event handlers.\n * @returns {Event}\n */\n getEvent(): Event<Sender, Args> {\n // For now, just cast the event dispatcher to the event interface. At some point in the future when the\n // codebase grows, it might make sense to split the dispatcher into separate dispatcher and event classes.\n return <Event<Sender, Args>>this;\n }\n}\n\n/**\n * A basic event listener wrapper to manage listeners within the {@link EventDispatcher}. This is a 'private' class\n * for internal dispatcher use and it is therefore not exported.\n */\nclass EventListenerWrapper<Sender, Args> {\n\n private eventListener: EventListener<Sender, Args>;\n private once: boolean;\n\n constructor(listener: EventListener<Sender, Args>, once: boolean = false) {\n this.eventListener = listener;\n this.once = once;\n }\n\n /**\n * Returns the wrapped event listener.\n * @returns {EventListener<Sender, Args>}\n */\n get listener(): EventListener<Sender, Args> {\n return this.eventListener;\n }\n\n /**\n * Fires the wrapped event listener with the given arguments.\n * @param sender\n * @param args\n */\n fire(sender: Sender, args: Args) {\n this.eventListener(sender, args);\n }\n\n /**\n * Checks if this listener is scheduled to be called only once.\n * @returns {boolean} once if true\n */\n isOnce(): boolean {\n return this.once;\n }\n\n clear(): void {\n }\n}\n\ninterface EventAttributes<Sender, Args> {\n sender: Sender;\n args: Args;\n}\n\n/**\n * Extends the basic {@link EventListenerWrapper} with rate-limiting functionality.\n */\nclass RateLimitedEventListenerWrapper<Sender, Args> extends EventListenerWrapper<Sender, Args> {\n\n private readonly rateMs: number;\n private readonly rateLimitingEventListener: EventListener<Sender, Args>;\n\n // save last seen event attributes\n private lastSeenEvent: EventAttributes<Sender, Args>;\n\n private rateLimitTimout: Timeout;\n\n constructor(listener: EventListener<Sender, Args>, rateMs: number) {\n super(listener); // sets the event listener sink\n\n this.rateMs = rateMs;\n\n // starting limiting the events to the given value\n const startRateLimiting = () => {\n this.rateLimitTimout.start();\n };\n\n // timout for limiting the events\n this.rateLimitTimout = new Timeout(this.rateMs, () => {\n if (this.lastSeenEvent) {\n this.fireSuper(this.lastSeenEvent.sender, this.lastSeenEvent.args);\n startRateLimiting(); // start rateLimiting again to keep rate limit active even after firing the last seen event\n this.lastSeenEvent = null;\n }\n });\n\n // In case the events stopping during the rateLimiting we need to track the last seen one and delegate after the\n // rate limiting is finished. This prevents missing the last update due to the rate limit.\n this.rateLimitingEventListener = (sender: Sender, args: Args) => {\n // only fire events if the rateLimiting is not running\n if (this.shouldFireEvent()) {\n this.fireSuper(sender, args);\n startRateLimiting();\n return;\n }\n\n this.lastSeenEvent = {\n sender: sender,\n args: args,\n };\n };\n }\n\n private shouldFireEvent(): boolean {\n return !this.rateLimitTimout.isActive();\n }\n\n private fireSuper(sender: Sender, args: Args) {\n // Fire the actual external event listener\n super.fire(sender, args);\n }\n\n fire(sender: Sender, args: Args) {\n // Fire the internal rate-limiting listener instead of the external event listener\n this.rateLimitingEventListener(sender, args);\n }\n\n clear(): void {\n super.clear();\n this.rateLimitTimout.clear();\n }\n}\n","const FocusVisibleCssClassName = '{{PREFIX}}-focus-visible';\n\nexport class FocusVisibilityTracker {\n private readonly eventHandlerMap: { [eventName: string]: EventListenerOrEventListenerObject };\n private lastInteractionWasKeyboard: boolean = true;\n\n constructor(private bitmovinUiPrefix: string) {\n this.eventHandlerMap = {\n mousedown: this.onMouseOrPointerOrTouch,\n pointerdown: this.onMouseOrPointerOrTouch,\n touchstart: this.onMouseOrPointerOrTouch,\n keydown: this.onKeyDown,\n focus: this.onFocus,\n blur: this.onBlur,\n };\n this.registerEventListeners();\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n this.lastInteractionWasKeyboard = true;\n };\n\n private onMouseOrPointerOrTouch = () => (this.lastInteractionWasKeyboard = false);\n\n private onFocus = ({ target: element }: FocusEvent) => {\n if (\n this.lastInteractionWasKeyboard &&\n isHtmlElement(element) &&\n isBitmovinUi(element, this.bitmovinUiPrefix) &&\n !element.classList.contains(FocusVisibleCssClassName)\n ) {\n element.classList.add(FocusVisibleCssClassName);\n }\n };\n\n private onBlur = ({ target: element }: FocusEvent) => {\n if (isHtmlElement(element)) {\n element.classList.remove(FocusVisibleCssClassName);\n }\n };\n\n private registerEventListeners(): void {\n for (const event in this.eventHandlerMap) {\n document.addEventListener(event, this.eventHandlerMap[event], true);\n }\n }\n\n private unregisterEventListeners(): void {\n for (const event in this.eventHandlerMap) {\n document.removeEventListener(event, this.eventHandlerMap[event], true);\n }\n }\n\n public release(): void {\n this.unregisterEventListeners();\n }\n}\n\nfunction isBitmovinUi(element: Element, bitmovinUiPrefix: string): boolean {\n return element.id.indexOf(bitmovinUiPrefix) === 0;\n}\n\nfunction isHtmlElement(element: unknown): element is HTMLElement & { classList: DOMTokenList } {\n return (\n element instanceof HTMLElement && element.classList instanceof DOMTokenList\n );\n}\n","import { PlayerAPI } from 'bitmovin-player';\n/**\n * The Group Playback API offers control over synchronized playback of a group of clients, e.g. for Apple SharePlay\n * sessions.\n\n * Note: The API currently only covers the immediate needs of the iOS SDK in combination with our UI which is regarding\n * temporarily suspending synchronization of the player from the group. But it is open to be extended as needed in the\n * future.\n */\n\n/**\n * Reason for suspending the synchronization with the group.\n */\nexport enum GroupPlaybackSuspensionReason {\n UserIsScrubbing = 'userIsScrubbing',\n}\n\n/**\n * A representation of a temporary break in participation.\n */\nexport interface GroupPlaybackSuspension {\n /**\n * The reason for the suspension.\n */\n reason: GroupPlaybackSuspensionReason;\n\n /**\n * A unique identifier.\n */\n id: string;\n}\n\n/**\n * Options to be considered upon ending a suspension.\n */\ninterface EndGroupPlaybackSuspensionOptions {\n /**\n * A proposed time for the group to seek to.\n */\n proposedPlaybackTime?: number;\n}\n\n/**\n * Group Playback API offering control over the player's participation in synchronized playback of a group of clients.\n * For example, an Apple SharePlay session.\n */\ninterface GroupPlaybackAPI {\n /**\n * Begins a new suspension.\n *\n * Temporarily suspends the local player's synchronization with the group. While suspended, any local playback control\n * action (e.g. play, pause, seek) will not be forwarded to the group and any action originating from another group\n * participant will not be performed on the local player.\n *\n * @remarks\n * It is possible for multiple suspensions to exist exist simultaneously with different suspension reasons. The player\n * will re-synchronize with the group once all existing suspensions have ended.\n *\n * @param reason - The reason for the suspension.\n * @returns A suspension object.\n */\n beginSuspension(reason: GroupPlaybackSuspensionReason): GroupPlaybackSuspension;\n\n /**\n * Ends the given suspension.\n *\n * @param suspension - The suspension to be ended.\n * @param options - Optional. Options to be considered when ending the suspension, e.g. a proposed seek time for the group.\n */\n endSuspension(suspension: GroupPlaybackSuspension, options?: EndGroupPlaybackSuspensionOptions): void;\n\n /**\n * Whether the player is currently participating in a group playback session.\n */\n hasJoined(): boolean;\n\n /**\n * Whether the player is currently suspending synchronization with the group.\n * Can only return true if `hasJoined()` also is true.\n */\n isSuspended(): boolean;\n}\n\n\nexport interface ExtendedPlayerAPI extends PlayerAPI {\n /**\n * Group Playback API\n *\n * @remarks\n * This API is optional as not every platform supports group playback.\n */\n groupPlayback?: GroupPlaybackAPI;\n}\n","export namespace Guid {\n\n let guid = 1;\n\n export function next() {\n return guid++;\n }\n}\n","import {DOM} from './dom';\n\nexport interface ImageLoadedCallback {\n (url: string, width: number, height: number): void;\n}\n\ninterface ImageLoaderState {\n url: string;\n image: DOM;\n loadedCallback: ImageLoadedCallback;\n loaded: boolean;\n width: number;\n height: number;\n}\n\n/**\n * Tracks the loading state of images.\n */\nexport class ImageLoader {\n\n private state: { [url: string]: ImageLoaderState; } = {};\n\n /**\n * Loads an image and call the callback once the image is loaded. If the image is already loaded, the callback\n * is called immediately, else it is called once loading has finished. Calling this method multiple times for the\n * same image while it is loading calls only let callback passed into the last call.\n * @param url The url to the image to load\n * @param loadedCallback The callback that is called when the image is loaded\n */\n load(url: string, loadedCallback: ImageLoadedCallback): void {\n if (!this.state[url]) {\n // When the image was never attempted to be loaded before, we create a state and store it in the state map\n // for later use when the same image is requested to be loaded again.\n let state: ImageLoaderState = {\n url: url,\n image: new DOM('img', {}),\n loadedCallback: loadedCallback,\n loaded: false,\n width: 0,\n height: 0,\n };\n this.state[url] = state;\n\n // Listen to the load event, update the state and call the callback once the image is loaded\n state.image.on('load', (e) => {\n state.loaded = true;\n state.width = (<HTMLImageElement>state.image.get(0)).width;\n state.height = (<HTMLImageElement>state.image.get(0)).height;\n\n this.callLoadedCallback(state);\n });\n\n // Set the image URL to start the loading\n state.image.attr('src', state.url);\n } else {\n // We have a state for the requested image, so it is either already loaded or currently loading\n let state = this.state[url];\n\n // We overwrite the callback to make sure that only the callback of the latest call gets executed.\n // Earlier callbacks become invalid once a new load call arrives, and they are not called as long as the image\n // is not loaded.\n state.loadedCallback = loadedCallback;\n\n // When the image is already loaded, we directly execute the callback instead of waiting for the load event\n if (state.loaded) {\n this.callLoadedCallback(state);\n }\n }\n }\n\n private callLoadedCallback(state: ImageLoaderState): void {\n state.loadedCallback(state.url, state.width, state.height);\n }\n}\n","import vocabularyDe from './languages/de.json';\nimport vocabularyEn from './languages/en.json';\nimport vocabularyEs from './languages/es.json';\nimport vocabularyNl from './languages/nl.json';\n\nimport { LocalizationConfig } from '../uimanager.js';\n\nexport const defaultVocabularies: Vocabularies = {\n 'en': vocabularyEn,\n 'de': vocabularyDe,\n 'es': vocabularyEs,\n 'nl': vocabularyNl,\n};\n\nconst defaultLocalizationConfig: LocalizationConfig = {\n language: 'en',\n vocabularies: defaultVocabularies,\n};\n\n/**\n * @category Localization\n */\nexport type Localizer = () => string;\n/**\n * @category Localization\n */\nexport type LocalizableText = string | Localizer;\n\n/**\n * @category Localization\n */\nexport interface Vocabulary {\n 'settings.video.quality': string;\n 'settings.audio.quality': string;\n 'settings.audio.track': string;\n 'settings.audio.mute': string;\n 'settings.audio.volume': string;\n 'settings.subtitles': string;\n 'settings.subtitles.font.color': string;\n 'settings.subtitles.font.opacity': string;\n 'settings.subtitles.background.color': string;\n 'settings.subtitles.background.opacity': string;\n 'settings.subtitles.font.size': string;\n 'settings.subtitles.characterEdge': string;\n 'settings.subtitles.characterEdge.raised': string;\n 'settings.subtitles.characterEdge.depressed': string;\n 'settings.subtitles.characterEdge.uniform': string;\n 'settings.subtitles.characterEdge.dropshadowed': string;\n 'settings.subtitles.font.family': string;\n 'settings.subtitles.font.family.monospacedserif': string;\n 'settings.subtitles.font.family.proportionalserif': string;\n 'settings.subtitles.font.family.monospacedsansserif': string;\n 'settings.subtitles.font.family.proportionalsansserif': string;\n 'settings.subtitles.font.family.casual': string;\n 'settings.subtitles.font.family.cursive': string;\n 'settings.subtitles.font.family.smallcapital': string;\n 'settings.subtitles.window.color': string;\n 'settings.subtitles.window.opacity': string;\n 'play': string;\n 'settings.time.hours': string;\n 'settings.time.minutes': string;\n 'settings.time.seconds': string;\n 'colors.white': string;\n 'colors.black': string;\n 'colors.red': string;\n 'colors.green': string;\n 'colors.blue': string;\n 'colors.cyan': string;\n 'colors.yellow': string;\n 'colors.magenta': string;\n 'percent': string;\n 'settings': string;\n 'ads.remainingTime': string;\n 'pictureInPicture': string;\n 'appleAirplay': string;\n 'googleCast': string;\n 'vr': string;\n 'off': string;\n 'auto': string;\n 'back': string;\n 'reset': string;\n 'replay': string;\n 'normal': string;\n 'default': string;\n 'open': string;\n 'close': string;\n 'fullscreen': string;\n 'speed': string;\n 'playPause': string;\n 'live': string;\n 'subtitle.example': string;\n 'subtitle.select': string;\n 'playingOn': string;\n 'connectingTo': string;\n 'watermarkLink': string;\n 'controlBar': string;\n 'player': string;\n 'seekBar': string;\n 'seekBar.value': string;\n 'seekBar.timeshift': string;\n 'seekBar.durationText': string;\n 'ecoMode': string;\n 'ecoMode.title': string;\n}\n\n/**\n * @category Localization\n */\nexport type CustomVocabulary<V> = V & Partial<Vocabulary>;\n\n/**\n * @category Localization\n */\nexport interface Vocabularies {\n [key: string]: CustomVocabulary<Record<string, string>>;\n}\n\n/**\n * @category Localization\n */\nexport class I18n {\n private language: string;\n private vocabulary: CustomVocabulary<Record<string, string>>;\n\n constructor(config: LocalizationConfig) {\n this.setConfig(config);\n }\n\n public setConfig(config: LocalizationConfig) {\n const mergedConfig = { ...defaultLocalizationConfig, ...config };\n const detectBrowserLanguage = mergedConfig.language === 'auto';\n const vocabularies = this.mergeVocabulariesWithDefaultVocabularies(mergedConfig.vocabularies);\n this.initializeLanguage(mergedConfig.language, detectBrowserLanguage, vocabularies);\n this.initializeVocabulary(vocabularies);\n }\n\n private static containsLanguage(vocabularies: Vocabularies, language: string) {\n return vocabularies.hasOwnProperty(language);\n }\n\n private mergeVocabulariesWithDefaultVocabularies(vocabularies: Vocabularies = {}) {\n const rawVocabularies: Vocabularies = { ...defaultVocabularies, ...vocabularies };\n return Object.keys(rawVocabularies).reduce((mergedVocabularies, language) => {\n let vocabulary = rawVocabularies[language];\n if (I18n.containsLanguage(defaultVocabularies, language) && I18n.containsLanguage(vocabularies, language)) {\n vocabulary = { ...defaultVocabularies[language], ...vocabularies[language] };\n }\n return { ...mergedVocabularies, [language]: vocabulary };\n }, {});\n }\n\n private initializeLanguage(\n language: string,\n browserLanguageDetectionEnabled: boolean,\n vocabularies: Vocabularies,\n ) {\n if (browserLanguageDetectionEnabled) {\n const userLanguage = window.navigator.language;\n\n if (I18n.containsLanguage(vocabularies, userLanguage)) {\n this.language = userLanguage;\n return;\n }\n const shortenedUserLanguage = userLanguage.slice(0, 2);\n if (I18n.containsLanguage(vocabularies, shortenedUserLanguage)) {\n this.language = shortenedUserLanguage;\n return;\n }\n }\n\n this.language = language;\n }\n\n private initializeVocabulary(vocabularies: Vocabularies) {\n this.vocabulary = ['en', this.language]\n .reduce((vocab, lang) => ({ ...vocab, ...(vocabularies[lang] || {}) }), {});\n }\n\n private replaceVariableWithPlaceholderIfExists(text: string, config: any) {\n const matches = text.match(new RegExp('{[a-zA-Z0-9]+}', 'g'));\n if (matches.length === 0) {\n return text;\n }\n\n return matches\n .map((m: string) => ({ match: m, key: m.slice(1, -1) }))\n .reduce((str, { key, match }) => config.hasOwnProperty(key) ? str.replace(match, config[key]) : str, text);\n }\n\n public getLocalizer<V extends CustomVocabulary<Record<string, string>> = CustomVocabulary<Record<string, string>>>(\n key: keyof V,\n config?: Record<string, string | number>,\n ): Localizer {\n return () => {\n if (key == null) { // because sometimes we call toDomElement() without configuring the component or setting text...\n return undefined;\n }\n let vocabularyString = this.vocabulary[key as string];\n\n if (vocabularyString == null) {\n vocabularyString = key as string;\n }\n\n if (config != null) {\n vocabularyString = this.replaceVariableWithPlaceholderIfExists(vocabularyString, config);\n }\n\n return vocabularyString;\n };\n }\n\n public performLocalization(text: LocalizableText) {\n return typeof text === 'function' ? text() : text;\n }\n}\n\n/**\n * @category Localization\n */\nexport const i18n = new I18n(defaultLocalizationConfig);\n","module.exports={\n \"settings.video.quality\": \"Videoqualität\",\n \"settings.audio.quality\": \"Audioqualität\",\n \"settings.audio.track\": \"Audiospur\",\n \"speed\": \"Geschwindigkeit\",\n \"play\": \"Abspielen\",\n \"pause\": \"Pause\",\n \"playPause\": \"Abspielen/Pause\",\n \"open\": \"öffnen\",\n \"close\": \"Schließen\",\n \"settings.audio.mute\": \"Stummschaltung\",\n \"settings.audio.volume\": \"Lautstärke\",\n \"pictureInPicture\": \"Bild im Bild\",\n \"appleAirplay\": \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\": \"VR\",\n \"settings\": \"Einstellungen\",\n \"fullscreen\": \"Vollbild\",\n \"off\": \"aus\",\n \"settings.subtitles\": \"Untertitel\",\n \"settings.subtitles.font.size\": \"Größe\",\n \"settings.subtitles.font.family\": \"Schriftart\",\n \"settings.subtitles.font.color\": \"Farbe\",\n \"settings.subtitles.font.opacity\": \"Deckkraft\",\n \"settings.subtitles.characterEdge\": \"Ränder\",\n \"settings.subtitles.background.color\": \"Hintergrundfarbe\",\n \"settings.subtitles.background.opacity\": \"Hintergrunddeckkraft\",\n \"settings.subtitles.window.color\": \"Hintergrundfarbe\",\n \"settings.subtitles.window.opacity\": \"Hintergrunddeckkraft\",\n \"settings.time.hours\": \"Stunden\",\n \"settings.time.minutes\": \"Minuten\",\n \"settings.time.seconds\": \"Sekunden\",\n \"back\": \"Zurück\",\n \"reset\": \"Zurücksetzen\",\n \"replay\": \"Wiederholen\",\n \"ads.remainingTime\": \"Diese Anzeige endet in {remainingTime} Sekunden\",\n \"default\": \"standard\",\n \"colors.white\": \"weiß\",\n \"colors.black\": \"schwarz\",\n \"colors.red\": \"rot\",\n \"colors.green\": \"grün\",\n \"colors.blue\": \"blau\",\n \"colors.yellow\": \"gelb\",\n \"subtitle.example\": \"Beispiel Untertitel\",\n \"subtitle.select\": \"Untertitel auswählen\",\n \"playingOn\": \"Spielt auf <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Verbindung mit <strong>{castDeviceName}</strong> wird hergestellt...\",\n \"watermarkLink\": \"Link zum Homepage\",\n \"controlBar\": \"Videoplayer Kontrollen\",\n \"player\": \"Video player\",\n \"seekBar\": \"Video-Timeline\",\n \"seekBar.value\": \"Wert\",\n \"seekBar.timeshift\": \"Timeshift\",\n \"seekBar.durationText\": \"aus\",\n \"quickseek.forward\": \"Vor\",\n \"quickseek.rewind\": \"Zurück\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\":\"Eco Mode\"\n}\n","module.exports={\n \"settings.video.quality\": \"Video Quality\",\n \"settings.audio.quality\": \"Audio Quality\",\n \"settings.audio.track\": \"Audio Track\",\n \"settings.audio.mute\" : \"Mute\",\n \"settings.audio.volume\" : \"Volume\",\n \"settings.subtitles.window.color\" : \"Window color\",\n \"settings.subtitles.window.opacity\" : \"Window opacity\",\n \"settings.subtitles\" : \"Subtitles\",\n \"settings.subtitles.font.color\" : \"Font color\",\n \"settings.subtitles.font.opacity\" : \"Font opacity\",\n \"settings.subtitles.background.color\" : \"Background color\",\n \"settings.subtitles.background.opacity\": \"Background opacity\",\n \"colors.white\": \"white\",\n \"colors.black\": \"black\",\n \"colors.red\": \"red\",\n \"colors.green\": \"green\",\n \"colors.blue\": \"blue\",\n \"colors.cyan\": \"cyan\",\n \"colors.yellow\": \"yellow\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"Font size\",\n \"settings.subtitles.characterEdge\": \"Character edge\",\n \"settings.subtitles.characterEdge.raised\": \"raised\",\n \"settings.subtitles.characterEdge.depressed\": \"depressed\",\n \"settings.subtitles.characterEdge.uniform\": \"uniform\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"drop shadowed\",\n \"settings.subtitles.font.family\": \"Font family\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospaced serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportional serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospaced sans serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportional sans serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursive\",\n \"settings.subtitles.font.family.smallcapital\": \"small capital\",\n \"settings.time.hours\": \"Hours\",\n \"settings.time.minutes\": \"Minutes\",\n \"settings.time.seconds\": \"Seconds\",\n \"ads.remainingTime\": \"This ad will end in {remainingTime} seconds.\",\n \"settings\": \"Settings\",\n \"fullscreen\" : \"Fullscreen\",\n \"speed\": \"Speed\",\n \"playPause\" : \"Play/Pause\",\n \"play\": \"Play\",\n \"pause\": \"Pause\",\n \"open\": \"open\",\n \"close\": \"Close\",\n \"pictureInPicture\": \"Picture-in-Picture\",\n \"appleAirplay\" : \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\" : \"VR\",\n \"off\": \"off\",\n \"auto\": \"auto\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\":\"Eco Mode\",\n \"back\" : \"Back\",\n \"reset\": \"Reset\",\n \"replay\": \"Replay\",\n \"normal\": \"normal\",\n \"default\": \"default\",\n \"live\": \"Live\",\n \"subtitle.example\": \"example subtitle\",\n \"subtitle.select\": \"Select subtitle\",\n \"playingOn\": \"Playing on <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Connecting to <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Link to Homepage\",\n \"controlBar\": \"Video player controls\",\n \"player\": \"Video player\",\n \"seekBar\": \"Video timeline\",\n \"seekBar.value\": \"Value\",\n \"seekBar.timeshift\": \"Timeshift\",\n \"seekBar.durationText\": \"out of\",\n \"quickseek.forward\": \"Fast Forward\",\n \"quickseek.rewind\": \"Rewind\"\n}\n","module.exports={\n \"settings.video.quality\": \"Calidad de Video\",\n \"settings.audio.quality\": \"Calidad de Audio\",\n \"settings.audio.track\": \"Pista de Audio\",\n \"settings.audio.mute\" : \"Silencio\",\n \"settings.audio.volume\" : \"Volumen\",\n \"settings.subtitles.window.color\" : \"color de Ventana\",\n \"settings.subtitles.window.opacity\" : \"opacidad de Ventana\",\n \"settings.subtitles\" : \"Subtítulos\",\n \"settings.subtitles.font.color\" : \"color de Fuente\",\n \"settings.subtitles.font.opacity\" : \"opacidad de Fuente\",\n \"settings.subtitles.background.color\" : \"color de Fondo\",\n \"settings.subtitles.background.opacity\": \"opacidad de Fondo\",\n \"colors.white\": \"blanco\",\n \"colors.black\": \"negro\",\n \"colors.red\": \"rojo\",\n \"colors.green\": \"verde\",\n \"colors.blue\": \"azul\",\n \"colors.cyan\": \"cian\",\n \"colors.yellow\": \"amarillo\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"tamaño de Fuente\",\n \"settings.subtitles.characterEdge\": \"borde del Caracter\",\n \"settings.subtitles.characterEdge.raised\": \"alzado\",\n \"settings.subtitles.characterEdge.depressed\": \"discreto\",\n \"settings.subtitles.characterEdge.uniform\": \"uniforme\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"sombreado\",\n \"settings.subtitles.font.family\": \"tipo de Fuente\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospaced serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportional serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospaced sans serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportional sans serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursiva\",\n \"settings.subtitles.font.family.smallcapital\": \"small capital\",\n \"settings.time.hours\": \"Horas\",\n \"settings.time.minutes\": \"Minutos\",\n \"settings.time.seconds\": \"Segundos\",\n \"ads.remainingTime\": \"Este anuncio acabará en {remainingTime} segundos.\",\n \"settings\": \"Configuración\",\n \"fullscreen\" : \"Pantalla Completa\",\n \"speed\": \"Velocidad\",\n \"playPause\" : \"Reproducir/Pausa\",\n \"play\": \"Reproducir\",\n \"pause\": \"Pausa\",\n \"open\": \"Abrir\",\n \"close\": \"Cerrar\",\n \"pictureInPicture\": \"Imagen en Imagen\",\n \"appleAirplay\" : \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\" : \"VR\",\n \"off\": \"off\",\n \"auto\": \"auto\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\": \"Eco Mode\",\n \"back\" : \"Atrás\",\n \"reset\": \"Reiniciar\",\n \"replay\": \"Rebobinar\",\n \"normal\": \"normal\",\n \"default\": \"predeterminado\",\n \"live\": \"Directo\",\n \"subtitle.example\": \"Ejemplo de Subtítulo\",\n \"subtitle.select\": \"Seleccionar subtítulo\",\n \"playingOn\": \"Reproduciendo en <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Conectando a <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Enlace al inicio\",\n \"controlBar\": \"Controles del Reproductor\",\n \"player\": \"Reproductor de Video\",\n \"seekBar\": \"Línea de Tiempo\",\n \"seekBar.value\": \"posición\",\n \"seekBar.timeshift\": \"cambio de posición\",\n \"seekBar.durationText\": \"de\",\n \"quickseek.forward\": \"Adelantar\",\n \"quickseek.rewind\": \"Rebobinar\"\n}","module.exports={\n \"settings.video.quality\": \"Videokwaliteit\",\n \"settings.audio.quality\": \"Audiokwaliteit\",\n \"settings.audio.track\": \"Audiospoor\",\n \"settings.audio.mute\": \"Dempen\",\n \"settings.audio.volume\": \"Volume\",\n \"settings.subtitles.window.color\": \"Vensterkleur\",\n \"settings.subtitles.window.opacity\": \"Venster doorzichtigheid\",\n \"settings.subtitles\": \"Ondertiteling\",\n \"settings.subtitles.font.color\": \"Lettertype kleur\",\n \"settings.subtitles.font.opacity\": \"Lettertype doorzichtigheid\",\n \"settings.subtitles.background.color\": \"Achtergrondkleur\",\n \"settings.subtitles.background.opacity\": \"Achtergrond doorzichtigheid\",\n \"colors.white\": \"wit\",\n \"colors.black\": \"zwart\",\n \"colors.red\": \"rood\",\n \"colors.green\": \"groen\",\n \"colors.blue\": \"blauw\",\n \"colors.cyan\": \"cyaan\",\n \"colors.yellow\": \"geel\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"Lettertype grootte\",\n \"settings.subtitles.characterEdge\": \"Lettertype rand\",\n \"settings.subtitles.characterEdge.raised\": \"verhoogd\",\n \"settings.subtitles.characterEdge.depressed\": \"verlaagd\",\n \"settings.subtitles.characterEdge.uniform\": \"uniform\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"schaduw\",\n \"settings.subtitles.font.family\": \"Standaard lettertype\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospace serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportioneel serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospace sans-serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportioneel sans-serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursief\",\n \"settings.subtitles.font.family.smallcapital\": \"kleine hoofdletters\",\n \"settings.time.hours\": \"Uren\",\n \"settings.time.minutes\": \"Minuten\",\n \"settings.time.seconds\": \"Seconden\",\n \"ads.remainingTime\": \"Deze advertentie eindigt in {remainingTime} seconden.\",\n \"settings\": \"Instellingen\",\n \"fullscreen\": \"Volledig scherm\",\n \"speed\": \"Snelheid\",\n \"playPause\": \"Afspelen/Pauzeren\",\n \"play\": \"Afspelen\",\n \"pause\": \"Pauzeren\",\n \"open\": \"Openen\",\n \"close\": \"Sluiten\",\n \"pictureInPicture\": \"Picture-in-Picture\",\n \"appleAirplay\": \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\": \"VR\",\n \"off\": \"uit\",\n \"auto\": \"automatisch\",\n \"ecoMode\": \"Eco-modus\",\n \"ecoMode.title\": \"Eco-modus\",\n \"back\": \"Terug\",\n \"reset\": \"Reset\",\n \"replay\": \"Opnieuw afspelen\",\n \"normal\": \"normaal\",\n \"default\": \"standaard\",\n \"live\": \"Live\",\n \"subtitle.example\": \"voorbeeld ondertiteling\",\n \"subtitle.select\": \"Selecteer ondertiteling\",\n \"playingOn\": \"Speelt af op <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Verbinden met <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Link naar homepage\",\n \"controlBar\": \"Videospeler bediening\",\n \"player\": \"Videospeler\",\n \"seekBar\": \"Video tijdlijn\",\n \"seekBar.value\": \"Waarde\",\n \"seekBar.timeshift\": \"Tijdverschuiving\",\n \"seekBar.durationText\": \"van\",\n \"quickseek.forward\": \"Vooruitspoelen\",\n \"quickseek.rewind\": \"Terugspoelen\"\n}","export const version: string = '{{VERSION}}';\n// Management\nexport * from './uimanager';\nexport * from './uiconfig';\n// Factories\nexport { UIFactory } from './uifactory';\nexport { DemoFactory } from './demofactory';\n// Utils\nexport { ArrayUtils } from './arrayutils';\nexport { StringUtils } from './stringutils';\nexport { PlayerUtils } from './playerutils';\nexport { UIUtils } from './uiutils';\nexport { BrowserUtils } from './browserutils';\nexport { StorageUtils } from './storageutils';\nexport { ErrorUtils } from './errorutils';\n// Localization\nexport { i18n, I18n, Vocabulary, Vocabularies, CustomVocabulary, LocalizableText, Localizer } from './localization/i18n';\n// Spatial Navigation\nexport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nexport { NavigationGroup } from './spatialnavigation/navigationgroup';\nexport { RootNavigationGroup } from './spatialnavigation/rootnavigationgroup';\nexport { ListNavigationGroup, ListOrientation } from './spatialnavigation/ListNavigationGroup';\n// Components\nexport { Button, ButtonConfig } from './components/button';\nexport { ControlBar, ControlBarConfig } from './components/controlbar';\nexport { FullscreenToggleButton } from './components/fullscreentogglebutton';\nexport { HugePlaybackToggleButton } from './components/hugeplaybacktogglebutton';\nexport { PlaybackTimeLabel, PlaybackTimeLabelConfig, PlaybackTimeLabelMode } from './components/playbacktimelabel';\nexport { PlaybackToggleButton, PlaybackToggleButtonConfig } from './components/playbacktogglebutton';\nexport { SeekBar, SeekBarConfig, SeekPreviewEventArgs, SeekBarMarker } from './components/seekbar';\nexport { SelectBox } from './components/selectbox';\nexport { ItemSelectionList } from './components/itemselectionlist';\nexport { SettingsPanel, SettingsPanelConfig } from './components/settingspanel';\nexport { SettingsToggleButton, SettingsToggleButtonConfig } from './components/settingstogglebutton';\nexport { ToggleButton, ToggleButtonConfig } from './components/togglebutton';\nexport { VideoQualitySelectBox } from './components/videoqualityselectbox';\nexport { VolumeToggleButton } from './components/volumetogglebutton';\nexport { VRToggleButton } from './components/vrtogglebutton';\nexport { Watermark, WatermarkConfig } from './components/watermark';\nexport { UIContainer, UIContainerConfig } from './components/uicontainer';\nexport { Container, ContainerConfig } from './components/container';\nexport { Label, LabelConfig } from './components/label';\nexport { AudioQualitySelectBox } from './components/audioqualityselectbox';\nexport { AudioTrackSelectBox } from './components/audiotrackselectbox';\nexport { CastStatusOverlay } from './components/caststatusoverlay';\nexport { CastToggleButton } from './components/casttogglebutton';\nexport { Component, ComponentConfig, ComponentHoverChangedEventArgs } from './components/component';\nexport { ErrorMessageOverlay, ErrorMessageOverlayConfig, ErrorMessageTranslator, ErrorMessageMap } from './components/errormessageoverlay';\nexport { RecommendationOverlay } from './components/recommendationoverlay';\nexport { SeekBarLabel, SeekBarLabelConfig } from './components/seekbarlabel';\nexport { SubtitleOverlay } from './components/subtitleoverlay';\nexport { SubtitleSelectBox } from './components/subtitleselectbox';\nexport { TitleBar, TitleBarConfig } from './components/titlebar';\nexport { VolumeControlButton, VolumeControlButtonConfig } from './components/volumecontrolbutton';\nexport { ClickOverlay, ClickOverlayConfig } from './components/clickoverlay';\nexport { AdSkipButton, AdSkipButtonConfig } from './components/adskipbutton';\nexport { AdMessageLabel } from './components/admessagelabel';\nexport { AdClickOverlay } from './components/adclickoverlay';\nexport { PlaybackSpeedSelectBox } from './components/playbackspeedselectbox';\nexport { HugeReplayButton } from './components/hugereplaybutton';\nexport { BufferingOverlay, BufferingOverlayConfig } from './components/bufferingoverlay';\nexport { CastUIContainer } from './components/castuicontainer';\nexport { PlaybackToggleOverlay, PlaybackToggleOverlayConfig } from './components/playbacktoggleoverlay';\nexport { CloseButton, CloseButtonConfig } from './components/closebutton';\nexport { MetadataLabel, MetadataLabelContent, MetadataLabelConfig } from './components/metadatalabel';\nexport { AirPlayToggleButton } from './components/airplaytogglebutton';\nexport { VolumeSlider, VolumeSliderConfig } from './components/volumeslider';\nexport { PictureInPictureToggleButton } from './components/pictureinpicturetogglebutton';\nexport { Spacer } from './components/spacer';\nexport { BackgroundColorSelectBox } from './components/subtitlesettings/backgroundcolorselectbox';\nexport { BackgroundOpacitySelectBox } from './components/subtitlesettings/backgroundopacityselectbox';\nexport { CharacterEdgeSelectBox } from './components/subtitlesettings/characteredgeselectbox';\nexport { FontColorSelectBox } from './components/subtitlesettings/fontcolorselectbox';\nexport { FontFamilySelectBox } from './components/subtitlesettings/fontfamilyselectbox';\nexport { FontOpacitySelectBox } from './components/subtitlesettings/fontopacityselectbox';\nexport { FontSizeSelectBox } from './components/subtitlesettings/fontsizeselectbox';\nexport { SubtitleSettingSelectBox } from './components/subtitlesettings/subtitlesettingselectbox';\nexport { SubtitleSettingsLabel } from './components/subtitlesettings/subtitlesettingslabel';\nexport { WindowColorSelectBox } from './components/subtitlesettings/windowcolorselectbox';\nexport { WindowOpacitySelectBox } from './components/subtitlesettings/windowopacityselectbox';\nexport { SubtitleSettingsResetButton } from './components/subtitlesettings/subtitlesettingsresetbutton';\nexport { ListBox } from './components/listbox';\nexport { SubtitleListBox } from './components/subtitlelistbox';\nexport { AudioTrackListBox } from './components/audiotracklistbox';\nexport { SettingsPanelPage } from './components/settingspanelpage';\nexport { SettingsPanelPageBackButton } from './components/settingspanelpagebackbutton';\nexport { SettingsPanelPageOpenButton } from './components/settingspanelpageopenbutton';\nexport { SubtitleSettingsPanelPage, SubtitleSettingsPanelPageConfig } from './components/subtitlesettings/subtitlesettingspanelpage';\nexport { SettingsPanelItem } from './components/settingspanelitem';\nexport { ReplayButton } from './components/replaybutton';\nexport { QuickSeekButton, QuickSeekButtonConfig } from './components/quickseekbutton';\nexport { ListSelector, ListSelectorConfig, ListItem, ListItemFilter, ListItemLabelTranslator } from './components/listselector';\n\n// Object.assign polyfill for ES5/IE9\n// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\nif (typeof Object.assign !== 'function') {\n Object.assign = function(target: any) {\n 'use strict';\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n target = Object(target);\n for (let index = 1; index < arguments.length; index++) {\n let source = arguments[index];\n if (source != null) {\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n }\n return target;\n };\n}\n","import { PlayerAPI, PlayerEvent, PlayerEventBase, PlayerEventCallback } from 'bitmovin-player';\nimport { WrappedPlayer } from './uimanager';\n\nexport enum MobileV3PlayerEvent {\n SourceError = 'sourceerror',\n PlayerError = 'playererror',\n PlaylistTransition = 'playlisttransition',\n}\n\nexport interface MobileV3PlayerErrorEvent extends PlayerEventBase {\n code: number;\n message: string;\n}\n\nexport interface MobileV3SourceErrorEvent extends PlayerEventBase {\n code: number;\n message: string;\n}\n\nexport type MobileV3PlayerEventType = PlayerEvent | MobileV3PlayerEvent;\n\nexport interface MobileV3PlayerAPI extends PlayerAPI {\n on(eventType: MobileV3PlayerEventType, callback: PlayerEventCallback): void;\n exports: PlayerAPI['exports'] & { PlayerEvent: MobileV3PlayerEventType };\n}\n\nexport function isMobileV3PlayerAPI(player: WrappedPlayer | PlayerAPI | MobileV3PlayerAPI): player is MobileV3PlayerAPI {\n for (const key in MobileV3PlayerEvent) {\n if (MobileV3PlayerEvent.hasOwnProperty(key) && !player.exports.PlayerEvent.hasOwnProperty(key)) {\n return false;\n }\n }\n\n return true;\n}\n","import {Event, EventDispatcher, NoArgs} from './eventdispatcher';\nimport {BrowserUtils} from './browserutils';\nimport { UIInstanceManager } from './uimanager';\nimport { PlayerAPI, TimeRange } from 'bitmovin-player';\n\n/**\n * @category Utils\n */\nexport namespace PlayerUtils {\n\n export enum PlayerState {\n Idle,\n Prepared,\n Playing,\n Paused,\n Finished,\n }\n\n export function isTimeShiftAvailable(player: PlayerAPI): boolean {\n return player.isLive() && player.getMaxTimeShift() !== 0;\n }\n\n export function getState(player: PlayerAPI): PlayerState {\n if (player.hasEnded()) {\n return PlayerState.Finished;\n } else if (player.isPlaying()) {\n return PlayerState.Playing;\n } else if (player.isPaused()) {\n return PlayerState.Paused;\n } else if (player.getSource() != null) {\n return PlayerState.Prepared;\n } else {\n return PlayerState.Idle;\n }\n }\n\n /**\n * Returns the currentTime - seekableRange.start. This ensures a user-friendly currentTime after a live stream\n * transitioned to VoD.\n * @param player\n */\n export function getCurrentTimeRelativeToSeekableRange(player: PlayerAPI): number {\n const currentTime = player.getCurrentTime();\n if (player.isLive()) {\n return currentTime;\n }\n\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(player, 0);\n return currentTime - seekableRangeStart;\n }\n\n /**\n * Returns the start value of the seekable range or the defaultValue if no seekableRange is present.\n * For now this happens only in combination with Mobile SDKs.\n *\n * TODO: remove this function in next major release\n *\n * @param player\n * @param defaultValue\n */\n export function getSeekableRangeStart(player: PlayerAPI, defaultValue: number = 0) {\n return player.getSeekableRange() && player.getSeekableRange().start || defaultValue;\n }\n\n /**\n * Calculates player seekable time range for live.\n * As the player returns `{ start: -1, end: -1 }` for live streams we need to calculate the `seekableRange` based on `maxTimeshift`.\n *\n * @param player\n */\n export function getSeekableRangeRespectingLive(player: PlayerAPI): TimeRange {\n if (!player.isLive()) {\n return player.getSeekableRange();\n }\n\n const currentTimeshift = -player.getTimeShift();\n const maxTimeshift = -player.getMaxTimeShift();\n const currentTime = player.getCurrentTime();\n\n const end = currentTime + (currentTimeshift);\n const start = currentTime - (maxTimeshift - currentTimeshift);\n\n return { start, end };\n }\n\n export interface TimeShiftAvailabilityChangedArgs extends NoArgs {\n timeShiftAvailable: boolean;\n }\n\n export class TimeShiftAvailabilityDetector {\n\n private player: PlayerAPI;\n private timeShiftAvailable: boolean;\n private timeShiftAvailabilityChangedEvent = new EventDispatcher<PlayerAPI, TimeShiftAvailabilityChangedArgs>();\n\n constructor(player: PlayerAPI) {\n this.player = player;\n this.timeShiftAvailable = undefined;\n\n let timeShiftDetector = () => {\n this.detect();\n };\n // Try to detect timeshift availability when source is loaded, which works for DASH streams\n player.on(player.exports.PlayerEvent.SourceLoaded, timeShiftDetector);\n // With HLS/NativePlayer streams, getMaxTimeShift can be 0 before the buffer fills, so we need to additionally\n // check timeshift availability in TimeChanged\n player.on(player.exports.PlayerEvent.TimeChanged, timeShiftDetector);\n }\n\n detect(): void {\n if (this.player.isLive()) {\n let timeShiftAvailableNow = PlayerUtils.isTimeShiftAvailable(this.player);\n\n // When the availability changes, we fire the event\n if (timeShiftAvailableNow !== this.timeShiftAvailable) {\n this.timeShiftAvailabilityChangedEvent.dispatch(this.player, { timeShiftAvailable: timeShiftAvailableNow });\n this.timeShiftAvailable = timeShiftAvailableNow;\n }\n }\n }\n\n get onTimeShiftAvailabilityChanged(): Event<PlayerAPI, TimeShiftAvailabilityChangedArgs> {\n return this.timeShiftAvailabilityChangedEvent.getEvent();\n }\n }\n\n export interface LiveStreamDetectorEventArgs extends NoArgs {\n live: boolean;\n }\n\n /**\n * Detects changes of the stream type, i.e. changes of the return value of the player#isLive method.\n * Normally, a stream cannot change its type during playback, it's either VOD or live. Due to bugs on some\n * platforms or browsers, it can still change. It is therefore unreliable to just check #isLive and this detector\n * should be used as a workaround instead.\n *\n * Additionally starting with player v8.19.0 we have the use-case that a live stream changes into a vod.\n * The DurationChanged event indicates this switch.\n *\n * Known cases:\n *\n * - HLS VOD on Android 4.3\n * Video duration is initially 'Infinity' and only gets available after playback starts, so streams are wrongly\n * reported as 'live' before playback (the live-check in the player checks for infinite duration).\n *\n * @deprecated since UI v3.9.0 in combination with player v8.19.0 use PlayerEvent.DurationChanged instead\n *\n * TODO: remove this class in next major release\n */\n export class LiveStreamDetector {\n\n private player: PlayerAPI;\n private live: boolean;\n private liveChangedEvent = new EventDispatcher<PlayerAPI, LiveStreamDetectorEventArgs>();\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, uimanager: UIInstanceManager) {\n this.player = player;\n this.uimanager = uimanager;\n this.live = undefined;\n\n let liveDetector = () => {\n this.detect();\n };\n this.uimanager.getConfig().events.onUpdated.subscribe(liveDetector);\n // Re-evaluate when playback starts\n player.on(player.exports.PlayerEvent.Play, liveDetector);\n\n // HLS live detection workaround for Android:\n // Also re-evaluate during playback, because that is when the live flag might change.\n // (Doing it only in Android Chrome saves unnecessary overhead on other platforms)\n if (BrowserUtils.isAndroid && BrowserUtils.isChrome) {\n player.on(player.exports.PlayerEvent.TimeChanged, liveDetector);\n }\n\n // DurationChanged event was introduced with player v8.19.0\n if (player.exports.PlayerEvent.DurationChanged) {\n player.on(player.exports.PlayerEvent.DurationChanged, liveDetector);\n }\n\n // Ad video's isLive() might be different than the actual video's isLive().\n player.on(player.exports.PlayerEvent.AdBreakStarted, liveDetector);\n player.on(player.exports.PlayerEvent.AdBreakFinished, liveDetector);\n }\n\n detect(): void {\n let liveNow = this.player.isLive();\n\n // Compare current to previous live state flag and fire event when it changes. Since we initialize the flag\n // with undefined, there is always at least an initial event fired that tells listeners the live state.\n if (liveNow !== this.live) {\n this.liveChangedEvent.dispatch(this.player, { live: liveNow });\n this.live = liveNow;\n }\n }\n\n get onLiveChanged(): Event<PlayerAPI, LiveStreamDetectorEventArgs> {\n return this.liveChangedEvent.getEvent();\n }\n }\n\n export function clampValueToRange(value: number, boundary1: number, boundary2: number): number {\n const lowerBoundary = Math.min(boundary1, boundary2);\n const upperBoundary = Math.max(boundary1, boundary2);\n return Math.min(Math.max(value, lowerBoundary), upperBoundary);\n }\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { Action, Direction } from './types';\nimport { Container } from '../components/container';\nimport { Component } from '../components/component';\n\nexport enum ListOrientation {\n Horizontal = 'horizontal',\n Vertical = 'vertical',\n}\n\n/**\n * @category Components\n */\nexport class ListNavigationGroup extends NavigationGroup {\n private readonly listNavigationDirections: Direction[];\n\n constructor(orientation: ListOrientation, container: Container<unknown>, ...components: Component<unknown>[]) {\n super(container, ...components);\n\n switch (orientation) {\n case ListOrientation.Vertical:\n this.listNavigationDirections = [Direction.UP, Direction.DOWN];\n break;\n\n case ListOrientation.Horizontal:\n this.listNavigationDirections = [Direction.LEFT, Direction.RIGHT];\n break;\n }\n }\n\n public handleAction(action: Action): void {\n super.handleAction(action);\n\n if (action === Action.SELECT) {\n // close the container when a list entry is selected\n this.handleAction(Action.BACK);\n }\n }\n\n public handleNavigation(direction: Direction): void {\n super.handleNavigation(direction);\n\n if (!this.listNavigationDirections.includes(direction)) {\n // close the container on navigation inputs that don't align\n // with the orientation of the list\n this.handleAction(Action.BACK);\n }\n }\n}\n","import { Component } from '../components/component';\nimport { Container } from '../components/container';\nimport { isComponent, isContainer, isListBox } from './typeguards';\n\n/**\n * Recursively resolves a container and the components contained within them, building a flat list of components.\n *\n * @param container The container to get the contained components from\n */\nfunction resolveAllComponents(container: Container<unknown>): Component<unknown>[] {\n const childComponents: Component<unknown>[] = [];\n\n container.getComponents().forEach(containerOrComponent => {\n if (isContainer(containerOrComponent)) {\n childComponents.push(...resolveAllComponents(containerOrComponent));\n } else if (isComponent(containerOrComponent)) {\n childComponents.push(containerOrComponent);\n }\n });\n\n return childComponents;\n}\n\n/**\n * Returns the HTML elements associated to the provided component.\n *\n * @param component The component to get the HTML elements from\n */\nfunction toHtmlElement(component: Component<unknown>): HTMLElement[] {\n if (isListBox(component)) {\n return [].slice.call(component.getDomElement().get()[0].children);\n } else {\n return component.getDomElement().get().slice(0, 1);\n }\n}\n\n/**\n * Takes the provided list of components and flat-maps them to a list of their respective HTML elements. In case a\n * provided component is a container, the children of that container will be resolved recursively. Ignores components\n * that are hidden.\n *\n * @param components The components to map to HTML elements\n */\nexport function getHtmlElementsFromComponents(components: Component<unknown>[]): HTMLElement[] {\n const htmlElements: HTMLElement[] = [];\n\n components\n .filter(component => !component.isHidden())\n .forEach(component => {\n const elementsToConsider = component instanceof Container ? resolveAllComponents(component) : [component];\n\n elementsToConsider.forEach(component => {\n htmlElements.push(...toHtmlElement(component));\n });\n });\n\n return htmlElements;\n}\n","import { Action, Direction, KeyMap } from './types';\nimport { BrowserUtils } from '../browserutils';\n\nconst TizenKeyMap = {\n isApplicable: () => BrowserUtils.isTizen,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 10009: Action.BACK,\n },\n};\n\nconst WebOsKeyMap = {\n isApplicable: () => BrowserUtils.isWebOs,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 461: Action.BACK,\n },\n};\n\nconst PlayStationKeyMap = {\n isApplicable: () => BrowserUtils.isPlayStation,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // Cross\n 13: Action.SELECT,\n // Circle\n 27: Action.BACK,\n },\n};\n\nconst AndroidKeyMap = {\n isApplicable: () => BrowserUtils.isAndroid,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 27: Action.BACK,\n },\n};\n\nconst HisenseKeyMap = {\n isApplicable: () => BrowserUtils.isHisense,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // OK\n 13: Action.SELECT,\n // Back\n 8: Action.BACK,\n },\n};\n\n// Default key map used on desktops\nconst DefaultKeyMap = {\n // Arrow Up\n 38: Direction.UP,\n // Arrow Down\n 40: Direction.DOWN,\n // Arrow Left\n 37: Direction.LEFT,\n // Arrow Right\n 39: Direction.RIGHT,\n // Enter\n 13: Action.SELECT,\n // Escape\n 27: Action.BACK,\n};\n\n/**\n * Returns the matching key map for the current platform.\n */\nexport function getKeyMapForPlatform(): KeyMap {\n const applicableKeyMap = [\n WebOsKeyMap,\n TizenKeyMap,\n PlayStationKeyMap,\n HisenseKeyMap,\n AndroidKeyMap,\n ].find(keyMap => keyMap.isApplicable());\n\n if (applicableKeyMap) {\n return applicableKeyMap.keyCodes;\n } else {\n return DefaultKeyMap;\n }\n}\n","import { Direction } from './types';\n\ninterface Vector {\n x: number;\n y: number;\n}\n\n/**\n * Calculates the length of a vector.\n *\n * @param vector The vector to calculate the length of\n */\nfunction length(vector: Vector): number {\n return Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));\n}\n\n/**\n * Normalizes the given vector.\n *\n * @param vector The vector to normalize\n */\nfunction normalize(vector: Vector): Vector {\n const len = length(vector);\n\n return {\n x: vector.x / len,\n y: vector.y / len,\n };\n}\n\n/**\n * Calculates the dot product between 2 vectors.\n *\n * @param a The first vector\n * @param b The second vector\n */\nfunction dotProduct(a: Vector, b: Vector): number {\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Calculates the distance between the 2 points pointed to by the provided vectors.\n *\n * @param a The first vector\n * @param b The second vector\n */\nfunction distance(a: Vector, b: Vector): number {\n return length({\n x: b.x - a.x,\n y: b.y - a.y,\n });\n}\n\n/**\n * Returns a vector that corresponds to the center of the provided element.\n *\n * @param element The element to get the center of\n */\nfunction getElementVector(element: HTMLElement): Vector {\n const boundingRect = getBoundingRectFromElement(element);\n\n return {\n x: boundingRect.x + boundingRect.width / 2,\n y: boundingRect.y + boundingRect.height / 2,\n };\n}\n\n/**\n * Returns the angle in degrees between the unit vector pointing in the given {Direction} and the unit vector that\n * points from the current element to another element.\n *\n * @param a The vector of the current element\n * @param b The vector of the other element\n * @param direction The direction to move along\n */\nfunction calculateAngle(a: Vector, b: Vector, direction: Direction): number {\n const directionVector = {\n x: (direction === Direction.LEFT ? -1 : direction === Direction.RIGHT ? 1 : 0),\n y: (direction === Direction.UP ? -1 : direction === Direction.DOWN ? 1 : 0),\n };\n\n const elementVector = normalize({\n x: b.x - a.x,\n y: b.y - a.y,\n });\n\n const angleCos = dotProduct(directionVector, elementVector) / (length(directionVector) * length(elementVector));\n\n return Math.acos(angleCos) * 180 / Math.PI;\n}\n\n/**\n * Returns the closest element to the current element when trying to navigate in the provided direction. Returns\n * undefined, if there is not element in the given direction.\n *\n * @param activeElement The currently selected element\n * @param elements The list of all elements that can be navigated to\n * @param direction The direction in which to navigate\n */\nexport function getElementInDirection(\n activeElement: HTMLElement,\n elements: HTMLElement[],\n direction: Direction,\n): HTMLElement | undefined {\n if (!activeElement) return undefined;\n\n const cutoffAngle = 45;\n const activeElemVector = getElementVector(activeElement);\n\n return elements\n // don't take the current element into account\n .filter(elem => elem !== activeElement)\n // get the angle between, and distance to any other element from the current element\n .map(element => {\n const elementVector = getElementVector(element);\n const dist = distance(activeElemVector, elementVector);\n const angle = calculateAngle(activeElemVector, elementVector, direction);\n\n return { angle, dist, element };\n })\n // filter out any elements that don't align with the direction we're trying to move in\n .filter(({ angle }) => angle <= cutoffAngle)\n // sort the resulting elements based on their distance to the current element in ascending order\n .sort(({ angle: angleA, dist: distA }, { angle: angleB, dist: distB }) => (angleA - angleB) + (distA - distB))\n // return the element closest to the current element\n .shift()?.element;\n}\n\n/**\n * Returns DOMRect like object containing horizontal X and vertical Y coordinates from and HTMLElement.\n * Handles use-cases for getBoundingClientRect when the return type can be either\n * a ClientRect or DOMRect object type.\n *\n * @param element The currently selected element\n */\nexport function getBoundingRectFromElement(element: HTMLElement) {\n const boundingRect = element.getBoundingClientRect();\n\n if (typeof boundingRect.x !== 'number' && typeof boundingRect.y !== 'number') {\n boundingRect.x = boundingRect.left;\n boundingRect.y = boundingRect.top;\n }\n\n return boundingRect;\n}\n\n","import { Container } from '../components/container';\nimport { Component } from '../components/component';\nimport { getElementInDirection } from './navigationalgorithm';\nimport { getHtmlElementsFromComponents } from './gethtmlelementsfromcomponents';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { isSettingsPanel } from './typeguards';\nimport { Action, ActionCallback, Callback, Direction, NavigationCallback } from './types';\n\n/**\n * Used as part of spatial navigation. Groups together different components to which you can navigate to, in a single\n * navigation group.\n *\n * Responsible for finding elements in direction on navigation and for tracking active element inside the group.\n * Triggers blur and focus on element when active element is changed, as well as click on element on `Action.SELECT`.\n * Will call `hideUi()` on passed in container if `Action.BACK` is called.\n *\n * @category Components\n */\nexport class NavigationGroup {\n private activeElement?: HTMLElement;\n private activeElementBeforeDisable?: HTMLElement;\n private readonly components: Component<unknown>[];\n private removeElementHoverEventListeners = () => {};\n private readonly eventSubscriber: NodeEventSubscriber;\n\n constructor(public readonly container: Container<unknown>, ...components: Component<unknown>[]) {\n this.components = components;\n this.eventSubscriber = new NodeEventSubscriber();\n }\n\n /**\n * If overwritten, allows to implement custom navigation behavior. Per default, the internal handler will still be\n * executed. To prevent execution of the default navigation handler, call `preventDefault()`;\n *\n * @param direction {Direction} The direction to move along\n * @param target {HTMLElement} The target element for the event\n * @param preventDefault {() => void} A function that, when called, will prevent the execution of the default handler\n */\n public onNavigation?: NavigationCallback;\n\n /**\n * If overwritten, allows to implement custom action behavior. Per default, the internal handler will still be\n * executed. To prevent execution of the default action handler, call `preventDefault()`;\n *\n * @param action {Action} The action that was called\n * @param target {HTMLElement} The target element that action was called on\n * @param preventDefault {() => void} A function that, when called, will prevent the execution of the default handler\n */\n public onAction?: ActionCallback;\n\n /**\n * Returns the active HTMLElement.\n */\n public getActiveElement(): HTMLElement | undefined {\n return this.activeElement;\n }\n\n private focusElement(element: HTMLElement): void {\n this.blurActiveElement();\n this.activeElement = element;\n this.activeElement.focus();\n }\n\n private blurActiveElement(): void {\n this.activeElement?.blur();\n }\n\n private focusFirstElement(): void {\n const element = getHtmlElementsFromComponents(this.components)[0];\n if (element) {\n this.focusElement(element);\n }\n }\n\n protected defaultNavigationHandler(direction: Direction): void {\n const targetElement = getElementInDirection(\n this.activeElement,\n getHtmlElementsFromComponents(this.components),\n direction,\n );\n\n if (targetElement) {\n this.focusElement(targetElement);\n }\n }\n\n protected defaultActionHandler(action: Action): void {\n switch (action) {\n case(Action.SELECT):\n this.activeElement.click();\n break;\n case(Action.BACK):\n this.container.hide();\n break;\n }\n }\n\n private handleInput<T>(data: T, defaultHandler: (data: T) => void, userHandler?: Callback<T>): void {\n let handleDefault = true;\n const preventDefault = () => (handleDefault = false);\n\n userHandler?.(data, this.activeElement, preventDefault);\n\n if (handleDefault) {\n defaultHandler.call(this, data);\n }\n }\n\n /**\n * Handles a navigation event.\n *\n * @param direction The direction of the navigation event\n */\n public handleNavigation(direction: Direction): void {\n if (!this.activeElement) {\n // If we do not have an active element, the active element has been disabled by a mouseleave\n // event. We should continue the navigation at the exact place where we left off.\n if (this.activeElementBeforeDisable) {\n this.focusElement(this.activeElementBeforeDisable);\n } else {\n this.focusFirstElement();\n }\n return;\n }\n this.handleInput(direction, this.defaultNavigationHandler, this.onNavigation);\n }\n\n /**\n * Handles an action event.\n *\n * @param action The action of the event\n */\n public handleAction(action: Action): void {\n this.handleInput(action, this.defaultActionHandler, this.onAction);\n }\n\n /**\n * Disable navigation group\n *\n * Call blur on active element, set as undefined, and track it as element before disable.\n */\n public disable(): void {\n if (this.activeElement) {\n this.activeElementBeforeDisable = this.activeElement;\n this.blurActiveElement();\n this.activeElement = undefined;\n }\n }\n\n /**\n * Enable navigation group\n *\n * Sets active element to either element that was active before disable, or first element of tracked elements.\n * If it is settings panel, it will always focus first element in the list.\n */\n public enable(): void {\n if (this.activeElementBeforeDisable && !isSettingsPanel(this.container)) {\n this.focusElement(this.activeElementBeforeDisable);\n this.activeElementBeforeDisable = undefined;\n } else {\n this.focusFirstElement();\n }\n\n this.trackElementHover();\n }\n\n /**\n * Adds event listener for `mouseenter` on tracked elements to ensure tracking of active element will work together\n * in combination of using mouse and key events.\n */\n private trackElementHover(): void {\n this.removeElementHoverEventListeners();\n\n const removeEventListenerFunctions = getHtmlElementsFromComponents(this.components).map(htmlElem => {\n const enterListener = this.focusElement.bind(this, htmlElem);\n const exitListener = () => this.disable();\n\n this.eventSubscriber.on(htmlElem, 'mouseenter', enterListener);\n this.eventSubscriber.on(htmlElem, 'mouseleave', exitListener);\n\n return () => {\n this.eventSubscriber.off(htmlElem, 'mouseenter', enterListener);\n this.eventSubscriber.off(htmlElem, 'mouseleave', exitListener);\n };\n });\n\n this.removeElementHoverEventListeners = () => removeEventListenerFunctions.forEach(fn => fn());\n }\n\n /**\n * Dispose of navigation group\n */\n public release(): void {\n this.eventSubscriber.release();\n this.activeElement = undefined;\n this.components.splice(0, this.components.length);\n this.removeElementHoverEventListeners();\n }\n}\n","type Listeners = ([Node, EventListenerOrEventListenerObject, boolean | AddEventListenerOptions])[];\n\n/**\n * Allows to subscribe to Node events.\n */\nexport class NodeEventSubscriber {\n private readonly attachedListeners: Map<keyof HTMLElementEventMap, Listeners>;\n\n constructor() {\n this.attachedListeners = new Map();\n }\n\n private getEventListenersOfType(type: keyof HTMLElementEventMap): Listeners {\n if (!this.attachedListeners.has(type)) {\n this.attachedListeners.set(type, []);\n }\n\n return this.attachedListeners.get(type);\n }\n\n /**\n * Adds the given event listener to the node.\n *\n * @param node The node to remove the event listener from\n * @param type The event to listen to\n * @param listener The listener to remove\n * @param options The event listener options\n */\n public on(\n node: Node,\n type: keyof HTMLElementEventMap,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n node.addEventListener(type, listener, options);\n this.getEventListenersOfType(type).push([node, listener, options]);\n }\n\n /**\n * Removes the given event listener from the node.\n *\n * @param node The node to attach the event listener to\n * @param type The event to listen to\n * @param listener The listener to add\n * @param options The event listener options\n */\n public off(\n node: Node,\n type: keyof HTMLElementEventMap,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n const listenersOfType = this.getEventListenersOfType(type);\n const listenerIndex = listenersOfType.findIndex(([otherNode, otherListener, otherOptions]) => {\n return otherNode === node && otherListener === listener && otherOptions === options;\n });\n\n node.removeEventListener(type, listener, options);\n\n if (listenerIndex > -1) {\n listenersOfType.splice(listenerIndex, 1);\n }\n }\n\n /**\n * Removes all attached event listeners.\n */\n public release(): void {\n this.attachedListeners.forEach((listenersOfType, type) => {\n listenersOfType.forEach(([element, listener, options]) => {\n this.off(element, type, listener, options);\n });\n });\n this.attachedListeners.clear();\n }\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { Component } from '../components/component';\nimport { UIContainer } from '../components/uicontainer';\nimport { Action, Direction } from './types';\n\n/**\n * Extends NavigationGroup and provides additional logic for hiding and showing the UI on the root container.\n *\n * @category Components\n */\nexport class RootNavigationGroup extends NavigationGroup {\n constructor(public readonly container: UIContainer, ...elements: Component<unknown>[]) {\n super(container, ...elements);\n }\n\n public handleAction(action: Action) {\n this.container.showUi();\n\n super.handleAction(action);\n }\n\n public handleNavigation(direction: Direction) {\n this.container.showUi();\n\n super.handleNavigation(direction);\n }\n\n protected defaultActionHandler(action: Action): void {\n if (action === Action.BACK) {\n this.container.hideUi();\n } else {\n super.defaultActionHandler(action);\n }\n }\n\n public release(): void {\n super.release();\n }\n}\n","import { RootNavigationGroup } from './rootnavigationgroup';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { Action, Direction } from './types';\nimport {getBoundingRectFromElement} from './navigationalgorithm';\n\nconst DefaultScrubSpeedPercentage = 0.005;\nconst ScrubSpeedClearInterval = 100;\nconst ScrubSpeedMultiplier = 1.1;\n\n/**\n * Handles Spatial Navigation interaction with the seek bar. Ensures, that seek operations can be executed and that the\n * scrubbing tooltip is shown as if the user scrubbed using the mouse/touchscreen.\n */\nexport class SeekBarHandler {\n private readonly cursorPosition = { x: 0, y: 0};\n private readonly eventSubscriber: NodeEventSubscriber;\n private isScrubbing = false;\n private scrubSpeedResetTimeout: number;\n private scrubSpeedPercentage = DefaultScrubSpeedPercentage;\n\n constructor(private readonly rootNavigationGroup: RootNavigationGroup) {\n this.rootNavigationGroup.onAction = this.onAction;\n this.eventSubscriber = new NodeEventSubscriber();\n this.rootNavigationGroup.onNavigation = this.onNavigation;\n }\n\n private updateScrubSpeedPercentage(): void {\n clearTimeout(this.scrubSpeedResetTimeout);\n this.scrubSpeedPercentage *= ScrubSpeedMultiplier;\n this.scrubSpeedResetTimeout = window.setTimeout(\n () => this.scrubSpeedPercentage = DefaultScrubSpeedPercentage, ScrubSpeedClearInterval,\n );\n }\n\n private getIncrement(direction: Direction, seekBarWrapper: HTMLElement): number {\n this.updateScrubSpeedPercentage();\n\n const seekBarWidth = seekBarWrapper.getBoundingClientRect().width;\n const increment = seekBarWidth * this.scrubSpeedPercentage;\n\n return direction === Direction.RIGHT ? increment : -increment;\n }\n\n private resetCursorPosition(): void {\n this.cursorPosition.x = 0;\n this.cursorPosition.y = 0;\n }\n\n private updateCursorPosition(direction: Direction, seekBarWrapper: HTMLElement): void {\n this.cursorPosition.x += this.getIncrement(direction, seekBarWrapper);\n }\n\n private initializeCursorPosition(seekBarWrapper: HTMLElement): void {\n const playbackPositionMarker = getPlaybackPositionMarker(seekBarWrapper);\n const rect = getBoundingRectFromElement(playbackPositionMarker);\n\n\n const startX = rect.x + (rect.width / 2);\n const startY = rect.y;\n\n this.cursorPosition.x = startX;\n this.cursorPosition.y = startY;\n }\n\n private initializeOrUpdateCursorPosition(seekBarWrapper: HTMLElement, direction: Direction): void {\n if (this.isScrubbing) {\n this.updateCursorPosition(direction, seekBarWrapper);\n } else {\n this.initializeCursorPosition(seekBarWrapper);\n }\n\n this.isScrubbing = true;\n }\n\n private getCursorPositionMouseEventInit(): MouseEventInit {\n return {\n clientX: this.cursorPosition.x,\n clientY: this.cursorPosition.y,\n };\n }\n\n private dispatchMouseMoveEvent(seekBar: Element): void {\n seekBar.dispatchEvent(new MouseEvent('mousemove', this.getCursorPositionMouseEventInit()));\n }\n\n private readonly onNavigation = (direction: Direction, target: HTMLElement, preventDefault: () => void): void => {\n if (!isSeekBarWrapper(target)) {\n return;\n }\n\n if (direction === Direction.UP || direction === Direction.DOWN) {\n this.stopSeeking(getSeekBar(target));\n\n return;\n }\n\n this.initializeOrUpdateCursorPosition(target, direction);\n this.dispatchMouseMoveEvent(getSeekBar(target));\n\n preventDefault();\n };\n\n private dispatchMouseClickEvent(seekBar: Element): void {\n const mouseDownHandler = () => {\n const mouseEventInit = this.getCursorPositionMouseEventInit();\n\n document.dispatchEvent(new MouseEvent('mouseup', mouseEventInit));\n this.eventSubscriber.off(seekBar, 'mousedown', mouseDownHandler);\n this.stopSeeking(seekBar);\n };\n\n this.eventSubscriber.on(seekBar, 'mousedown', mouseDownHandler);\n seekBar.dispatchEvent(new MouseEvent('mousedown'));\n }\n\n private stopSeeking(seekBar: Element): void {\n this.resetCursorPosition();\n this.isScrubbing = false;\n this.dispatchMouseLeaveEvent(seekBar);\n }\n\n private dispatchMouseLeaveEvent(seekBar: Element): void {\n seekBar.dispatchEvent(new MouseEvent('mouseleave'));\n }\n\n private readonly onAction = (action: Action, target: HTMLElement, preventDefault: () => void): void => {\n if (!isSeekBarWrapper(target)) {\n return;\n }\n\n const seekBar = getSeekBar(target);\n\n if (action === Action.SELECT && this.isScrubbing) {\n this.dispatchMouseClickEvent(seekBar);\n preventDefault();\n } else if (action === Action.BACK) {\n this.stopSeeking(seekBar);\n preventDefault();\n }\n };\n\n /**\n * Releases the SeekBraHandler, making sure all event subscribers are removed.\n */\n public release(): void {\n this.eventSubscriber.release();\n this.rootNavigationGroup.onAction = undefined;\n this.rootNavigationGroup.onNavigation = undefined;\n }\n}\n\nfunction isSeekBarWrapper(element: HTMLElement): boolean {\n return Array.from(element.classList).findIndex(className => /-ui-seekbar$/.test(className)) > -1;\n}\n\nfunction getSeekBar(seekBarWrapper: HTMLElement): Element {\n return seekBarWrapper.children.item(0);\n}\n\nfunction getPlaybackPositionMarker(seekBarWrapper: HTMLElement): HTMLElement {\n return seekBarWrapper.querySelector('[class*=\"seekbar-playbackposition-marker\"]');\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { RootNavigationGroup } from './rootnavigationgroup';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { SeekBarHandler } from './seekbarhandler';\nimport { getKeyMapForPlatform } from './keymap';\nimport { Action, Direction, KeyMap } from './types';\nimport { isAction, isDirection } from './typeguards';\n\n/**\n * SpatialNavigation keeps track of all navigation groups, and updates the active navigation group when visibility\n * changes on group container.\n *\n * It listens to key events, and triggers either handleNavigation or handleAction on the active group.\n * SeekBarHandler will get instantiated with root navigation group and disposed on release of the spatial navigation.\n */\nexport class SpatialNavigation {\n private unsubscribeVisibilityChangesFns: (() => void)[];\n private readonly navigationGroups: NavigationGroup[] = [];\n private readonly activeNavigationGroups: NavigationGroup[];\n private readonly eventSubscriber: NodeEventSubscriber;\n private readonly seekBarHandler: SeekBarHandler;\n private readonly keyMap: KeyMap;\n\n constructor(rootNavigationGroup: RootNavigationGroup, ...navigationGroups: NavigationGroup[]) {\n this.seekBarHandler = new SeekBarHandler(rootNavigationGroup);\n\n this.activeNavigationGroups = [];\n this.unsubscribeVisibilityChangesFns = [];\n this.eventSubscriber = new NodeEventSubscriber();\n this.navigationGroups = [rootNavigationGroup, ...navigationGroups];\n this.keyMap = getKeyMapForPlatform();\n\n this.subscribeToNavigationGroupVisibilityChanges();\n this.attachKeyEventHandler();\n this.enableDefaultNavigationGroup();\n }\n\n private attachKeyEventHandler(): void {\n this.eventSubscriber.on(document, 'keydown', this.handleKeyEvent, true);\n }\n\n private onShow = (group: NavigationGroup): void => {\n this.activeNavigationGroups.push(group);\n this.updateEnabledNavigationGroup();\n };\n\n private onHide = (group: NavigationGroup): void => {\n const groupIndex = this.activeNavigationGroups.findIndex(other => other === group);\n\n if (groupIndex > -1) {\n group.disable();\n this.activeNavigationGroups.splice(groupIndex, 1);\n this.updateEnabledNavigationGroup();\n }\n };\n\n /**\n * Subscribes to onHide and onShow on all navigation groups containers as Spatial navigation tracks active navigation\n * group based on their container visibility.\n */\n private subscribeToNavigationGroupVisibilityChanges(): void {\n this.navigationGroups.forEach(group => {\n const onShowHandler = () => this.onShow(group);\n const onHideHandler = () => this.onHide(group);\n\n group.container.onShow.subscribe(onShowHandler);\n group.container.onHide.subscribe(onHideHandler);\n\n this.unsubscribeVisibilityChangesFns.push(\n () => group.container.onShow.unsubscribe(onShowHandler),\n () => group.container.onHide.unsubscribe(onHideHandler),\n );\n });\n }\n\n private unsubscribeFromNavigationGroupVisibilityChanges(): void {\n this.unsubscribeVisibilityChangesFns.forEach(unsub => unsub());\n this.unsubscribeVisibilityChangesFns = [];\n }\n\n /**\n * It will enable group of which container is currently shown\n * If there are no groups with containers that are currently visible, it will enable root navigation group\n */\n private enableDefaultNavigationGroup(): void {\n const isShown = (group: NavigationGroup) => group.container.isShown();\n const groupToEnable = this.navigationGroups.find(isShown) ?? this.navigationGroups[0];\n\n if (groupToEnable) {\n this.activeNavigationGroups.push(groupToEnable);\n this.updateEnabledNavigationGroup();\n }\n }\n\n /**\n * Disables navigation groups that are no longer active and calls enable on last pushed navigation group\n */\n private updateEnabledNavigationGroup(): void {\n this.activeNavigationGroups.forEach((group, idx) => {\n if (idx < this.activeNavigationGroups.length - 1) {\n group.disable();\n } else {\n group.enable();\n }\n });\n }\n\n /**\n * Returns currently active navigation group\n */\n public getActiveNavigationGroup(): NavigationGroup | undefined {\n return this.activeNavigationGroups[this.activeNavigationGroups.length - 1];\n }\n\n /**\n * Checks if keyboard event keycode is tracked either as Direction or Action and calls appropriate handler on active\n * navigation group\n *\n * @param e {KeyboardEvent}\n */\n private handleKeyEvent = (e: KeyboardEvent): void => {\n const event: Direction | Action | undefined = this.keyMap[getKeyCode(e)];\n\n const active = this.getActiveNavigationGroup();\n if (!active || !active.container || active.container.isHidden() || active.container.isDisabled()) {\n return;\n }\n\n if (isDirection(event)) {\n active.handleNavigation(event);\n\n e.preventDefault();\n e.stopPropagation();\n }\n if (isAction(event)) {\n active.handleAction(event);\n\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n /**\n * Dispose of SpatialNavigation\n *\n * Remove all event handlers, release seekbar handler and release all navigation groups.\n */\n public release(): void {\n this.unsubscribeFromNavigationGroupVisibilityChanges();\n this.eventSubscriber.release();\n this.navigationGroups.forEach(group => group.release());\n this.seekBarHandler.release();\n }\n}\n\nfunction getKeyCode(event: KeyboardEvent): number {\n return event.keyCode;\n}\n","import { Component } from '../components/component';\nimport { SettingsPanel } from '../components/settingspanel';\nimport { Container } from '../components/container';\nimport { ListBox } from '../components/listbox';\nimport { Action, Direction } from './types';\n\nexport function isSettingsPanel(component: Component<unknown>): component is SettingsPanel {\n return component instanceof SettingsPanel;\n}\n\nexport function isComponent(obj: unknown): obj is Component<unknown> {\n return obj !== null && obj !== undefined && obj instanceof Component;\n}\n\nexport function isContainer(obj: unknown): obj is Container<unknown> {\n return obj !== null && obj !== undefined && obj instanceof Container;\n}\n\nexport function isListBox(obj: unknown): obj is ListBox {\n return obj instanceof ListBox;\n}\n\nexport function isDirection(direction: unknown): direction is Direction {\n return typeof direction === 'string' && Object.values<string>(Direction).includes(direction);\n}\n\nexport function isAction(action: unknown): action is Action {\n return typeof action === 'string' && Object.values<string>(Action).includes(action);\n}\n","export type Callback<T> = (data: T, target: HTMLElement, preventDefault: () => void) => void;\nexport type NavigationCallback = Callback<Direction>;\nexport type ActionCallback = Callback<Action>;\nexport type KeyMap = {\n [keyCode: number]: Action | Direction;\n};\n\nexport enum Direction {\n UP = 'up',\n DOWN = 'down',\n LEFT = 'left',\n RIGHT = 'right',\n}\n\nexport enum Action {\n SELECT = 'select',\n BACK = 'back',\n}\n","import { UIConfig } from './uiconfig';\n\n/**\n * @category Utils\n */\nexport namespace StorageUtils {\n let disableStorageApi: boolean;\n\n export function setStorageApiDisabled(uiConfig: UIConfig) {\n disableStorageApi = uiConfig.disableStorageApi;\n }\n\n function shouldUseLocalStorage(): boolean {\n try {\n return (\n !disableStorageApi &&\n window.localStorage &&\n typeof localStorage.getItem === 'function' &&\n typeof localStorage.setItem === 'function'\n );\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Stores a string item into localStorage.\n * @param key the item's key\n * @param data the item's data\n */\n export function setItem(key: string, data: string): void {\n if (shouldUseLocalStorage()) {\n try {\n window.localStorage.setItem(key, data);\n } catch (e) {\n console.debug(`Failed to set storage item ${key}`, e);\n }\n }\n }\n\n /**\n * Gets an item's string value from the localStorage.\n * @param key the key to look up its associated value\n * @return {string | null} Returns the string if found, null if there is no data stored for the key\n */\n export function getItem(key: string): string | null {\n if (shouldUseLocalStorage()) {\n try {\n return window.localStorage.getItem(key);\n } catch (e) {\n console.debug(`Failed to get storage item ${key}`, e);\n }\n }\n\n return null;\n }\n\n /**\n * Stores an object into localStorage. The object will be serialized to JSON. The following types are supported\n * in addition to the default types:\n * - ColorUtils.Color\n *\n * @param key the key to store the data to\n * @param data the object to store\n */\n export function setObject<T>(key: string, data: T): void {\n let json = JSON.stringify(data);\n setItem(key, json);\n }\n\n /**\n * Gets an object for the given key from localStorage. The object will be deserialized from JSON. Beside the\n * default types, the following types are supported:\n * - ColorUtils.Color\n *\n * @param key the key to look up its associated object\n * @return {any} Returns the object if found, null otherwise\n */\n export function getObject<T>(key: string): T | null {\n let json = getItem(key);\n\n if (json) {\n let object = JSON.parse(json);\n return <T>object;\n }\n return null;\n }\n}\n","import { Ad, LinearAd, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * @category Utils\n */\nexport namespace StringUtils {\n\n export let FORMAT_HHMMSS: string = 'hh:mm:ss';\n export let FORMAT_MMSS: string = 'mm:ss';\n\n /**\n * Formats a number of seconds into a time string with the pattern hh:mm:ss.\n *\n * @param totalSeconds the total number of seconds to format to string\n * @param format the time format to output (default: hh:mm:ss)\n * @returns {string} the formatted time string\n */\n export function secondsToTime(totalSeconds: number, format: string = FORMAT_HHMMSS): string {\n let isNegative = totalSeconds < 0;\n\n if (isNegative) {\n // If the time is negative, we make it positive for the calculation below\n // (else we'd get all negative numbers) and reattach the negative sign later.\n totalSeconds = -totalSeconds;\n }\n\n // Split into separate time parts\n let hours = Math.floor(totalSeconds / 3600);\n let minutes = Math.floor(totalSeconds / 60) - hours * 60;\n let seconds = Math.floor(totalSeconds) % 60;\n\n return (isNegative ? '-' : '') + format\n .replace('hh', leftPadWithZeros(hours, 2))\n .replace('mm', leftPadWithZeros(minutes, 2))\n .replace('ss', leftPadWithZeros(seconds, 2));\n }\n\n export function secondsToText(totalSeconds: number): string {\n const isNegative = totalSeconds < 0;\n\n if (isNegative) {\n // If the time is negative, we make it positive for the calculation below\n // (else we'd get all negative numbers) and reattach the negative sign later.\n totalSeconds = -totalSeconds;\n }\n\n // Split into separate time parts\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor(totalSeconds / 60) - hours * 60;\n const seconds = Math.floor(totalSeconds) % 60;\n\n return (isNegative ? '-' : '') +\n (hours !== 0 ? `${leftPadWithZeros(hours, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.hours'))} ` : '') +\n (minutes !== 0 ? `${leftPadWithZeros(minutes, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.minutes'))} ` : '') +\n `${leftPadWithZeros(seconds, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.seconds'))}`;\n }\n\n /**\n * Converts a number to a string and left-pads it with zeros to the specified length.\n * Example: leftPadWithZeros(123, 5) => '00123'\n *\n * @param num the number to convert to string and pad with zeros\n * @param length the desired length of the padded string\n * @returns {string} the padded number as string\n */\n function leftPadWithZeros(num: number | string, length: number): string {\n let text = num + '';\n let padding = '0000000000'.substr(0, length - text.length);\n return padding + text;\n }\n\n /**\n * Fills out placeholders in an ad message.\n *\n * Has the placeholders '{remainingTime[formatString]}', '{playedTime[formatString]}',\n * '{adDuration[formatString]}' and {adBreakRemainingTime[formatString]}, which are replaced by the remaining time until the ad can be skipped, the current\n * time or the ad duration. The format string is optional. If not specified, the placeholder is replaced by the time\n * in seconds. If specified, it must be of the following format:\n * - %d - Inserts the time as an integer.\n * - %0Nd - Inserts the time as an integer with leading zeroes, if the length of the time string is smaller than N.\n * - %f - Inserts the time as a float.\n * - %0Nf - Inserts the time as a float with leading zeroes.\n * - %.Mf - Inserts the time as a float with M decimal places. Can be combined with %0Nf, e.g. %04.2f (the time\n * 10.123 would be printed as 0010.12).\n * - %hh:mm:ss\n * - %mm:ss\n *\n * Examples:\n * - { text: 'Ad: {remainingTime%mm:ss} secs' }\n * An input value of 100 would be displayed as: 'Ad: 01:40 secs'\n * - { text: 'Ad: {remainingTime%f} secs' }\n * An input value of 100 would be displayed as: 'Ad: 100.0 secs'\n * - { text: 'Adbreak: {adBreakRemainingTime%f} secs' }\n * Adbreak with 2 ads each 50 seconds would be displayed as: 'Ad: 100.0 secs'\n *\n * @param adMessage an ad message with optional placeholders to fill\n * @param skipOffset if specified, {remainingTime} will be filled with the remaining time until the ad can be skipped\n * @param player the player to get the time data from\n * @returns {string} the ad message with filled placeholders\n */\n export function replaceAdMessagePlaceholders(adMessage: string, skipOffset: number, player: PlayerAPI) {\n let adMessagePlaceholderRegex = new RegExp(\n '\\\\{(remainingTime|playedTime|adDuration|adBreakRemainingTime)(}|%((0[1-9]\\\\d*(\\\\.\\\\d+(d|f)|d|f)|\\\\.\\\\d+f|d|f)|hh:mm:ss|mm:ss)})',\n 'g',\n );\n\n return adMessage.replace(adMessagePlaceholderRegex, (formatString) => {\n let time = 0;\n if (formatString.indexOf('remainingTime') > -1) {\n if (skipOffset) {\n time = Math.ceil(skipOffset - player.getCurrentTime());\n } else {\n time = player.getDuration() - player.getCurrentTime();\n }\n } else if (formatString.indexOf('playedTime') > -1) {\n time = player.getCurrentTime();\n } else if (formatString.indexOf('adDuration') > -1) {\n time = player.getDuration();\n } else if (formatString.indexOf('adBreakRemainingTime') > -1) { // To display the remaining time in the ad break as opposed to in the ad\n time = 0;\n\n // compute list of ads and calculate duration of remaining ads based on index of active ad\n if (player.ads.isLinearAdActive()) {\n const isActiveAd = (ad: Ad) => player.ads.getActiveAd().id === ad.id;\n const indexOfActiveAd = player.ads.getActiveAdBreak().ads.findIndex(isActiveAd);\n const duration = player.ads.getActiveAdBreak().ads\n .slice(indexOfActiveAd)\n .reduce((total, ad) => total + (ad.isLinear ? (ad as LinearAd).duration : 0), 0);\n\n // And remaning ads duration minus time played\n time = duration - player.getCurrentTime();\n }\n }\n\n return formatNumber(Math.round(time), formatString);\n });\n }\n\n function formatNumber(time: number, format: string) {\n let formatStringValidationRegex = /%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)/;\n let leadingZeroesRegex = /(%0[1-9]\\d*)(?=(\\.\\d+f|f|d))/;\n let decimalPlacesRegex = /\\.\\d*(?=f)/;\n\n if (!formatStringValidationRegex.test(format)) {\n // If the format is invalid, we set a default fallback format\n format = '%d';\n }\n\n // Determine the number of leading zeros\n let leadingZeroes = 0;\n let leadingZeroesMatches = format.match(leadingZeroesRegex);\n if (leadingZeroesMatches) {\n leadingZeroes = parseInt(leadingZeroesMatches[0].substring(2));\n }\n\n // Determine the number of decimal places\n let numDecimalPlaces = null;\n let decimalPlacesMatches = format.match(decimalPlacesRegex);\n if (decimalPlacesMatches && !isNaN(parseInt(decimalPlacesMatches[0].substring(1)))) {\n numDecimalPlaces = parseInt(decimalPlacesMatches[0].substring(1));\n if (numDecimalPlaces > 20) {\n numDecimalPlaces = 20;\n }\n }\n\n // Float format\n if (format.indexOf('f') > -1) {\n let timeString = '';\n\n if (numDecimalPlaces !== null) {\n // Apply fixed number of decimal places\n timeString = time.toFixed(numDecimalPlaces);\n } else {\n timeString = '' + time;\n }\n\n // Apply leading zeros\n if (timeString.indexOf('.') > -1) {\n return leftPadWithZeros(timeString, timeString.length + (leadingZeroes - timeString.indexOf('.')));\n } else {\n return leftPadWithZeros(timeString, leadingZeroes);\n }\n\n }\n // Time format\n else if (format.indexOf(':') > -1) {\n let totalSeconds = Math.ceil(time);\n\n // hh:mm:ss format\n if (format.indexOf('hh') > -1) {\n return secondsToTime(totalSeconds);\n }\n // mm:ss format\n else {\n let minutes = Math.floor(totalSeconds / 60);\n let seconds = totalSeconds % 60;\n\n return leftPadWithZeros(minutes, 2) + ':' + leftPadWithZeros(seconds, 2);\n }\n }\n // Integer format\n else {\n return leftPadWithZeros(Math.ceil(time), leadingZeroes);\n }\n }\n}\n","import { ListItem, ListSelector, ListSelectorConfig } from './components/listselector';\nimport { UIInstanceManager } from './uimanager';\nimport { PlayerAPI, SubtitleEvent, SubtitleTrack } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * Helper class to handle all subtitle related events\n *\n * This class listens to player events as well as the `ListSelector` event if selection changed\n *\n * @category Utils\n */\nexport class SubtitleSwitchHandler {\n\n private static SUBTITLES_OFF_KEY: string = 'null';\n\n private player: PlayerAPI;\n private listElement: ListSelector<ListSelectorConfig>;\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, element: ListSelector<ListSelectorConfig>, uimanager: UIInstanceManager) {\n this.player = player;\n this.listElement = element;\n this.uimanager = uimanager;\n\n this.bindSelectionEvent();\n this.bindPlayerEvents();\n this.refreshSubtitles();\n }\n\n private bindSelectionEvent(): void {\n this.listElement.onItemSelected.subscribe((_, value: string) => {\n // TODO add support for multiple concurrent subtitle selections\n if (value === SubtitleSwitchHandler.SUBTITLES_OFF_KEY) {\n const currentSubtitle = this.player.subtitles.list().filter((subtitle) => subtitle.enabled).pop();\n if (currentSubtitle) {\n this.player.subtitles.disable(currentSubtitle.id);\n }\n } else {\n this.player.subtitles.enable(value, true);\n }\n });\n }\n\n private bindPlayerEvents(): void {\n this.player.on(this.player.exports.PlayerEvent.SubtitleAdded, this.addSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleEnabled, this.selectCurrentSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleDisabled, this.selectCurrentSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleRemoved, this.removeSubtitle);\n // Update subtitles when source goes away\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, this.clearSubtitles);\n // Update subtitles when the period within a source changes\n this.player.on(this.player.exports.PlayerEvent.PeriodSwitched, this.refreshSubtitles);\n this.uimanager.getConfig().events.onUpdated.subscribe(this.refreshSubtitles);\n }\n\n private addSubtitle = (event: SubtitleEvent) => {\n const subtitle = event.subtitle;\n if (!this.listElement.hasItem(subtitle.id)) {\n this.listElement.addItem(subtitle.id, subtitle.label);\n }\n };\n\n private removeSubtitle = (event: SubtitleEvent) => {\n const subtitle = event.subtitle;\n if (this.listElement.hasItem(subtitle.id)) {\n this.listElement.removeItem(subtitle.id);\n }\n };\n\n private selectCurrentSubtitle = () => {\n if (!this.player.subtitles) {\n // Subtitles API not available (yet)\n return;\n }\n\n let currentSubtitle = this.player.subtitles.list().filter((subtitle) => subtitle.enabled).pop();\n this.listElement.selectItem(currentSubtitle ? currentSubtitle.id : SubtitleSwitchHandler.SUBTITLES_OFF_KEY);\n };\n\n private clearSubtitles = () => {\n this.listElement.clearItems();\n }\n\n private refreshSubtitles = () => {\n if (!this.player.subtitles) {\n // Subtitles API not available (yet)\n return;\n }\n\n const offListItem: ListItem = {\n key: SubtitleSwitchHandler.SUBTITLES_OFF_KEY,\n label: i18n.getLocalizer('off'),\n };\n\n const subtitles = this.player.subtitles.list();\n const subtitleToListItem = (subtitle: SubtitleTrack): ListItem => {\n return { key: subtitle.id, label: subtitle.label };\n };\n\n this.listElement.synchronizeItems([\n offListItem, ...subtitles.map(subtitleToListItem),\n ]);\n this.selectCurrentSubtitle();\n };\n}\n","// TODO change to internal (not exported) class, how to use in other files?\n/**\n * Executes a callback after a specified amount of time, optionally repeatedly until stopped.\n */\nexport class Timeout {\n\n private readonly delay: number;\n private readonly callback: () => void;\n private readonly repeat: boolean;\n // There's two setTimeout declarations, one on Window which returns type \"number\" and one in NodeJS which returns\n // type \"Timer\". For unknown reasons builds on Jenkins fail due to a type mismatch when we use type \"number\" here,\n // although it works on other platforms (e.g. Windows, Codeship).\n // To work around the issue we use type \"any\". The type does not matter anyway because we're not working with\n // this value except providing it to clearTimeout.\n private timeoutOrIntervalId: any;\n private active: boolean;\n private suspended: boolean;\n\n /**\n * Creates a new timeout callback handler.\n * @param delay the delay in milliseconds after which the callback should be executed\n * @param callback the callback to execute after the delay time\n * @param repeat if true, call the callback repeatedly in delay intervals\n */\n constructor(delay: number, callback: () => void, repeat: boolean = false) {\n this.delay = delay;\n this.callback = callback;\n this.repeat = repeat;\n this.timeoutOrIntervalId = 0;\n this.active = false;\n this.suspended = false;\n }\n\n /**\n * Starts the timeout and calls the callback when the timeout delay has passed. Has no effect when the timeout is\n * suspended.\n * @returns {Timeout} the current timeout (so the start call can be chained to the constructor)\n */\n start(): this {\n this.reset();\n return this;\n }\n\n /**\n * Clears the timeout. The callback will not be called if clear is called during the timeout.\n */\n clear(): void {\n this.clearInternal();\n }\n\n /**\n * Suspends the timeout. The callback will not be called and calls to `start` and `reset` will be ignored until the\n * timeout is resumed.\n */\n suspend() {\n this.suspended = true;\n this.clearInternal();\n\n return this;\n }\n\n /**\n * Resumes the timeout.\n * @param reset whether to reset the timeout after resuming\n */\n resume(reset: boolean) {\n this.suspended = false;\n\n if (reset) {\n this.reset();\n }\n\n return this;\n }\n\n /**\n * Resets the passed timeout delay to zero. Can be used to defer the calling of the callback. Has no effect if the\n * timeout is suspended.\n */\n reset(): void {\n this.clearInternal();\n\n if (this.suspended) {\n return;\n }\n\n if (this.repeat) {\n this.timeoutOrIntervalId = setInterval(this.callback, this.delay);\n } else {\n this.timeoutOrIntervalId = setTimeout(() => {\n this.active = false;\n this.callback();\n }, this.delay);\n }\n this.active = true;\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n private clearInternal(): void {\n if (this.repeat) {\n clearInterval(this.timeoutOrIntervalId);\n } else {\n clearTimeout(this.timeoutOrIntervalId);\n }\n this.active = false;\n }\n}","import { SubtitleOverlay } from './components/subtitleoverlay';\nimport { SettingsPanelPage } from './components/settingspanelpage';\nimport { SettingsPanelItem } from './components/settingspanelitem';\nimport { VideoQualitySelectBox } from './components/videoqualityselectbox';\nimport { PlaybackSpeedSelectBox } from './components/playbackspeedselectbox';\nimport { AudioTrackSelectBox } from './components/audiotrackselectbox';\nimport { AudioQualitySelectBox } from './components/audioqualityselectbox';\nimport { SettingsPanel } from './components/settingspanel';\nimport { SubtitleSettingsPanelPage } from './components/subtitlesettings/subtitlesettingspanelpage';\nimport { SettingsPanelPageOpenButton } from './components/settingspanelpageopenbutton';\nimport { SubtitleSettingsLabel } from './components/subtitlesettings/subtitlesettingslabel';\nimport { SubtitleSelectBox } from './components/subtitleselectbox';\nimport { ControlBar } from './components/controlbar';\nimport { Container, ContainerConfig } from './components/container';\nimport { PlaybackTimeLabel, PlaybackTimeLabelMode } from './components/playbacktimelabel';\nimport { SeekBar } from './components/seekbar';\nimport { SeekBarLabel } from './components/seekbarlabel';\nimport { PlaybackToggleButton } from './components/playbacktogglebutton';\nimport { VolumeToggleButton } from './components/volumetogglebutton';\nimport { VolumeSlider } from './components/volumeslider';\nimport { Spacer } from './components/spacer';\nimport { PictureInPictureToggleButton } from './components/pictureinpicturetogglebutton';\nimport { AirPlayToggleButton } from './components/airplaytogglebutton';\nimport { CastToggleButton } from './components/casttogglebutton';\nimport { VRToggleButton } from './components/vrtogglebutton';\nimport { SettingsToggleButton } from './components/settingstogglebutton';\nimport { FullscreenToggleButton } from './components/fullscreentogglebutton';\nimport { UIContainer } from './components/uicontainer';\nimport { BufferingOverlay } from './components/bufferingoverlay';\nimport { PlaybackToggleOverlay } from './components/playbacktoggleoverlay';\nimport { CastStatusOverlay } from './components/caststatusoverlay';\nimport { TitleBar } from './components/titlebar';\nimport { RecommendationOverlay } from './components/recommendationoverlay';\nimport { Watermark } from './components/watermark';\nimport { ErrorMessageOverlay } from './components/errormessageoverlay';\nimport { AdClickOverlay } from './components/adclickoverlay';\nimport { AdMessageLabel } from './components/admessagelabel';\nimport { AdSkipButton } from './components/adskipbutton';\nimport { CloseButton } from './components/closebutton';\nimport { MetadataLabel, MetadataLabelContent } from './components/metadatalabel';\nimport { PlayerUtils } from './playerutils';\nimport { Label } from './components/label';\nimport { CastUIContainer } from './components/castuicontainer';\nimport { UIConditionContext, UIManager } from './uimanager';\nimport { UIConfig } from './uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\nimport { SubtitleListBox } from './components/subtitlelistbox';\nimport { AudioTrackListBox } from './components/audiotracklistbox';\nimport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nimport { RootNavigationGroup } from './spatialnavigation/rootnavigationgroup';\nimport { ListNavigationGroup, ListOrientation } from './spatialnavigation/ListNavigationGroup';\nimport { EcoModeContainer } from './components/ecomodecontainer';\n\nexport namespace UIFactory {\n export function buildDefaultUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernUI(player, config);\n }\n\n export function buildDefaultSmallScreenUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernSmallScreenUI(player, config);\n }\n\n export function buildDefaultCastReceiverUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernCastReceiverUI(player, config);\n }\n\n export function buildDefaultTvUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernTvUI(player, config);\n }\n\n export function modernUI(config: UIConfig) {\n let subtitleOverlay = new SubtitleOverlay();\n\n let mainSettingsPanelPage: SettingsPanelPage;\n\n const components: Container<ContainerConfig>[] = [\n new SettingsPanelItem(i18n.getLocalizer('settings.video.quality'), new VideoQualitySelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('speed'), new PlaybackSpeedSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.track'), new AudioTrackSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.quality'), new AudioQualitySelectBox()),\n ];\n\n if (config.ecoMode) {\n const ecoModeContainer = new EcoModeContainer();\n\n ecoModeContainer.setOnToggleCallback(() => {\n // forces the browser to re-calculate the height of the settings panel when adding/removing elements\n settingsPanel.getDomElement().css({ width: '', height: '' });\n });\n\n components.unshift(ecoModeContainer);\n }\n\n mainSettingsPanelPage = new SettingsPanelPage({\n components,\n });\n\n let settingsPanel = new SettingsPanel({\n components: [mainSettingsPanelPage],\n hidden: true,\n });\n\n let subtitleSettingsPanelPage = new SubtitleSettingsPanelPage({\n settingsPanel: settingsPanel,\n overlay: subtitleOverlay,\n });\n\n const subtitleSelectBox = new SubtitleSelectBox();\n\n let subtitleSettingsOpenButton = new SettingsPanelPageOpenButton({\n targetPage: subtitleSettingsPanelPage,\n container: settingsPanel,\n ariaLabel: i18n.getLocalizer('settings.subtitles'),\n text: i18n.getLocalizer('open'),\n });\n\n mainSettingsPanelPage.addComponent(\n new SettingsPanelItem(\n new SubtitleSettingsLabel({\n text: i18n.getLocalizer('settings.subtitles'),\n opener: subtitleSettingsOpenButton,\n }),\n subtitleSelectBox,\n {\n role: 'menubar',\n },\n ),\n );\n\n settingsPanel.addComponent(subtitleSettingsPanelPage);\n\n let controlBar = new ControlBar({\n components: [\n settingsPanel,\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n new Container({\n components: [\n new PlaybackToggleButton(),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new CastToggleButton(),\n new VRToggleButton(),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new CastStatusOverlay(),\n controlBar,\n new TitleBar(),\n new RecommendationOverlay(),\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernAdsUI() {\n return new UIContainer({\n components: [\n new BufferingOverlay(),\n new AdClickOverlay(),\n new PlaybackToggleOverlay(),\n new Container({\n components: [new AdMessageLabel({ text: i18n.getLocalizer('ads.remainingTime') }), new AdSkipButton()],\n cssClass: 'ui-ads-status',\n }),\n new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackToggleButton(),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n }),\n ],\n cssClasses: ['ui-skin-ads'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernSmallScreenUI() {\n let subtitleOverlay = new SubtitleOverlay();\n\n let mainSettingsPanelPage = new SettingsPanelPage({\n components: [\n new SettingsPanelItem(i18n.getLocalizer('settings.video.quality'), new VideoQualitySelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('speed'), new PlaybackSpeedSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.track'), new AudioTrackSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.quality'), new AudioQualitySelectBox()),\n ],\n });\n\n let settingsPanel = new SettingsPanel({\n components: [mainSettingsPanelPage],\n hidden: true,\n pageTransitionAnimation: false,\n hideDelay: -1,\n });\n\n let subtitleSettingsPanelPage = new SubtitleSettingsPanelPage({\n settingsPanel: settingsPanel,\n overlay: subtitleOverlay,\n });\n\n let subtitleSettingsOpenButton = new SettingsPanelPageOpenButton({\n targetPage: subtitleSettingsPanelPage,\n container: settingsPanel,\n ariaLabel: i18n.getLocalizer('settings.subtitles'),\n text: i18n.getLocalizer('open'),\n });\n\n const subtitleSelectBox = new SubtitleSelectBox();\n\n mainSettingsPanelPage.addComponent(\n new SettingsPanelItem(\n new SubtitleSettingsLabel({\n text: i18n.getLocalizer('settings.subtitles'),\n opener: subtitleSettingsOpenButton,\n }),\n subtitleSelectBox,\n {\n role: 'menubar',\n },\n ),\n );\n\n settingsPanel.addComponent(subtitleSettingsPanelPage);\n\n settingsPanel.addComponent(new CloseButton({ target: settingsPanel }));\n subtitleSettingsPanelPage.addComponent(new CloseButton({ target: settingsPanel }));\n\n let controlBar = new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new CastStatusOverlay(),\n new PlaybackToggleOverlay(),\n new RecommendationOverlay(),\n controlBar,\n new TitleBar({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n new CastToggleButton(),\n new VRToggleButton(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new VolumeToggleButton(),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n }),\n settingsPanel,\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-smallscreen'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernSmallScreenAdsUI() {\n return new UIContainer({\n components: [\n new BufferingOverlay(),\n new AdClickOverlay(),\n new PlaybackToggleOverlay(),\n new TitleBar({\n components: [\n // dummy label with no content to move buttons to the right\n new Label({ cssClass: 'label-metadata-title' }),\n new FullscreenToggleButton(),\n ],\n }),\n new Container({\n components: [new AdMessageLabel({ text: 'Ad: {remainingTime} secs' }), new AdSkipButton()],\n cssClass: 'ui-ads-status',\n }),\n ],\n cssClasses: ['ui-skin-ads', 'ui-skin-smallscreen'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernCastReceiverUI() {\n let controlBar = new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ smoothPlaybackPositionUpdateIntervalMs: -1 }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n });\n\n return new CastUIContainer({\n components: [\n new SubtitleOverlay(),\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new Watermark(),\n controlBar,\n new TitleBar({ keepHiddenWithoutMetadata: true }),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-cast-receiver'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function buildModernUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n // show smallScreen UI only on mobile/handheld devices\n let smallScreenSwitchWidth = 600;\n\n return new UIManager(\n player,\n [\n {\n ui: modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return (\n context.isMobile && context.documentWidth < smallScreenSwitchWidth && context.isAd && context.adRequiresUi\n );\n },\n },\n {\n ui: modernAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n },\n {\n ui: modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return (\n !context.isAd &&\n !context.adRequiresUi &&\n context.isMobile &&\n context.documentWidth < smallScreenSwitchWidth\n );\n },\n },\n {\n ui: modernUI(config),\n condition: (context: UIConditionContext) => {\n return !context.isAd && !context.adRequiresUi;\n },\n },\n ],\n config,\n );\n }\n\n export function buildModernSmallScreenUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(\n player,\n [\n {\n ui: modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n },\n {\n ui: modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return !context.isAd && !context.adRequiresUi;\n },\n },\n ],\n config,\n );\n }\n\n export function buildModernCastReceiverUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(player, modernCastReceiverUI(), config);\n }\n\n export function buildModernTvUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(\n player,\n [\n {\n ...modernTvUI(),\n },\n ],\n config,\n );\n }\n\n export function modernTvUI() {\n const subtitleListBox = new SubtitleListBox();\n const subtitleListPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [new SettingsPanelItem(null, subtitleListBox)],\n }),\n ],\n hidden: true,\n });\n\n const audioTrackListBox = new AudioTrackListBox();\n const audioTrackListPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [new SettingsPanelItem(null, audioTrackListBox)],\n }),\n ],\n hidden: true,\n });\n\n const seekBar = new SeekBar({ label: new SeekBarLabel() });\n const playbackToggleOverlay = new PlaybackToggleOverlay();\n const subtitleToggleButton = new SettingsToggleButton({\n settingsPanel: subtitleListPanel,\n autoHideWhenNoActiveSettings: true,\n cssClass: 'ui-subtitlesettingstogglebutton',\n text: i18n.getLocalizer('settings.subtitles'),\n });\n const audioToggleButton = new SettingsToggleButton({\n settingsPanel: audioTrackListPanel,\n autoHideWhenNoActiveSettings: true,\n cssClass: 'ui-audiotracksettingstogglebutton',\n ariaLabel: i18n.getLocalizer('settings.audio.track'),\n text: i18n.getLocalizer('settings.audio.track'),\n });\n const uiContainer = new UIContainer({\n components: [\n new SubtitleOverlay(),\n new BufferingOverlay(),\n playbackToggleOverlay,\n new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n seekBar,\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.RemainingTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n }),\n new TitleBar({\n components: [\n new Container({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n subtitleToggleButton,\n audioToggleButton,\n ],\n cssClasses: ['ui-titlebar-top'],\n }),\n new Container({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Description }),\n subtitleListPanel,\n audioTrackListPanel,\n ],\n cssClasses: ['ui-titlebar-bottom'],\n }),\n ],\n }),\n new RecommendationOverlay(),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-tv'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n\n const spatialNavigation = new SpatialNavigation(\n new RootNavigationGroup(uiContainer, playbackToggleOverlay, seekBar, audioToggleButton, subtitleToggleButton),\n new ListNavigationGroup(ListOrientation.Vertical, subtitleListPanel, subtitleListBox),\n new ListNavigationGroup(ListOrientation.Vertical, audioTrackListPanel, audioTrackListBox),\n );\n\n return {\n ui: uiContainer,\n spatialNavigation: spatialNavigation,\n };\n }\n}\n","import {UIContainer} from './components/uicontainer';\nimport {DOM} from './dom';\nimport { Component, ComponentConfig, ViewModeChangedEventArgs } from './components/component';\nimport {Container} from './components/container';\nimport { SeekBar, SeekBarMarker } from './components/seekbar';\nimport {NoArgs, EventDispatcher, CancelEventArgs} from './eventdispatcher';\nimport {UIUtils} from './uiutils';\nimport {ArrayUtils} from './arrayutils';\nimport {BrowserUtils} from './browserutils';\nimport { TimelineMarker, UIConfig } from './uiconfig';\nimport { PlayerAPI, PlayerEventCallback, PlayerEventBase, PlayerEvent, AdEvent, LinearAd } from 'bitmovin-player';\nimport { VolumeController } from './volumecontroller';\nimport { i18n, CustomVocabulary, Vocabularies } from './localization/i18n';\nimport { FocusVisibilityTracker } from './focusvisibilitytracker';\nimport { isMobileV3PlayerAPI, MobileV3PlayerAPI, MobileV3PlayerEvent } from './mobilev3playerapi';\nimport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nimport { SubtitleSettingsManager } from './components/subtitlesettings/subtitlesettingsmanager';\nimport { StorageUtils } from './storageutils';\n\n/**\n * @category Configs\n */\nexport interface LocalizationConfig {\n /**\n * Sets the desired language, and falls back to 'en' if there is no vocabulary for the desired language. Setting it\n * to \"auto\" will enable language detection from the browser's locale.\n */\n language?: 'auto' | 'en' | 'de' | string;\n /**\n * A map of `language` to {@link CustomVocabulary} definitions. Can be used to overwrite default translations and add\n * custom strings or additional languages.\n */\n vocabularies?: Vocabularies;\n}\n\n/**\n * @category Configs\n */\nexport interface InternalUIConfig extends UIConfig {\n events: {\n /**\n * Fires when the configuration has been updated/changed.\n */\n onUpdated: EventDispatcher<UIManager, void>;\n };\n volumeController: VolumeController;\n}\n\n/**\n * The context that will be passed to a {@link UIConditionResolver} to determine if it's conditions fulfil the context.\n */\nexport interface UIConditionContext {\n /**\n * Tells if the player is loading or playing an ad.\n */\n isAd: boolean;\n /**\n * Tells if the current ad requires an external UI, if {@link #isAd} is true.\n */\n adRequiresUi: boolean;\n /**\n * Tells if the player is currently in fullscreen mode.\n */\n isFullscreen: boolean;\n /**\n * Tells if the UI is running in a mobile browser.\n */\n isMobile: boolean;\n /**\n * Tells if the player is in playing or paused state.\n */\n isPlaying: boolean;\n /**\n * The width of the player/UI element.\n */\n width: number;\n /**\n * The width of the document where the player/UI is embedded in.\n */\n documentWidth: number;\n}\n\n/**\n * Resolves the conditions of its associated UI in a {@link UIVariant} upon a {@link UIConditionContext} and decides\n * if the UI should be displayed. If it returns true, the UI is a candidate for display; if it returns false, it will\n * not be displayed in the given context.\n */\nexport interface UIConditionResolver {\n (context: UIConditionContext): boolean;\n}\n\n/**\n * Associates a UI instance with an optional {@link UIConditionResolver} that determines if the UI should be displayed.\n */\nexport interface UIVariant {\n ui: UIContainer;\n condition?: UIConditionResolver;\n spatialNavigation?: SpatialNavigation;\n}\n\nexport interface ActiveUiChangedArgs extends NoArgs {\n /**\n * The previously active {@link UIInstanceManager} prior to the {@link UIManager} switching to a different UI variant.\n */\n previousUi: UIInstanceManager;\n /**\n * The currently active {@link UIInstanceManager}.\n */\n currentUi: UIInstanceManager;\n}\n\nexport class UIManager {\n\n private player: PlayerAPI;\n private uiContainerElement: DOM;\n private uiVariants: UIVariant[];\n private uiInstanceManagers: InternalUIInstanceManager[];\n private currentUi: InternalUIInstanceManager;\n private config: InternalUIConfig; // Conjunction of provided uiConfig and sourceConfig from the player\n private managerPlayerWrapper: PlayerWrapper;\n private focusVisibilityTracker: FocusVisibilityTracker;\n private subtitleSettingsManager: SubtitleSettingsManager;\n\n private events = {\n onUiVariantResolve: new EventDispatcher<UIManager, UIConditionContext>(),\n onActiveUiChanged: new EventDispatcher<UIManager, ActiveUiChangedArgs>(),\n };\n\n /**\n * Creates a UI manager with a single UI variant that will be permanently shown.\n * @param player the associated player of this UI\n * @param ui the UI to add to the player\n * @param uiconfig optional UI configuration\n */\n constructor(player: PlayerAPI, ui: UIContainer, uiconfig?: UIConfig);\n /**\n * Creates a UI manager with a list of UI variants that will be dynamically selected and switched according to\n * the context of the UI.\n *\n * Every time the UI context changes, the conditions of the UI variants will be sequentially resolved and the first\n * UI, whose condition evaluates to true, will be selected and displayed. The last variant in the list might omit the\n * condition resolver and will be selected as default/fallback UI when all other conditions fail. If there is no\n * fallback UI and all conditions fail, no UI will be displayed.\n *\n * @param player the associated player of this UI\n * @param uiVariants a list of UI variants that will be dynamically switched\n * @param uiconfig optional UI configuration\n */\n constructor(player: PlayerAPI, uiVariants: UIVariant[], uiconfig?: UIConfig);\n constructor(player: PlayerAPI, playerUiOrUiVariants: UIContainer | UIVariant[], uiconfig: UIConfig = {}) {\n if (playerUiOrUiVariants instanceof UIContainer) {\n // Single-UI constructor has been called, transform arguments to UIVariant[] signature\n let playerUi = <UIContainer>playerUiOrUiVariants;\n let uiVariants = [];\n\n // Add the default player UI\n uiVariants.push({ ui: playerUi });\n\n this.uiVariants = uiVariants;\n }\n else {\n // Default constructor (UIVariant[]) has been called\n this.uiVariants = <UIVariant[]>playerUiOrUiVariants;\n }\n\n this.subtitleSettingsManager = new SubtitleSettingsManager();\n this.player = player;\n this.managerPlayerWrapper = new PlayerWrapper(player);\n\n // ensure that at least the metadata object does exist in the uiconfig\n uiconfig.metadata = uiconfig.metadata ? uiconfig.metadata : {};\n\n this.config = {\n playbackSpeedSelectionEnabled: true, // Switch on speed selector by default\n autoUiVariantResolve: true, // Switch on auto UI resolving by default\n disableAutoHideWhenHovered: false, // Disable auto hide when UI is hovered\n enableSeekPreview: true,\n ...uiconfig,\n events: {\n onUpdated: new EventDispatcher<UIManager, void>(),\n },\n volumeController: new VolumeController(this.managerPlayerWrapper.getPlayer()),\n };\n\n /**\n * Gathers configuration data from the UI config and player source config and creates a merged UI config\n * that is used throughout the UI instance.\n */\n const updateConfig = () => {\n const playerSourceConfig = player.getSource() || {};\n this.config.metadata = JSON.parse(JSON.stringify(uiconfig.metadata || {}));\n\n // Extract the UI-related config properties from the source config\n const playerSourceUiConfig: UIConfig = {\n metadata: {\n // TODO move metadata into source.metadata namespace in player v8\n title: playerSourceConfig.title,\n description: playerSourceConfig.description,\n markers: (playerSourceConfig as any).markers,\n },\n recommendations: (playerSourceConfig as any).recommendations,\n };\n\n // Player source config takes precedence over the UI config, because the config in the source is attached\n // to a source which changes with every player.load, whereas the UI config stays the same for the whole\n // lifetime of the player instance.\n this.config.metadata.title = playerSourceUiConfig.metadata.title || uiconfig.metadata.title;\n this.config.metadata.description = playerSourceUiConfig.metadata.description || uiconfig.metadata.description;\n this.config.metadata.markers = playerSourceUiConfig.metadata.markers || uiconfig.metadata.markers || [];\n this.config.recommendations = playerSourceUiConfig.recommendations || uiconfig.recommendations || [];\n\n StorageUtils.setStorageApiDisabled(uiconfig);\n };\n\n updateConfig();\n this.subtitleSettingsManager.initialize();\n\n // Update the source configuration when a new source is loaded and dispatch onUpdated\n const updateSource = () => {\n updateConfig();\n this.config.events.onUpdated.dispatch(this);\n };\n\n const wrappedPlayer = this.managerPlayerWrapper.getPlayer();\n\n wrappedPlayer.on(this.player.exports.PlayerEvent.SourceLoaded, updateSource);\n\n // The PlaylistTransition event is only available on Mobile v3 for now.\n // This event is fired when a new source becomes active in the player.\n if (isMobileV3PlayerAPI(wrappedPlayer)) {\n wrappedPlayer.on(MobileV3PlayerEvent.PlaylistTransition, updateSource);\n }\n\n if (uiconfig.container) {\n // Unfortunately \"uiContainerElement = new DOM(config.container)\" will not accept the container with\n // string|HTMLElement type directly, although it accepts both types, so we need to spit these two cases up here.\n // TODO check in upcoming TS versions if the container can be passed in directly, or fix the constructor\n this.uiContainerElement = uiconfig.container instanceof HTMLElement ?\n new DOM(uiconfig.container) : new DOM(uiconfig.container);\n } else {\n this.uiContainerElement = new DOM(player.getContainer());\n }\n\n // Create UI instance managers for the UI variants\n // The instance managers map to the corresponding UI variants by their array index\n this.uiInstanceManagers = [];\n let uiVariantsWithoutCondition = [];\n for (let uiVariant of this.uiVariants) {\n if (uiVariant.condition == null) {\n // Collect variants without conditions for error checking\n uiVariantsWithoutCondition.push(uiVariant);\n }\n // Create the instance manager for a UI variant\n this.uiInstanceManagers.push(new InternalUIInstanceManager(\n player,\n uiVariant.ui,\n this.config,\n this.subtitleSettingsManager,\n uiVariant.spatialNavigation,\n ));\n }\n // Make sure that there is only one UI variant without a condition\n // It does not make sense to have multiple variants without condition, because only the first one in the list\n // (the one with the lowest index) will ever be selected.\n if (uiVariantsWithoutCondition.length > 1) {\n throw Error('Too many UIs without a condition: You cannot have more than one default UI');\n }\n // Make sure that the default UI variant, if defined, is at the end of the list (last index)\n // If it comes earlier, the variants with conditions that come afterwards will never be selected because the\n // default variant without a condition always evaluates to 'true'\n if (uiVariantsWithoutCondition.length > 0\n && uiVariantsWithoutCondition[0] !== this.uiVariants[this.uiVariants.length - 1]) {\n throw Error('Invalid UI variant order: the default UI (without condition) must be at the end of the list');\n }\n\n let adStartedEvent: AdEvent = null; // keep the event stored here during ad playback\n\n // Dynamically select a UI variant that matches the current UI condition.\n let resolveUiVariant = (event: PlayerEventBase) => {\n // Make sure that the AdStarted event data is persisted through ad playback in case other events happen\n // in the meantime, e.g. player resize. We need to store this data because there is no other way to find out\n // ad details while an ad is playing (in v8.0 at least; from v8.1 there will be ads.getActiveAd()).\n // Existing event data signals that an ad is currently active (instead of ads.isLinearAdActive()).\n if (event != null) {\n switch (event.type) {\n // The ads UI is shown upon the first AdStarted event. Subsequent AdStarted events within an ad break\n // will not change the condition context and thus not lead to undesired UI variant resolving.\n // The ads UI is shown upon AdStarted instead of AdBreakStarted because there can be a loading delay\n // between these two events in the player, and the AdBreakStarted event does not carry any metadata to\n // initialize the ads UI, so it would be rendered in an uninitialized state for a certain amount of time.\n // TODO show ads UI upon AdBreakStarted and display loading overlay between AdBreakStarted and first AdStarted\n // TODO display loading overlay between AdFinished and next AdStarted\n case player.exports.PlayerEvent.AdStarted:\n adStartedEvent = event as AdEvent;\n break;\n // The ads UI is hidden only when the ad break is finished, i.e. not on AdFinished events. This way we keep\n // the ads UI variant active throughout an ad break, as reacting to AdFinished would lead to undesired UI\n // variant switching between two ads in an ad break, e.g. ads UI -> AdFinished -> content UI ->\n // AdStarted -> ads UI.\n case player.exports.PlayerEvent.AdBreakFinished:\n adStartedEvent = null;\n // When switching to a variant for the first time, a config.events.onUpdated event is fired to trigger a UI\n // update of the new variant, because most components subscribe to this event to update themselves. When\n // switching to the ads UI on the first AdStarted, all UI variants update themselves with the ad data, so\n // when switching back to the \"normal\" UI it will carry properties of the ad instead of the main content.\n // We thus fire this event here to force an UI update with the properties of the main content. This is\n // basically a hack because the config.events.onUpdated event is abused in many places and not just used\n // for config updates (e.g. adding a marker to the seekbar).\n // TODO introduce an event that is fired when the playback content is updated, a switch to/from ads\n this.config.events.onUpdated.dispatch(this);\n break;\n // When a new source is loaded during ad playback, there will be no Ad(Break)Finished event\n case player.exports.PlayerEvent.SourceLoaded:\n case player.exports.PlayerEvent.SourceUnloaded:\n adStartedEvent = null;\n break;\n }\n }\n\n // Detect if an ad has started\n let isAd = adStartedEvent != null;\n let adRequiresUi = false;\n if (isAd) {\n let ad = adStartedEvent.ad;\n // for now only linear ads can request a UI\n if (ad.isLinear) {\n let linearAd = ad as LinearAd;\n adRequiresUi = linearAd.uiConfig && linearAd.uiConfig.requestsUi || false;\n }\n }\n\n if (adRequiresUi) {\n // we dispatch onUpdated event because if there are multiple adBreaks for same position\n // `Play` and `Playing` events will not be dispatched which will cause `PlaybackButton` state\n // to be out of sync\n this.config.events.onUpdated.dispatch(this);\n }\n\n this.resolveUiVariant({\n isAd: isAd,\n adRequiresUi: adRequiresUi,\n }, (context) => {\n // If this is an ad UI, we need to relay the saved ON_AD_STARTED event data so ad components can configure\n // themselves for the current ad.\n if (context.isAd) {\n /* Relay the ON_AD_STARTED event to the ads UI\n *\n * Because the ads UI is initialized in the ON_AD_STARTED handler, i.e. when the ON_AD_STARTED event has\n * already been fired, components in the ads UI that listen for the ON_AD_STARTED event never receive it.\n * Since this can break functionality of components that rely on this event, we relay the event to the\n * ads UI components with the following call.\n */\n this.currentUi.getWrappedPlayer().fireEventInUI(this.player.exports.PlayerEvent.AdStarted, adStartedEvent);\n }\n });\n };\n\n // Listen to the following events to trigger UI variant resolution\n if (this.config.autoUiVariantResolve) {\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.SourceLoaded, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.SourceUnloaded, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.Play, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.Paused, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.AdStarted, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.AdBreakFinished, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.PlayerResized, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.ViewModeChanged, resolveUiVariant);\n }\n\n this.focusVisibilityTracker = new FocusVisibilityTracker('{{PREFIX}}');\n\n // Initialize the UI\n resolveUiVariant(null);\n }\n\n /**\n * Exposes i18n.getLocalizer() function\n * @returns {I18nApi.getLocalizer()}\n */\n static localize<V extends CustomVocabulary<Record<string, string>>>(key: keyof V) {\n return i18n.getLocalizer(key);\n }\n\n /**\n * Provide configuration to support Custom UI languages\n * default language: 'en'\n */\n static setLocalizationConfig(localizationConfig: LocalizationConfig) {\n i18n.setConfig(localizationConfig);\n }\n\n getSubtitleSettingsManager() {\n return this.subtitleSettingsManager;\n }\n\n getConfig(): UIConfig {\n return this.config;\n }\n\n /**\n * Returns the list of UI variants as passed into the constructor of {@link UIManager}.\n * @returns {UIVariant[]} the list of available UI variants\n */\n getUiVariants(): UIVariant[] {\n return this.uiVariants;\n }\n\n /**\n * Switches to a UI variant from the list returned by {@link getUiVariants}.\n * @param {UIVariant} uiVariant the UI variant to switch to\n * @param {() => void} onShow a callback that is executed just before the new UI variant is shown\n */\n switchToUiVariant(uiVariant: UIVariant, onShow?: () => void): void {\n let uiVariantIndex = this.uiVariants.indexOf(uiVariant);\n\n const previousUi = this.currentUi;\n const nextUi: InternalUIInstanceManager = this.uiInstanceManagers[uiVariantIndex];\n // Determine if the UI variant is changing\n // Only if the UI variant is changing, we need to do some stuff. Else we just leave everything as-is.\n if (nextUi === this.currentUi) {\n return;\n // console.log('switched from ', this.currentUi ? this.currentUi.getUI() : 'none',\n // ' to ', nextUi ? nextUi.getUI() : 'none');\n }\n\n // Hide the currently active UI variant\n if (this.currentUi) {\n this.currentUi.getUI().hide();\n }\n\n // Assign the new UI variant as current UI\n this.currentUi = nextUi;\n\n // When we switch to a different UI instance, there's some additional stuff to manage. If we do not switch\n // to an instance, we're done here.\n if (this.currentUi == null) {\n return;\n }\n // Add the UI to the DOM (and configure it) the first time it is selected\n if (!this.currentUi.isConfigured()) {\n this.addUi(this.currentUi);\n // ensure that the internal state is ready for the upcoming show call\n if (!this.currentUi.getUI().isHidden()) {\n this.currentUi.getUI().hide();\n }\n }\n if (onShow) {\n onShow();\n }\n this.currentUi.getUI().show();\n this.events.onActiveUiChanged.dispatch(this, { previousUi, currentUi: nextUi });\n }\n\n /**\n * Triggers a UI variant switch as triggered by events when automatic switching is enabled. It allows to overwrite\n * properties of the {@link UIConditionContext}.\n * @param {Partial<UIConditionContext>} context an optional set of properties that overwrite properties of the\n * automatically determined context\n * @param {(context: UIConditionContext) => void} onShow a callback that is executed just before the new UI variant\n * is shown (if a switch is happening)\n */\n resolveUiVariant(context: Partial<UIConditionContext> = {}, onShow?: (context: UIConditionContext) => void): void {\n // Determine the current context for which the UI variant will be resolved\n const defaultContext: UIConditionContext = {\n isAd: false,\n adRequiresUi: false,\n isFullscreen: this.player.getViewMode() === this.player.exports.ViewMode.Fullscreen,\n isMobile: BrowserUtils.isMobile,\n isPlaying: this.player.isPlaying(),\n width: this.uiContainerElement.width(),\n documentWidth: document.body.clientWidth,\n };\n\n // Overwrite properties of the default context with passed in context properties\n const switchingContext = { ...defaultContext, ...context };\n\n // Fire the event and allow modification of the context before it is used to resolve the UI variant\n this.events.onUiVariantResolve.dispatch(this, switchingContext);\n\n let nextUiVariant: UIVariant = null;\n\n // Select new UI variant\n // If no variant condition is fulfilled, we switch to *no* UI\n for (let uiVariant of this.uiVariants) {\n const matchesCondition = uiVariant.condition == null || uiVariant.condition(switchingContext) === true;\n if (nextUiVariant == null && matchesCondition) {\n nextUiVariant = uiVariant;\n } else {\n // hide all UIs besides the one which should be active\n uiVariant.ui.hide();\n }\n }\n\n this.switchToUiVariant(nextUiVariant, () => {\n if (onShow) {\n onShow(switchingContext);\n }\n });\n }\n\n private addUi(ui: InternalUIInstanceManager): void {\n let dom = ui.getUI().getDomElement();\n let player = ui.getWrappedPlayer();\n\n ui.configureControls();\n /* Append the UI DOM after configuration to avoid CSS transitions at initialization\n * Example: Components are hidden during configuration and these hides may trigger CSS transitions that are\n * undesirable at this time. */\n this.uiContainerElement.append(dom);\n\n // When the UI is loaded after a source was loaded, we need to tell the components to initialize themselves\n if (player.getSource()) {\n this.config.events.onUpdated.dispatch(this);\n\n }\n\n // Fire onConfigured after UI DOM elements are successfully added. When fired immediately, the DOM elements\n // might not be fully configured and e.g. do not have a size.\n // https://swizec.com/blog/how-to-properly-wait-for-dom-elements-to-show-up-in-modern-browsers/swizec/6663\n if (window.requestAnimationFrame) {\n requestAnimationFrame(() => { ui.onConfigured.dispatch(ui.getUI()); });\n } else {\n // IE9 fallback\n setTimeout(() => { ui.onConfigured.dispatch(ui.getUI()); }, 0);\n }\n }\n\n private releaseUi(ui: InternalUIInstanceManager): void {\n ui.releaseControls();\n\n const uiContainer = ui.getUI();\n if (uiContainer.hasDomElement()) {\n uiContainer.getDomElement().remove();\n }\n\n ui.clearEventHandlers();\n }\n\n release(): void {\n for (let uiInstanceManager of this.uiInstanceManagers) {\n this.releaseUi(uiInstanceManager);\n }\n this.managerPlayerWrapper.clearEventHandlers();\n this.focusVisibilityTracker.release();\n }\n\n /**\n * Fires just before UI variants are about to be resolved and the UI variant is possibly switched. It is fired when\n * the switch is triggered from an automatic switch and when calling {@link resolveUiVariant}.\n * Can be used to modify the {@link UIConditionContext} before resolving is done.\n * @returns {EventDispatcher<UIManager, UIConditionContext>}\n */\n get onUiVariantResolve(): EventDispatcher<UIManager, UIConditionContext> {\n return this.events.onUiVariantResolve;\n }\n\n /**\n * Fires after the UIManager has switched to a different UI variant.\n * @returns {EventDispatcher<UIManager, ActiveUiChangedArgs>}\n */\n get onActiveUiChanged(): EventDispatcher<UIManager, ActiveUiChangedArgs> {\n return this.events.onActiveUiChanged;\n }\n\n /**\n * The current active {@link UIInstanceManager}.\n */\n get activeUi(): UIInstanceManager {\n return this.currentUi;\n }\n\n /**\n * Returns the list of all added markers in undefined order.\n */\n getTimelineMarkers(): TimelineMarker[] {\n return this.config.metadata.markers;\n }\n\n /**\n * Adds a marker to the timeline. Does not check for duplicates/overlaps at the `time`.\n */\n addTimelineMarker(timelineMarker: TimelineMarker): void {\n this.config.metadata.markers.push(timelineMarker);\n this.config.events.onUpdated.dispatch(this);\n }\n\n /**\n * Removes a marker from the timeline (by reference) and returns `true` if the marker has\n * been part of the timeline and successfully removed, or `false` if the marker could not\n * be found and thus not removed.\n */\n removeTimelineMarker(timelineMarker: TimelineMarker): boolean {\n if (ArrayUtils.remove(this.config.metadata.markers, timelineMarker) === timelineMarker) {\n this.config.events.onUpdated.dispatch(this);\n return true;\n }\n\n return false;\n }\n}\n\nexport interface SeekPreviewArgs extends NoArgs {\n /**\n * The timeline position in percent where the event originates from.\n */\n position: number;\n /**\n * The timeline marker associated with the current position, if existing.\n */\n marker?: SeekBarMarker;\n}\n\n/**\n * Encapsulates functionality to manage a UI instance. Used by the {@link UIManager} to manage multiple UI instances.\n */\nexport class UIInstanceManager {\n private playerWrapper: PlayerWrapper;\n private ui: UIContainer;\n private config: InternalUIConfig;\n private subtitleSettingsManager: SubtitleSettingsManager;\n protected spatialNavigation?: SpatialNavigation;\n\n private events = {\n onConfigured: new EventDispatcher<UIContainer, NoArgs>(),\n onSeek: new EventDispatcher<SeekBar, NoArgs>(),\n onSeekPreview: new EventDispatcher<SeekBar, SeekPreviewArgs>(),\n onSeeked: new EventDispatcher<SeekBar, NoArgs>(),\n onComponentShow: new EventDispatcher<Component<ComponentConfig>, NoArgs>(),\n onComponentHide: new EventDispatcher<Component<ComponentConfig>, NoArgs>(),\n onComponentViewModeChanged: new EventDispatcher<Component<ComponentConfig>, ViewModeChangedEventArgs>(),\n onControlsShow: new EventDispatcher<UIContainer, NoArgs>(),\n onPreviewControlsHide: new EventDispatcher<UIContainer, CancelEventArgs>(),\n onControlsHide: new EventDispatcher<UIContainer, NoArgs>(),\n onRelease: new EventDispatcher<UIContainer, NoArgs>(),\n };\n\n constructor(player: PlayerAPI, ui: UIContainer, config: InternalUIConfig, subtitleSettingsManager: SubtitleSettingsManager, spatialNavigation?: SpatialNavigation) {\n this.playerWrapper = new PlayerWrapper(player);\n this.ui = ui;\n this.config = config;\n this.subtitleSettingsManager = subtitleSettingsManager;\n this.spatialNavigation = spatialNavigation;\n }\n\n getSubtitleSettingsManager() {\n return this.subtitleSettingsManager;\n }\n\n getConfig(): InternalUIConfig {\n return this.config;\n }\n\n getUI(): UIContainer {\n return this.ui;\n }\n\n getPlayer(): PlayerAPI {\n return this.playerWrapper.getPlayer();\n }\n\n /**\n * Fires when the UI is fully configured and added to the DOM.\n * @returns {EventDispatcher}\n */\n get onConfigured(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onConfigured;\n }\n\n /**\n * Fires when a seek starts.\n * @returns {EventDispatcher}\n */\n get onSeek(): EventDispatcher<SeekBar, NoArgs> {\n return this.events.onSeek;\n }\n\n /**\n * Fires when the seek timeline is scrubbed.\n * @returns {EventDispatcher}\n */\n get onSeekPreview(): EventDispatcher<SeekBar, SeekPreviewArgs> {\n return this.events.onSeekPreview;\n }\n\n /**\n * Fires when a seek is finished.\n * @returns {EventDispatcher}\n */\n get onSeeked(): EventDispatcher<SeekBar, NoArgs> {\n return this.events.onSeeked;\n }\n\n /**\n * Fires when a component is showing.\n * @returns {EventDispatcher}\n */\n get onComponentShow(): EventDispatcher<Component<ComponentConfig>, NoArgs> {\n return this.events.onComponentShow;\n }\n\n /**\n * Fires when a component is hiding.\n * @returns {EventDispatcher}\n */\n get onComponentHide(): EventDispatcher<Component<ComponentConfig>, NoArgs> {\n return this.events.onComponentHide;\n }\n\n /**\n * Fires when the UI controls are showing.\n * @returns {EventDispatcher}\n */\n get onControlsShow(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onControlsShow;\n }\n\n /**\n * Fires before the UI controls are hiding to check if they are allowed to hide.\n * @returns {EventDispatcher}\n */\n get onPreviewControlsHide(): EventDispatcher<UIContainer, CancelEventArgs> {\n return this.events.onPreviewControlsHide;\n }\n\n /**\n * Fires when the UI controls are hiding.\n * @returns {EventDispatcher}\n */\n get onControlsHide(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onControlsHide;\n }\n\n /**\n * Fires when the UI controls are released.\n * @returns {EventDispatcher}\n */\n get onRelease(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onRelease;\n }\n\n get onComponentViewModeChanged(): EventDispatcher<Component<ComponentConfig>, ViewModeChangedEventArgs> {\n return this.events.onComponentViewModeChanged;\n }\n\n protected clearEventHandlers(): void {\n this.playerWrapper.clearEventHandlers();\n\n let events = <any>this.events; // avoid TS7017\n for (let event in events) {\n let dispatcher = <EventDispatcher<Object, Object>>events[event];\n dispatcher.unsubscribeAll();\n }\n }\n}\n\n/**\n * Extends the {@link UIInstanceManager} for internal use in the {@link UIManager} and provides access to functionality\n * that components receiving a reference to the {@link UIInstanceManager} should not have access to.\n */\nclass InternalUIInstanceManager extends UIInstanceManager {\n\n private configured: boolean;\n private released: boolean;\n\n getWrappedPlayer(): WrappedPlayer {\n // TODO find a non-hacky way to provide the WrappedPlayer to the UIManager without exporting it\n // getPlayer() actually returns the WrappedPlayer but its return type is set to Player so the WrappedPlayer does\n // not need to be exported\n return <WrappedPlayer>this.getPlayer();\n }\n\n configureControls(): void {\n this.configureControlsTree(this.getUI());\n this.configured = true;\n }\n\n isConfigured(): boolean {\n return this.configured;\n }\n\n private configureControlsTree(component: Component<ComponentConfig>) {\n let configuredComponents: Component<ComponentConfig>[] = [];\n\n UIUtils.traverseTree(component, (component) => {\n // First, check if we have already configured a component, and throw an error if we did. Multiple configuration\n // of the same component leads to unexpected UI behavior. Also, a component that is in the UI tree multiple\n // times hints at a wrong UI structure.\n // We could just skip configuration in such a case and not throw an exception, but enforcing a clean UI tree\n // seems like the better choice.\n for (let configuredComponent of configuredComponents) {\n if (configuredComponent === component) {\n // Write the component to the console to simplify identification of the culprit\n // (e.g. by inspecting the config)\n if (console) {\n console.error('Circular reference in UI tree', component);\n }\n\n // Additionally throw an error, because this case must not happen and leads to unexpected UI behavior.\n throw Error('Circular reference in UI tree: ' + component.constructor.name);\n }\n }\n\n component.initialize();\n component.configure(this.getPlayer(), this);\n configuredComponents.push(component);\n });\n }\n\n releaseControls(): void {\n // Do not call release methods if the components have never been configured; this can result in exceptions\n if (this.configured) {\n this.onRelease.dispatch(this.getUI());\n this.releaseControlsTree(this.getUI());\n this.configured = false;\n }\n this.spatialNavigation?.release();\n this.released = true;\n }\n\n isReleased(): boolean {\n return this.released;\n }\n\n private releaseControlsTree(component: Component<ComponentConfig>) {\n component.release();\n\n if (component instanceof Container) {\n for (let childComponent of component.getComponents()) {\n this.releaseControlsTree(childComponent);\n }\n }\n }\n\n clearEventHandlers(): void {\n super.clearEventHandlers();\n }\n}\n\n/**\n * Extended interface of the {@link Player} for use in the UI.\n */\nexport interface WrappedPlayer extends PlayerAPI {\n /**\n * Fires an event on the player that targets all handlers in the UI but never enters the real player.\n * @param event the event to fire\n * @param data data to send with the event\n */\n fireEventInUI(event: PlayerEvent, data: {}): void;\n}\n\n/**\n * Wraps the player to track event handlers and provide a simple method to remove all registered event\n * handlers from the player.\n *\n * @category Utils\n */\nexport class PlayerWrapper {\n\n private player: PlayerAPI;\n private wrapper: WrappedPlayer;\n\n private eventHandlers: { [eventType: string]: PlayerEventCallback[]; } = {};\n\n constructor(player: PlayerAPI) {\n this.player = player;\n\n // Collect all members of the player (public API methods and properties of the player)\n const objectProtoPropertyNames = Object.getOwnPropertyNames(Object.getPrototypeOf({}));\n const namesToIgnore = ['constructor', ...objectProtoPropertyNames];\n const members = getAllPropertyNames(player).filter(name => namesToIgnore.indexOf(name) === -1);\n // Split the members into methods and properties\n let methods = <any[]>[];\n let properties = <any[]>[];\n\n for (let member of members) {\n if (typeof (<any>player)[member] === 'function') {\n methods.push(member);\n } else {\n properties.push(member);\n }\n }\n\n // Create wrapper object\n let wrapper = <any>{};\n\n // Add function wrappers for all API methods that do nothing but calling the base method on the player\n for (let method of methods) {\n wrapper[method] = function() {\n // console.log('called ' + member); // track method calls on the player\n return (<any>player)[method].apply(player, arguments);\n };\n }\n\n // Add all public properties of the player to the wrapper\n for (let property of properties) {\n // Get an eventually existing property descriptor to differentiate between plain properties and properties with\n // getters/setters.\n const propertyDescriptor = ((target: PlayerAPI) => {\n while (target) {\n const propertyDescriptor = Object.getOwnPropertyDescriptor(target, property);\n if (propertyDescriptor) {\n return propertyDescriptor;\n }\n // Check if the PropertyDescriptor exists on a child prototype in case we have an inheritance of the player\n target = Object.getPrototypeOf(target);\n }\n })(player);\n\n // If the property has getters/setters, wrap them accordingly...\n if (propertyDescriptor && (propertyDescriptor.get || propertyDescriptor.set)) {\n Object.defineProperty(wrapper, property, {\n get: () => propertyDescriptor.get.call(player),\n set: (value: any) => propertyDescriptor.set.call(player, value),\n });\n }\n // ... else just transfer the property to the wrapper\n else {\n wrapper[property] = (<any>player)[property];\n }\n }\n\n // Explicitly add a wrapper method for 'on' that adds added event handlers to the event list\n wrapper.on = (eventType: PlayerEvent, callback: PlayerEventCallback) => {\n player.on(eventType, callback);\n\n if (!this.eventHandlers[eventType]) {\n this.eventHandlers[eventType] = [];\n }\n\n this.eventHandlers[eventType].push(callback);\n\n return wrapper;\n };\n\n // Explicitly add a wrapper method for 'off' that removes removed event handlers from the event list\n wrapper.off = (eventType: PlayerEvent, callback: PlayerEventCallback) => {\n player.off(eventType, callback);\n\n if (this.eventHandlers[eventType]) {\n ArrayUtils.remove(this.eventHandlers[eventType], callback);\n }\n\n return wrapper;\n };\n\n wrapper.fireEventInUI = (event: PlayerEvent, data: {}) => {\n if (this.eventHandlers[event]) { // check if there are handlers for this event registered\n // Extend the data object with default values to convert it to a {@link PlayerEventBase} object.\n let playerEventData = <PlayerEventBase>Object.assign({}, {\n timestamp: Date.now(),\n type: event,\n // Add a marker property so the UI can detect UI-internal player events\n uiSourced: true,\n }, data);\n\n // Execute the registered callbacks\n for (let callback of this.eventHandlers[event]) {\n callback(playerEventData);\n }\n }\n };\n\n this.wrapper = <WrappedPlayer>wrapper;\n }\n\n /**\n * Returns a wrapped player object that can be used on place of the normal player object.\n * @returns {WrappedPlayer} a wrapped player\n */\n getPlayer(): WrappedPlayer {\n return this.wrapper;\n }\n\n /**\n * Clears all registered event handlers from the player that were added through the wrapped player.\n */\n clearEventHandlers(): void {\n try {\n // Call the player API to check if the instance is still valid or already destroyed.\n // This can be any call throwing the PlayerAPINotAvailableError when the player instance is destroyed.\n this.player.getSource();\n } catch (error) {\n if (error instanceof this.player.exports.PlayerAPINotAvailableError) {\n // We have detected that the player instance is already destroyed, so we clear the event handlers to avoid\n // event handler unsubscription attempts (which would result in PlayerAPINotAvailableError errors).\n this.eventHandlers = {};\n }\n }\n\n for (let eventType in this.eventHandlers) {\n for (let callback of this.eventHandlers[eventType]) {\n this.player.off(eventType as PlayerEvent, callback);\n }\n }\n }\n}\n\nfunction getAllPropertyNames(target: Object): string[] {\n let names: string[] = [];\n\n while (target) {\n const newNames = Object.getOwnPropertyNames(target).filter(name => names.indexOf(name) === -1);\n names = names.concat(newNames);\n // go up prototype chain\n target = Object.getPrototypeOf(target);\n }\n\n return names;\n}\n","import {Component, ComponentConfig} from './components/component';\nimport {Container} from './components/container';\n\n/**\n * @category Utils\n */\nexport namespace UIUtils {\n export interface TreeTraversalCallback {\n (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>): void;\n }\n\n export function traverseTree(component: Component<ComponentConfig>, visit: TreeTraversalCallback): void {\n let recursiveTreeWalker = (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>) => {\n visit(component, parent);\n\n // If the current component is a container, visit it's children\n if (component instanceof Container) {\n for (let childComponent of component.getComponents()) {\n recursiveTreeWalker(childComponent, component);\n }\n }\n };\n\n // Walk and configure the component tree\n recursiveTreeWalker(component);\n }\n\n // From: https://github.com/nfriend/ts-keycode-enum/blob/master/Key.enum.ts\n export enum KeyCode {\n LeftArrow = 37,\n UpArrow = 38,\n RightArrow = 39,\n DownArrow = 40,\n Space = 32,\n End = 35,\n Home = 36,\n }\n}\n","import { Event, EventDispatcher } from './eventdispatcher';\nimport { PlayerAPI } from 'bitmovin-player';\n\nexport interface VolumeSettingChangedArgs {\n volume: number;\n muted: boolean;\n}\n\n/**\n * Can be used to centrally manage and control the volume and mute state of the player from multiple components.\n */\nexport class VolumeController {\n\n private static readonly issuerName = 'ui-volumecontroller';\n\n private readonly events = {\n onChanged: new EventDispatcher<VolumeController, VolumeSettingChangedArgs>(),\n };\n\n private storedVolume: number;\n\n constructor(private readonly player: PlayerAPI) {\n this.storeVolume();\n\n const handler = () => {\n this.onChangedEvent();\n };\n\n player.on(player.exports.PlayerEvent.SourceLoaded, handler);\n player.on(player.exports.PlayerEvent.VolumeChanged, handler);\n player.on(player.exports.PlayerEvent.Muted, handler);\n player.on(player.exports.PlayerEvent.Unmuted, handler);\n }\n\n setVolume(volume: number): void {\n this.player.setVolume(volume, VolumeController.issuerName);\n }\n\n getVolume(): number {\n return this.player.getVolume();\n }\n\n setMuted(muted: boolean): void {\n if (muted) {\n this.player.mute(VolumeController.issuerName);\n } else {\n this.player.unmute(VolumeController.issuerName);\n }\n }\n\n toggleMuted(): void {\n if (this.isMuted() || this.getVolume() === 0) {\n // Unmuting from the mute or zero-volume state recalls the previously saved volume setting. Setting the\n // volume automatically unmutes the player in v7.\n this.recallVolume();\n } else {\n this.setMuted(true);\n }\n }\n\n isMuted(): boolean {\n return this.player.isMuted();\n }\n\n /**\n * Stores (saves) the current volume so it can later be restored with {@link recallVolume}.\n */\n storeVolume(): void {\n this.storedVolume = this.getVolume();\n }\n\n /**\n * Recalls (sets) the volume previously stored with {@link storeVolume}.\n */\n recallVolume(): void {\n this.setMuted(this.storedVolume === 0);\n this.setVolume(this.storedVolume);\n }\n\n startTransition(): VolumeTransition {\n return new VolumeTransition(this);\n }\n\n onChangedEvent() {\n const playerMuted = this.isMuted();\n const playerVolume = this.getVolume();\n\n const uiMuted = playerMuted || playerVolume === 0;\n const uiVolume = playerMuted ? 0 : playerVolume;\n\n this.storeVolume();\n\n this.events.onChanged.dispatch(this, { volume: uiVolume, muted: uiMuted });\n }\n\n /**\n * Gets the event that is fired when the volume settings have changed.\n */\n get onChanged(): Event<VolumeController, VolumeSettingChangedArgs> {\n return this.events.onChanged.getEvent();\n }\n}\n\nexport class VolumeTransition {\n\n constructor(private controller: VolumeController) {\n // Store the volume at the beginning of a volume change so we can recall it later in case we set the volume to\n // zero and actually mute the player.\n controller.storeVolume();\n }\n\n update(volume: number): void {\n // Update the volume while transitioning so the user has a \"live preview\" of the desired target volume\n this.controller.setMuted(false);\n this.controller.setVolume(volume);\n }\n\n finish(volume: number): void {\n if (volume === 0) {\n // When the volume is zero we essentially mute the volume so we recall the volume from the beginning of the\n // transition and mute the player instead. Recalling is necessary to return to the actual audio volume\n // when unmuting.\n // We must first recall the volume and then mute, because recalling sets the volume on the player\n // and setting a player volume > 0 unmutes the player in v7.\n this.controller.recallVolume();\n this.controller.setMuted(true);\n } else {\n this.controller.setMuted(false);\n this.controller.setVolume(volume);\n this.controller.storeVolume();\n }\n }\n}","import { SubtitleRegionContainer, SubtitleLabel } from './components/subtitleoverlay';\nimport { VTTProperties, VTTRegionProperties } from 'bitmovin-player/types/subtitles/vtt/API';\nimport { DOM, Size } from './dom';\n\n// Our default height of a line\nconst lineHeight = 28;\n\n// Default relative line height\nconst lineHeightPercent = 5;\nlet lineCount: number = 1;\n\nconst defaultLineNumber = 21; // Our default amount of lines\n\nenum Direction {\n Top = 'top',\n Bottom = 'bottom',\n Left = 'left',\n Right = 'right',\n}\n\nenum VttVerticalWriting {\n GrowingRight = 'lr',\n GrowingLeft = 'rl',\n}\n\ntype VerticalWritingDirection = Direction.Left | Direction.Right;\n\nconst DirectionPair = new Map<Direction, Direction>([\n [Direction.Top, Direction.Bottom],\n [Direction.Bottom, Direction.Top],\n [Direction.Left, Direction.Right],\n [Direction.Right, Direction.Left],\n]);\n\n/**\n * Sets the default standardized styles for the Cue Box\n * https://w3.org/TR/webvtt1/#applying-css-properties\n */\nconst setDefaultVttStyles = (cueContainerDom: DOM, vtt: VTTProperties) => {\n if (vtt.region) {\n cueContainerDom.css('position', 'relative');\n cueContainerDom.css('unicode-bidi', 'plaintext');\n } else {\n cueContainerDom.css('position', 'absolute');\n cueContainerDom.css('overflow-wrap', 'break-word');\n cueContainerDom.css('overflow', 'hidden');\n cueContainerDom.css('flex-flow', 'column');\n }\n cueContainerDom.css('display', 'inline-flex');\n};\n\n/**\n * Align the Cue Box's line\n * https://w3.org/TR/webvtt1/#webvtt-cue-line-alignment\n */\nconst setVttLineAlign = (\n cueContainerDom: DOM,\n { lineAlign }: VTTProperties,\n direction: Direction,\n relativeCueBoxPosition: number) => {\n switch (lineAlign) {\n case 'center':\n setCssForCenterLineAlign(\n cueContainerDom, direction, relativeCueBoxPosition);\n break;\n case 'end':\n setCssForEndLineAlign(\n cueContainerDom, direction, relativeCueBoxPosition);\n }\n};\n\n/**\n * Defines the line positioning of the Cue Box\n * https://w3.org/TR/webvtt1/#webvtt-cue-line\n */\nconst setVttLine = (\n cueContainerDom: DOM,\n vtt: VTTProperties,\n direction: Direction,\n subtitleOverLaySize: Size,\n) => {\n const overlayReferenceEdge = DirectionPair.get(direction);\n if (vtt.line === 'auto' && vtt.vertical) {\n cueContainerDom.css(overlayReferenceEdge, '0');\n return;\n }\n if (vtt.line === 'auto' && !vtt.vertical) {\n return;\n }\n\n let relativeLinePosition = parseFloat(vtt.line as string);\n\n if (vtt.snapToLines) {\n let targetLine = Number(vtt.line);\n if (targetLine < 0) {\n targetLine = defaultLineNumber + targetLine;\n }\n\n const lineHeight = subtitleOverLaySize.height / defaultLineNumber;\n const absoluteLinePosition = lineHeight * targetLine;\n relativeLinePosition = (100 * absoluteLinePosition) / subtitleOverLaySize.height;\n }\n\n if (vtt.lineAlign !== 'end')\n cueContainerDom.css(\n overlayReferenceEdge, `${relativeLinePosition}%`);\n setVttLineAlign(cueContainerDom, vtt, direction, relativeLinePosition);\n};\n\n/**\n * Defines the writing direction of the Cue Box\n * https://w3.org/TR/webvtt1/#webvtt-cue-writing-direction\n */\nconst setVttWritingDirectionAndCueBoxPositioning = (\n cueContainerDom: DOM, vtt: VTTProperties,\n subtitleOverlaySize: Size,\n) => {\n switch (vtt.vertical) {\n case '':\n cueContainerDom.css('writing-mode', 'horizontal-tb');\n cueContainerDom.css(Direction.Bottom, '0');\n setVttLine(cueContainerDom, vtt, Direction.Bottom, subtitleOverlaySize);\n break;\n case VttVerticalWriting.GrowingRight:\n setCueBoxPositionForVerticalWriting(\n cueContainerDom, Direction.Right, vtt, subtitleOverlaySize);\n break;\n case VttVerticalWriting.GrowingLeft:\n setCueBoxPositionForVerticalWriting(\n cueContainerDom, Direction.Left, vtt, subtitleOverlaySize);\n break;\n }\n};\n\nconst setCueBoxPositionForVerticalWriting = (\n cueContainerDom: DOM,\n direction: VerticalWritingDirection,\n vtt: VTTProperties,\n subtitleOverlaySize: Size,\n) => {\n const writingMode = direction === Direction.Right ?\n 'vertical-lr' : 'vertical-rl';\n\n cueContainerDom.css('writing-mode', writingMode);\n cueContainerDom.css(Direction.Top, '0');\n setVttLine(cueContainerDom, vtt, direction, subtitleOverlaySize);\n};\n\n/**\n * Defines the Cue position alignment\n * https://w3.org/TR/webvtt1/#webvtt-cue-position-alignment\n */\nconst setVttPositionAlign = (cueContainerDom: DOM, vtt: VTTProperties, direction: Direction) => {\n // https://www.w3.org/TR/webvtt1/#webvtt-cue-position\n if (vtt.position === 'auto') {\n cueContainerDom.css(direction, '0');\n } else {\n switch (vtt.positionAlign) {\n case 'line-left':\n cueContainerDom.css(direction, `${vtt.position}%`);\n cueContainerDom.css(DirectionPair.get(direction), 'auto');\n cueContainerDom.css('justify-content', 'flex-start');\n break;\n case 'center':\n cueContainerDom.css(direction, `${vtt.position - vtt.size / 2}%`);\n cueContainerDom.css(DirectionPair.get(direction), 'auto');\n cueContainerDom.css('justify-content', 'center');\n break;\n case 'line-right':\n cueContainerDom.css(direction, 'auto');\n cueContainerDom.css(DirectionPair.get(direction), `${100 - vtt.position}%`);\n cueContainerDom.css('justify-content', 'flex-end');\n break;\n default:\n cueContainerDom.css(direction, `${vtt.position}%`);\n cueContainerDom.css('justify-content', 'flex-start');\n }\n }\n};\n\nconst countLines = (innerHtml: string) =>\n innerHtml.split('<br />').length;\n\nconst setCssForCenterLineAlign = (\n cueContainerDom: DOM,\n direction: Direction,\n relativeCueBoxPosition: number) => {\n switch (direction) {\n case Direction.Bottom:\n cueContainerDom.css('transform', 'translateY(-50%)');\n break;\n case Direction.Left:\n cueContainerDom.css('transform', 'translateX(50%)');\n break;\n case Direction.Right:\n cueContainerDom.css('transform', 'translateX(-50%)');\n break;\n }\n};\n\nconst setCssForEndLineAlign = (\n cueContainerDom: DOM,\n direction: Direction,\n offset: number) => {\n const opositeToOverlayReferenceEdge = direction;\n cueContainerDom.css(opositeToOverlayReferenceEdge, `${100 - offset}%`);\n};\n\n/**\n * @category Utils\n */\nexport namespace VttUtils {\n export const setVttCueBoxStyles = (\n cueContainer: SubtitleLabel,\n subtitleOverlaySize: Size,\n ) => {\n const vtt = cueContainer.vtt;\n const cueContainerDom = cueContainer.getDomElement();\n\n\n setDefaultVttStyles(cueContainerDom, vtt);\n\n lineCount = countLines(cueContainer.getText());\n setVttWritingDirectionAndCueBoxPositioning(cueContainerDom, vtt, subtitleOverlaySize);\n\n // https://w3.org/TR/webvtt1/#webvtt-cue-text-alignment\n const textAlign = vtt.align === 'middle' ? 'center' : vtt.align;\n cueContainerDom.css('text-align', textAlign);\n\n // https://w3.org/TR/webvtt1/#webvtt-cue-size\n const containerSize = vtt.size;\n if (vtt.vertical === '') {\n cueContainerDom.css('width', `${containerSize}%`);\n setVttPositionAlign(cueContainerDom, vtt, Direction.Left);\n } else {\n cueContainerDom.css('height', `${containerSize}%`);\n setVttPositionAlign(cueContainerDom, vtt, Direction.Top);\n }\n };\n\n /** https://www.w3.org/TR/webvtt1/#regions\n * https://www.speechpad.com/captions/webvtt#toc_16\n */\n export const setVttRegionStyles = (\n regionContainer: SubtitleRegionContainer,\n region: VTTRegionProperties,\n overlaySize: Size,\n ) => {\n const regionContainerDom = regionContainer.getDomElement();\n const regionPositionX = overlaySize.width * region.viewportAnchorX / 100 - ((overlaySize.width * region.width / 100) * region.regionAnchorX / 100);\n const regionPositionY = overlaySize.height * region.viewportAnchorY / 100 - ((region.lines * lineHeight) * region.regionAnchorY / 100);\n regionContainerDom.css('position', 'absolute');\n regionContainerDom.css('overflow', 'hidden');\n regionContainerDom.css('width', `${region.width}%`);\n regionContainerDom.css(Direction.Left, `${regionPositionX}px`);\n regionContainerDom.css(Direction.Right, 'unset');\n regionContainerDom.css(Direction.Top, `${regionPositionY}px`);\n regionContainerDom.css(Direction.Bottom, 'unset');\n regionContainerDom.css('height', `${region.lines * lineHeight}px`);\n };\n}\n"]}
1
+ {"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/ts/arrayutils.ts","src/ts/audiotrackutils.ts","src/ts/browserutils.ts","src/ts/components/adclickoverlay.ts","src/ts/components/admessagelabel.ts","src/ts/components/adskipbutton.ts","src/ts/components/airplaytogglebutton.ts","src/ts/components/audioqualityselectbox.ts","src/ts/components/audiotracklistbox.ts","src/ts/components/audiotrackselectbox.ts","src/ts/components/bufferingoverlay.ts","src/ts/components/button.ts","src/ts/components/caststatusoverlay.ts","src/ts/components/casttogglebutton.ts","src/ts/components/castuicontainer.ts","src/ts/components/clickoverlay.ts","src/ts/components/closebutton.ts","src/ts/components/component.ts","src/ts/components/container.ts","src/ts/components/controlbar.ts","src/ts/components/ecomodecontainer.ts","src/ts/components/ecomodetogglebutton.ts","src/ts/components/errormessageoverlay.ts","src/ts/components/fullscreentogglebutton.ts","src/ts/components/hugeplaybacktogglebutton.ts","src/ts/components/hugereplaybutton.ts","src/ts/components/itemselectionlist.ts","src/ts/components/label.ts","src/ts/components/listbox.ts","src/ts/components/listselector.ts","src/ts/components/metadatalabel.ts","src/ts/components/pictureinpicturetogglebutton.ts","src/ts/components/playbackspeedselectbox.ts","src/ts/components/playbacktimelabel.ts","src/ts/components/playbacktogglebutton.ts","src/ts/components/playbacktoggleoverlay.ts","src/ts/components/quickseekbutton.ts","src/ts/components/recommendationoverlay.ts","src/ts/components/replaybutton.ts","src/ts/components/seekbar.ts","src/ts/components/seekbarbufferlevel.ts","src/ts/components/seekbarcontroller.ts","src/ts/components/seekbarlabel.ts","src/ts/components/selectbox.ts","src/ts/components/settingspanel.ts","src/ts/components/settingspanelitem.ts","src/ts/components/settingspanelpage.ts","src/ts/components/settingspanelpagebackbutton.ts","src/ts/components/settingspanelpagenavigatorbutton.ts","src/ts/components/settingspanelpageopenbutton.ts","src/ts/components/settingstogglebutton.ts","src/ts/components/spacer.ts","src/ts/components/subtitlelistbox.ts","src/ts/components/subtitleoverlay.ts","src/ts/components/subtitleselectbox.ts","src/ts/components/subtitlesettings/backgroundcolorselectbox.ts","src/ts/components/subtitlesettings/backgroundopacityselectbox.ts","src/ts/components/subtitlesettings/characteredgeselectbox.ts","src/ts/components/subtitlesettings/fontcolorselectbox.ts","src/ts/components/subtitlesettings/fontfamilyselectbox.ts","src/ts/components/subtitlesettings/fontopacityselectbox.ts","src/ts/components/subtitlesettings/fontsizeselectbox.ts","src/ts/components/subtitlesettings/subtitlesettingselectbox.ts","src/ts/components/subtitlesettings/subtitlesettingslabel.ts","src/ts/components/subtitlesettings/subtitlesettingsmanager.ts","src/ts/components/subtitlesettings/subtitlesettingspanelpage.ts","src/ts/components/subtitlesettings/subtitlesettingsresetbutton.ts","src/ts/components/subtitlesettings/windowcolorselectbox.ts","src/ts/components/subtitlesettings/windowopacityselectbox.ts","src/ts/components/timelinemarkershandler.ts","src/ts/components/titlebar.ts","src/ts/components/togglebutton.ts","src/ts/components/tvnoisecanvas.ts","src/ts/components/uicontainer.ts","src/ts/components/videoqualityselectbox.ts","src/ts/components/volumecontrolbutton.ts","src/ts/components/volumeslider.ts","src/ts/components/volumetogglebutton.ts","src/ts/components/vrtogglebutton.ts","src/ts/components/watermark.ts","src/ts/demofactory.ts","src/ts/dom.ts","src/ts/errorutils.ts","src/ts/eventdispatcher.ts","src/ts/focusvisibilitytracker.ts","src/ts/groupplaybackapi.ts","src/ts/guid.ts","src/ts/imageloader.ts","src/ts/localization/i18n.ts","src/ts/localization/languages/de.json","src/ts/localization/languages/en.json","src/ts/localization/languages/es.json","src/ts/localization/languages/nl.json","src/ts/main.ts","src/ts/mobilev3playerapi.ts","src/ts/playerutils.ts","src/ts/spatialnavigation/ListNavigationGroup.ts","src/ts/spatialnavigation/gethtmlelementsfromcomponents.ts","src/ts/spatialnavigation/keymap.ts","src/ts/spatialnavigation/navigationalgorithm.ts","src/ts/spatialnavigation/navigationgroup.ts","src/ts/spatialnavigation/nodeeventsubscriber.ts","src/ts/spatialnavigation/rootnavigationgroup.ts","src/ts/spatialnavigation/seekbarhandler.ts","src/ts/spatialnavigation/spatialnavigation.ts","src/ts/spatialnavigation/typeguards.ts","src/ts/spatialnavigation/types.ts","src/ts/storageutils.ts","src/ts/stringutils.ts","src/ts/subtitleutils.ts","src/ts/timeout.ts","src/ts/uifactory.ts","src/ts/uimanager.ts","src/ts/uiutils.ts","src/ts/volumecontroller.ts","src/ts/vttutils.ts"],"names":["f","g","exports","module","define","amd","window","global","self","this","bitmovin","playerui","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","ArrayUtils","remove","array","item","index","indexOf","splice","i18n_1","AudioTrackSwitchHandler","player","element","uimanager","_this","addAudioTrack","event","audioTrack","track","listElement","hasItem","id","addItem","i18n","getLocalizer","label","removeAudioTrack","removeItem","selectCurrentAudioTrack","currentAudioTrack","getAudio","selectItem","refreshAudioTracks","audioTracks","getAvailableAudio","synchronizeItems","map","key","bindSelectionEvent","bindPlayerEvents","prototype","onItemSelected","subscribe","_","value","setAudio","on","PlayerEvent","AudioChanged","SourceUnloaded","PeriodSwitched","AudioAdded","AudioRemoved","getConfig","events","onUpdated","BrowserUtils","Object","defineProperty","windowExists","navigator","userAgent","test","isHisense","platform","includes","maxTouchPoints","msMaxTouchPoints","_super","clickoverlay_1","AdClickOverlay","ClickOverlay","__extends","configure","adFinishedHandler","setUrl","clickThroughCallback","AdStarted","ad","clickThroughUrl","clickThroughUrlOpened","AdFinished","AdSkipped","AdError","onClick","pause","config","mergeConfig","acceptsTouchWithUiHidden","label_1","stringutils_1","AdMessageLabel","Label","adEndHandler","off","TimeChanged","updateMessageHandler","text","setText","StringUtils","replaceAdMessagePlaceholders","performLocalization","uiConfig","message","cssClass","button_1","AdSkipButton","Button","updateSkipMessageHandler","untilSkippableMessage","skippableMessage","skipOffset","show","getCurrentTime","disable","enable","skippableAfter","hide","ads","skip","togglebutton_1","AirPlayToggleButton","ToggleButton","airPlayAvailableHandler","isAirplayAvailable","showAirplayTargetPicker","console","log","airPlayChangedHandler","isAirplayActive","AirplayAvailable","AirplayChanged","selectbox_1","AudioQualitySelectBox","SelectBox","updateAudioQualities","audioQualities","getAvailableAudioQualities","clearItems","_i","audioQualities_1","audioQuality","selectCurrentAudioQuality","getAudioQuality","sender","setAudioQuality","AudioQualityChanged","AudioQualityAdded","AudioQualityRemoved","cssClasses","listbox_1","audiotrackutils_1","AudioTrackListBox","ListBox","AudioTrackSelectBox","container_1","component_1","timeout_1","BufferingOverlay","Container","showOverlay","overlayShowTimeout","start","hideOverlay","clear","Timeout","showDelayMs","StallStarted","StallEnded","Play","Playing","Paused","Seek","Seeked","TimeShift","TimeShifted","isStalled","indicators","Component","tag","role","hidden","components","dom_1","eventdispatcher_1","toDomElement","buttonElementAttributes","aria-label","ariaLabel","class","getCssClasses","type","aria-pressed","tabindex","tabIndex","toString","buttonElement","DOM","append","prefixCss","html","onClickEvent","getDomElement","find","buttonEvents","dispatch","getEvent","EventDispatcher","CastStatusOverlay","CastWaitingForDevice","castDeviceName","castPayload","deviceName","statusLabel","CastStarted","CastStopped","CastToggleButton","castAvailableHander","isCastAvailable","isCasting","castStop","castVideo","CastAvailable","uicontainer_1","CastUIContainer","UIContainer","isUiShown","showUi","castUiHideTimeout","hideDelay","onControlsHide","onControlsShow","showUiPermanently","showUiWithTimeout","isPlaying","release","initialize","url","data","open","getUrl","undefined","CloseButton","target","ViewMode","guid_1","disabled","isHidden","isDisabled","onShow","onComponentShow","onHide","onComponentHide","onViewModeChanged","args","onComponentViewModeChanged","onHoverChangedEvent","hasDomElement","Boolean","setAriaLabel","setAriaAttr","name","attr","concat","defaults","base","assign","css","join","trim","cssClassOrId","cssPrefix","addClass","CLASS_HIDDEN","onHideEvent","removeClass","onShowEvent","isShown","toggleHidden","CLASS_DISABLED","onDisabledEvent","onEnabledEvent","isEnabled","isHovered","hovered","componentEvents","onEnabled","onDisabled","onViewModeChangedEvent","mode","viewMode","onHoverChanged","Guid","next","Temporary","arrayutils_1","addComponent","component","push","componentsToAdd","removeComponent","componentsToRemove","getComponents","removeComponents","_a","slice","updateComponents","shift","innerContainerElement","containerElement","innerContainer","initialComponent","suspendHideTimeout","resumeHideTimeout","trackComponentViewMode","Persistent","componentsInPersistentViewMode","Math","max","uiutils_1","spacer_1","browserutils_1","settingspanel_1","ControlBar","hoverStackCount","isSettingsPanelShown","disableAutoHideWhenHovered","isTouchSupported","UIUtils","traverseTree","Spacer","isMobile","SettingsPanel","onPreviewControlsHide","cancel","ecomodetogglebutton_1","settingspanelitem_1","EcoModeContainer","setOnToggleCallback","callback","onToggleCallback","SegmentPlayback","segment","bitrate","frameRate","maxHeight","maxBitrate","maxWidth","currentEnergyKwh","maxEnergyKwh","mimeType","height","mediaInfo","width","_b","getMaxQualityAvailable","getAvailableVideoQualities","calculateEnergyConsumption","duration","ecoModeSavedEmissionsItem","updateSavedEmissions","emissionsSavedLabel","currentEnergyConsuption","maxEnergyConsuption","currentEnergyEmission","maxEnergyEmisson","savedEmissons","toFixed","fps","availableVideoQualities","sortedQualities","sort","b","ecoModeToggleButton","EcoModeToggleButton","labelEcoMode","for","ecoModeToggleButtonItem","SettingsPanelItem","onToggleOn","onToggleOff","areAdaptationApisAvailable","toggle","enableEcoMode","setVideoQuality","disableEcoMode","VideoQualityChanged","quality","targetQuality","isGetConfigAvailable","adaptation","isSetConfigAvailable","setConfig","adaptationConfig","codec","resolution","maxSelectableVideoHeight","limitToPlayerSize","defaultConfig","onClass","offClass","tvnoisecanvas_1","errorutils_1","mobilev3playerapi_1","ErrorMessageOverlay","errorEventHandler","handleErrorMessage","customizedMessage","errorMessages","customMessage","messages","display","isMobileV3PlayerAPI","MobileV3PlayerEvent","PlayerError","ErrorUtils","defaultMobileV3ErrorMessageTranslator","SourceError","defaultWebErrorMessageTranslator","SourceLoaded","tvNoiseBackground","stop","errorMessage","errorLabel","TvNoiseCanvas","FullscreenToggleButton","fullscreenStateHandler","getViewMode","Fullscreen","fullscreenAvailabilityChangedHandler","isFullScreenAvailable","isViewModeAvailable","ViewModeChanged","ViewModeAvailabilityChanged","targetViewMode","Inline","setViewMode","playbacktogglebutton_1","HugePlaybackToggleButton","PlaybackToggleButton","togglePlayback","isPlayInitiated","play","toggleFullscreen","suppressPlayButtonTransitionAnimation","setTransitionAnimationsEnabled","onToggle","subscribeOnce","firstPlay","enterFullscreenOnInitialPlayback","clickTime","doubleClickTime","isAutoplayEnabled","now","Date","setTimeout","Warning","WarningCode","PLAYBACK_COULD_NOT_BE_STARTED","playback","autoplay","isAutoplayUpcoming","getSource","enabled","noTransitionAnimationsClass","hasClass","HugeReplayButton","listselector_1","ItemSelectionList","ListSelector","isActive","items","updateDomItems","selectedValue","selectedListItem","empty","listItem","CLASS_SELECTED","deselectItem","this_1","String","onItemSelectedEvent","onItemAddedEvent","selectedItem","onItemRemovedEvent","tagName","labelElement","localizedText","onTextChangedEvent","getText","clearText","isEmpty","labelEvents","onTextChanged","onItemAdded","addListBoxDomItem","onItemRemoved","removeListBoxDomItem","refreshSelectedItem","listBoxElement","createListBoxDomItems","buildListBoxItemButton","ListBoxItemButton","getComponentForKey","c","listBoxItemButton_1","newItem","getItemForKey","handleSelectionChange","getItemIndex","getItems","sortedInsert","__assign","filter","translator","findIndex","entry","getSelectedItem","newItems","forEach","items_1","itemCount","keys","listSelectorEvents","MetadataLabelContent","MetadataLabel","init","content","Title","uiconfig","metadata","title","Description","description","toLowerCase","PictureInPictureToggleButton","pictureInPictureStateHandler","PictureInPicture","pictureInPictureAvailabilityChangedHandler","isPictureInPictureAvailable","PlaybackSpeedSelectBox","setDefaultValue","playbackSpeed","getPlaybackSpeed","setSpeed","addDefaultItems","setPlaybackSpeed","parseFloat","PlaybackSpeedChanged","speed","customItems","defaultPlaybackSpeeds","PlaybackTimeLabelMode","playerutils_1","PlaybackTimeLabel","minWidth","min-width","updateTimeFormatBasedOnDuration","live","liveCssClass","liveEdgeCssClass","liveClickHandler","timeShift","updateLiveTimeshiftState","isTimeshifted","isTimeshiftAvailable","getTimeShift","getMaxTimeShift","isPaused","liveStreamDetector","PlayerUtils","LiveStreamDetector","playbackTimeHandler","onLiveChanged","isLive","hideInLivePlayback","unsubscribe","detect","getDuration","Infinity","setTime","getCurrentTimeRelativeToSeekableRange","timeFormat","abs","FORMAT_HHMMSS","FORMAT_MMSS","Ready","playbackSeconds","durationSeconds","currentTime","secondsToTime","totalTime","timeLabelMode","CurrentTime","TotalTime","CurrentAndTotalTime","RemainingTime","setTimeFormat","handleClickEvent","playbackStateHandler","isSeeking","updateLiveState","isTimeShiftAvailable","CLASS_STOPTOGGLE","timeShiftDetector","PlaybackFinished","TimeShiftAvailabilityDetector","onTimeShiftAvailabilityChanged","onSeek","onSeeked","onAriaLabel","offAriaLabel","hugeplaybacktogglebutton_1","PlaybackToggleOverlay","playbackToggleButton","QuickSeekButton","switchVisibility","hasTimeShift","timeShiftAvailable","newSeekTime","clampedValue","seekSeconds","currentSeekTarget","clampValueToRange","seek","onSeekedOrTimeShifted","onTimeShift","seekDirection","seekTarget","position","hugereplaybutton_1","RecommendationOverlay","setupRecommendations","clearRecommendations","recommendations","recommendations_1","RecommendationItem","itemConfig","replayButton","itemElement","href","background-image","thumbnail","bgElement","titleElement","timeElement","ReplayButton","hasEnded","groupplaybackapi_1","seekbarcontroller_1","timelinemarkershandler_1","seekbarbufferlevel_1","SeekBar","hasLabel","getLabel","setAriaSliderMinMax","min","setAriaSliderValues","ariaValueText","seekBarType","SeekBarType","Live","timeshiftValue","ceil","Vod","secondsToText","floor","getPlaybackPositionPercentage","getRelativeCurrentTime","updateBufferLevel","playbackPositionPercentage","bufferLoadedPercentageLevel","getMinBufferLevel","setBufferPosition","configureSeek","scrubbing","isPlayerSeeking","suspension","playbackPositionHandler","isGroupPlaybackAPIAvailable","uiManager","setPosition","seekBarBackdrop","SeekBarController","keyStepIncrements","volumeController","setSeekBarControls","smoothPlaybackPositionUpdater","forceUpdate","isUserSeeking","SegmentRequestFinished","setPlaybackPosition","isInInitialStartupState","smoothPlaybackPositionUpdateIntervalMs","SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED","isNeitherPausedNorPlaying","configureLivePausedTimeshiftUpdater","onPlayerSeek","setSeeking","onPlayerSeeked","groupPlayback","hasJoined","beginSuspension","GroupPlaybackSuspensionReason","UserIsScrubbing","onSeekPreview","enableSeekPreview","subscribeRateLimited","seekWhileScrubbing","percentage","proposedPlaybackTime","getTargetSeekPosition","endSuspension","refreshPlaybackPosition","PlayerResized","uiBoundingRect","getUI","get","getBoundingClientRect","onConfigured","seekbarSnappingRange","snappingRange","seekbarSnappingEnabled","snappingEnabled","setSeekPosition","configureSmoothPlaybackPositionUpdater","initializeTimelineMarkers","Volume","timelineMarkerConfig","timelineMarkersHandler","TimelineMarkersHandler","seekBar","seekBarMarkersContainer","pausedTimeshiftUpdater","startSmoothPlaybackPositionUpdater","currentTimeSeekBar","stopSmoothPlaybackPositionUpdater","currentTimePlayer","updateIntervalMs","error","PlayerAPINotAvailableError","currentTimeDelta","seekBarContainer","vertical","seekBarBufferLevel","seekBarPlaybackPosition","seekBarBufferPosition","seekBarPlaybackPositionMarker","seekBarSeekPosition","seekBarChapterMarkersContainer","seeking","mouseTouchMoveHandler","preventDefault","vr","stopPropagation","offset","getOffset","targetPercentage","seekPositionPx","onSeekPreviewEvent","mouseTouchUpHandler","document","matchingMarker","getMarkerAtPosition","onSeekedEvent","isTouchEvent","onSeekEvent","seekPositionPercentage","getHorizontalOffset","eventPageX","elementOffsetPx","left","widthPx","sanitizeOffset","getVerticalOffset","eventPageY","top","changedTouches","touches","pageY","pageX","MouseEvent","warn","percent","px","style","transform","-ms-transform","-webkit-transform","scale","CLASS_SEEKING","seekBarEvents","targetOffsetPx","snappedMarker","updateLabelPosition","marker","TouchEvent","seekableRangeStart","maxTimeShift","getSeekableRangeStart","targetPlaybackPosition","pixelPosition","setPositionInBounds","leftRight","upDown","playerDuration","videoBufferLength","getVideoBufferLength","audioBufferLength","getAudioBufferLength","bufferLength","Number","MAX_VALUE","coerceValueIntoRange","range","cb","arrowKeyControls","currentValue","valueUpdate","controlValue","right","up","down","home","end","seekBarControls","volumeTransition","startTransition","getVolume","finish","bind","domElement","controls","keyCode","KeyCode","LeftArrow","RightArrow","UpArrow","DownArrow","Home","End","Space","imageloader_1","SeekBarLabel","setTitleText","setThumbnail","handleSeekPreview","bounds","labelBounding","container","parentElement","preventOverflowOffset","caret","timeLabel","seconds","titleLabel","thumbnailElement","thumbnailImageLoader","load","x","thumbnailCssSprite","thumbnailCssSingleImage","sizeX","sizeY","offsetX","offsetY","y","aspectRatio","padding-bottom","background-size","background-position","appliedMarkerCssClasses","targetTimeShift","currentTimeShift","timeShiftPreview","wallClockTime","getThumbnail","time","ImageLoader","DocumentDropdownClosedEvents","SelectDropdownClosedEvents","DropdownOpenedEvents","selectElement","closeDropdown","addDropdownOpenedListeners","onChange","uiContainer","onPlayerStateChange","getSelectElement","optionElement","addDropdownCloseListeners","removeDropdownCloseListeners","clearTimeout","dropdownCloseListenerTimeoutId","addEventListener","onDropdownClosed","removeEventListener","removeListenerFunctions","removeDropdownOpenedListeners","event_1","listener","onDropdownOpened","DropdownOpenedEvents_1","removeListenerFunctions_1","val","select","blur","state","PlayerState","Idle","Finished","NavigationDirection","settingspanelpage_1","hideHoveredSelectBoxes","hideTimeout","reset","activePage","onInactiveEvent","resetNavigation","onActiveEvent","getRootPage","onSettingsStateChanged","onSettingsStateChangedEvent","updateActivePageClass","getActivePage","setActivePageIndex","setActivePage","getPages","targetPage","navigateToPage","Forwards","pageTransitionAnimation","popToRootSettingsPanelPage","popSettingsPanelPage","navigationStack","Backwards","rootPageHasActiveSettings","hasActiveSettings","SettingsPanelPage","settingsPanelEvents","suspend","resume","page","CLASS_ACTIVE_PAGE","resetNavigationOnShow","sourcePage","rootPage","animateNavigation","direction","skipAnimation","pop","settingsPanelDomElement","settingsPanelWidth","settingsPanelHeight","clone","targetSettingsPanelHeight","settingsPanelHTMLElement","scrollWidth","scrollHeight","targetPageHtmlElement","cloneNode","parentNode","appendChild","targetSettingsPanelWidth","removeChild","forceBrowserReflow","offsetLeft","getComputedItems","selectBox","allItems","apply","videoqualityselectbox_1","audioqualityselectbox_1","playbackspeedselectbox_1","handleConfigItemChanged","setting","minItemsToDisplay","VideoQualitySelectBox","hasAutoItem","playbackSpeedSelectionEnabled","onActiveChangedEvent","settingsPanelItemEvents","onActiveChanged","settingsStateChangedHandler","lastShownItem","CLASS_LAST","settingsPanelPageEvents","activeItems","onActive","isIOS","isMacIntel","focusToFirstInput","onInactive","settingspanelpagenavigatorbutton_1","SettingsPanelPageBackButton","SettingsPanelPageNavigatorButton","popPage","pushTargetPage","SettingsPanelPageOpenButton","SettingsToggleButton","settingsPanel","visibleSettingsPanels","autoHideWhenNoActiveSettings","settingsPanelItemsChangedHandler","subtitleutils_1","SubtitleListBox","SubtitleSwitchHandler","controlbar_1","vttutils_1","SubtitleOverlay","subtitleClearHandler","subtitleContainerManager","subtitleManager","clearInactiveCues","toRemove","removeLabel","ActiveSubtitleManager","SubtitleRegionContainerManager","CueEnter","generateLabel","cueEnter","preprocessLabelEventCallback","previewSubtitleActive","previewSubtitle","addLabel","size","forceSubtitlesIntoViewContainer","handleSubtitleCropping","CueUpdate","labelToReplace","cueUpdate","replaceLabel","CueExit","labelToRemove","cueExit","hasCues","SubtitleDisabled","CLASS_CONTROLBAR_VISIBLE","configureCea608Captions","detectCroppedSubtitleLabel","parent","childRect","parentRect","bottom","labelDomElement","cropDetection","removeCss","row","column","SubtitleLabel","generateImageTagText","image","vtt","region","regionStyle","updateCEA608FontSize","dummyLabel","font-size","line-height","visibility","dummyLabelCharWidth","dummyLabelCharHeight","fontSizeRatio","subtitleOverlayWidth","subtitleOverlayHeight","fontLetterSpacing","CEA608_NUM_COLUMNS","CEA608_NUM_ROWS","fontSize","letter-spacing","CLASS_CEA_608","fontSizeCalculationRequired","CEA608_COLUMN_OFFSET","CEA608_ROW_OFFSET","SubtitleEnabled","enablePreviewSubtitleLabel","removePreviewSubtitleLabel","calculateId","addCueToMap","popCueFromMap","activeSubtitleCueMap","activeSubtitleCueCount","activeSubtitleCues","activeSubtitleCue","removedCues","cue","imageData","imgTag","src","outerHTML","getCues","cueCount","getRegion","regionContainerId","regionName","overlaySize","subtitleRegionContainers","regionContainerId_1","regionContainer","SubtitleRegionContainer","subtitleOverlay","previousLabel","newLabel","labelToAdd","labelCount","VttUtils","setVttRegionStyles","setVttCueBoxStyles","SubtitleSelectBox","subtitlesettingselectbox_1","BackgroundColorSelectBox","SubtitleSettingSelectBox","setColorAndOpacity","settingsManager","backgroundColor","isSet","backgroundOpacity","toggleOverlayClass","onChanged","property","BackgroundOpacitySelectBox","CharacterEdgeSelectBox","characterEdge","FontColorSelectBox","fontColor","fontOpacity","FontFamilySelectBox","fontFamily","FontOpacitySelectBox","FontSizeSelectBox","currentCssClass","overlay","getSubtitleSettingsManager","SubtitleSettingsLabel","opener","storageutils_1","SubtitleSettingsManager","_properties","SubtitleSettingsProperty","windowColor","windowOpacity","userSettings","localStorageKey","DummyComponent","instance","propertyName","save","StorageUtils","setObject","getObject","_instance","_value","onChangedEvent","_onChanged","_manager","manager","fontsizeselectbox_1","fontfamilyselectbox_1","fontcolorselectbox_1","fontopacityselectbox_1","characteredgeselectbox_1","backgroundcolorselectbox_1","backgroundopacityselectbox_1","windowcolorselectbox_1","windowopacityselectbox_1","subtitlesettingsresetbutton_1","settingspanelpagebackbutton_1","SubtitleSettingsPanelPage","WindowColorSelectBox","WindowOpacitySelectBox","SubtitleSettingsResetButton","getSeekBarWidth","markersContainer","timelineMarkers","configureMarkers","clearMarkers","AdBreakStarted","AdBreakFinished","updateMarkers","updateMarkersDOM","onRelease","intervalMarkerMatch","positionMarkerMatch","removeMarkerFromConfig","markers","_marker","filterRemovedMarkers","seekbarMarker","removeMarkerFromDOM","shouldProcessMarkers","validToProcess","hasMarkers","markerPosition","markerDuration","getSeekableRangeRespectingLive","isNaN","updateMarkerDOM","newMarker","createMarkerDOM","getMarkerCssProperties","seekBarWidthPx","positionInPx","cssProperties","markerWidthPx","round","imageElement_1","markerClasses","markerElement","data-marker-time","data-marker-title","imageUrl","handler","Destroy","metadatalabel_1","TitleBar","shouldBeShown","hasMetadataText","checkMetadataTextAndUpdateVisibility","keepHiddenWithoutMetadata","isOff","onState","onToggleEvent","onToggleOnEvent","isOn","onToggleOffEvent","toggleButtonEvents","canvas","canvasElement","canvasContext","getContext","noiseAnimationWindowPos","canvasHeight","lastFrameUpdate","canvasWidth","renderFrame","useAnimationFrame","cancelAnimationFrame","frameUpdateHandlerId","frameInterval","getTime","currentPixelOffset","noiseImage","createImageData","random","interferenceHeight","putImageData","scheduleNextRender","requestAnimationFrame","userInteractionEventSource","configureUIShowHide","configurePlayerStates","isFirstTouch","playerState","hidingPrevented","hidePlayerStateExceptions","uiHideTimeout","hideUi","previewHideEventArgs","userInteractionEvents","shouldPreventDefault","findButtonComponent","buttonComponent","hideImmediatelyOnMouseLeave","playerStateChange","enumName","stateClassNames","STATE_PREFIX","updateState","removeStates","updateLayoutSizeClasses","Prepared","getState","FULLSCREEN","BUFFERING","REMOTE_CONTROL","CONTROLS_HIDDEN","CONTROLS_SHOWN","substring","getContainer","createElement","flex","updateVideoQualities","videoQualities","hasAuto","getStreamType","videoQualities_1","videoQuality","selectCurrentVideoQuality","getVideoQuality","VideoQualityAdded","VideoQualityRemoved","volumeslider_1","volumetogglebutton_1","VolumeControlButton","volumeToggleButton","getVolumeToggleButton","volumeSlider","getVolumeSlider","volumeSliderHovered","volumeSliderHideTimeout","VolumeToggleButton","VolumeSlider","seekbar_1","setVolumeAriaSliderValues","hideIfVolumeControlProhibited","detectVolumeControlAvailability","muted","volume","updateVolumeWhileScrubbing","dummyVideoElement","update","volumeLevelTens","toggleMuted","VRToggleButton","vrStateHandler","ev","VR_RENDERING_ERROR","isVRConfigured","isVRStereoAvailable","getStereo","vrButtonVisibilityHandler","source","VRStereoChanged","setStereo","Watermark","vrtogglebutton_1","settingstogglebutton_1","playbacktimelabel_1","airplaytogglebutton_1","errormessageoverlay_1","casttogglebutton_1","fullscreentogglebutton_1","recommendationoverlay_1","caststatusoverlay_1","watermark_1","subtitleoverlay_1","seekbarlabel_1","playbacktoggleoverlay_1","pictureinpicturetogglebutton_1","uimanager_1","titlebar_1","bufferingoverlay_1","subtitlelistbox_1","audiotracklistbox_1","uifactory_1","main_1","DemoFactory","buildDemoWithSeparateAudioSubtitlesButtons","subtitleListBox","audioTrackListBox","UIManager","ui","UIFactory","modernSmallScreenAdsUI","condition","context","documentWidth","isAd","adRequiresUi","modernAdsUI","modernSmallScreenUI","subtitleSettingsPanel","audioTrackSettingsPanel","controlBar","something","attributes","Array","HTMLElement","elements","Document","attributeName","attributeValue","setAttribute","findChildElements","findChildElementsOfElement","selector","childElements","querySelectorAll","allChildElements","inputElements","focus","scrollTo","arguments","setHtml","getHtml","innerHTML","HTMLSelectElement","HTMLInputElement","attribute","setAttr","getAttr","removeAttr","removeAttribute","getAttribute","dataAttribute","setData","getData","childElement","elementRect","htmlRect","body","offsetWidth","offsetHeight","eventName","eventHandler","options","split","className","classNames","classList","add","replace","RegExp","contains","propertyNameOrCollection","setCss","getCss","setCssCollection","elementIndex","removeProperty","getComputedStyle","ruleValueCollection","defaultErrorMessages","1000","1001","1100","1101","1102","1103","1104","1105","1106","1107","1108","1109","1110","1111","1112","1113","1200","1201","1202","1203","1204","1205","1206","1207","1208","1209","1210","1211","1300","1301","1302","1303","1304","1400","1401","1402","1403","1404","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2100","2101","3000","3001","3002","3003","3004","3100","listeners","EventListenerWrapper","rateMs","RateLimitedEventListenerWrapper","subscribedListener","unsubscribeAll","listenersToRemove","listeners_1","fire","isOnce","listenersToRemove_1","eventListener","once","shouldFireEvent","rateLimitTimout","fireSuper","rateLimitingEventListener","startRateLimiting","lastSeenEvent","FocusVisibleCssClassName","FocusVisibilityTracker","bitmovinUiPrefix","lastInteractionWasKeyboard","onKeyDown","metaKey","altKey","ctrlKey","onMouseOrPointerOrTouch","onFocus","isHtmlElement","onBlur","eventHandlerMap","mousedown","pointerdown","touchstart","keydown","registerEventListeners","DOMTokenList","unregisterEventListeners","event_2","guid","loadedCallback","state_1","loaded","callLoadedCallback","de_json_1","__importDefault","en_json_1","es_json_1","nl_json_1","defaultLocalizationConfig","defaultVocabularies","en","default","de","es","nl","language","vocabularies","I18n","mergedConfig","detectBrowserLanguage","mergeVocabulariesWithDefaultVocabularies","initializeLanguage","initializeVocabulary","containsLanguage","hasOwnProperty","rawVocabularies","reduce","mergedVocabularies","vocabulary","browserLanguageDetectionEnabled","userLanguage","shortenedUserLanguage","vocab","lang","replaceVariableWithPlaceholderIfExists","matches","match","m","str","vocabularyString","settings.video.quality","settings.audio.quality","settings.audio.track","playPause","close","settings.audio.mute","settings.audio.volume","pictureInPicture","appleAirplay","googleCast","settings","fullscreen","settings.subtitles","settings.subtitles.font.size","settings.subtitles.font.family","settings.subtitles.font.color","settings.subtitles.font.opacity","settings.subtitles.characterEdge","settings.subtitles.background.color","settings.subtitles.background.opacity","settings.subtitles.window.color","settings.subtitles.window.opacity","settings.time.hours","settings.time.minutes","settings.time.seconds","back","replay","ads.remainingTime","colors.white","colors.black","colors.red","colors.green","colors.blue","colors.yellow","subtitle.example","subtitle.select","playingOn","connectingTo","watermarkLink","seekBar.value","seekBar.timeshift","seekBar.durationText","quickseek.forward","quickseek.rewind","ecoMode","ecoMode.title","colors.cyan","colors.magenta","settings.subtitles.characterEdge.raised","settings.subtitles.characterEdge.depressed","settings.subtitles.characterEdge.uniform","settings.subtitles.characterEdge.dropshadowed","settings.subtitles.font.family.monospacedserif","settings.subtitles.font.family.proportionalserif","settings.subtitles.font.family.monospacedsansserif","settings.subtitles.font.family.proportionalsansserif","settings.subtitles.font.family.casual","settings.subtitles.font.family.cursive","settings.subtitles.font.family.smallcapital","auto","normal","version","__exportStar","demofactory_1","enumerable","spatialnavigation_1","navigationgroup_1","SpatialNavigation","rootnavigationgroup_1","NavigationGroup","ListNavigationGroup_1","RootNavigationGroup","ListNavigationGroup","ListOrientation","itemselectionlist_1","audiotrackselectbox_1","subtitleselectbox_1","volumecontrolbutton_1","adskipbutton_1","admessagelabel_1","adclickoverlay_1","castuicontainer_1","closebutton_1","subtitlesettingslabel_1","settingspanelpageopenbutton_1","subtitlesettingspanelpage_1","replaybutton_1","quickseekbutton_1","TypeError","timeShiftAvailabilityChangedEvent","liveDetector","liveChangedEvent","isAndroid","isChrome","DurationChanged","defaultValue","getSeekableRange","currentTimeshift","maxTimeshift","timeShiftAvailableNow","liveNow","boundary1","boundary2","lowerBoundary","upperBoundary","types_1","handleAction","action","Action","SELECT","BACK","handleNavigation","listNavigationDirections","orientation","__spreadArray","Vertical","Direction","UP","DOWN","Horizontal","LEFT","RIGHT","typeguards_1","getHtmlElementsFromComponents","htmlElements","resolveAllComponents","childComponents","containerOrComponent","isContainer","isComponent","isListBox","children","TizenKeyMap","isApplicable","isTizen","keyCodes","38","40","37","39","13","10009","WebOsKeyMap","isWebOs","461","PlayStationKeyMap","isPlayStation","27","AndroidKeyMap","HisenseKeyMap","8","DefaultKeyMap","getKeyMapForPlatform","applicableKeyMap","keyMap","vector","sqrt","pow","getElementVector","boundingRect","getBoundingRectFromElement","calculateAngle","directionVector","len","elementVector","angleCos","acos","PI","getElementInDirection","activeElement","activeElemVector","elem","dist","angle","angleA","distA","navigationalgorithm_1","gethtmlelementsfromcomponents_1","nodeeventsubscriber_1","removeElementHoverEventListeners","eventSubscriber","NodeEventSubscriber","getActiveElement","focusElement","blurActiveElement","focusFirstElement","defaultNavigationHandler","targetElement","defaultActionHandler","click","handleInput","defaultHandler","userHandler","handleDefault","onNavigation","activeElementBeforeDisable","onAction","isSettingsPanel","trackElementHover","removeEventListenerFunctions","htmlElem","exitListener","enterListener","fn","attachedListeners","Map","getEventListenersOfType","has","set","node","listenersOfType","listenerIndex","otherNode","otherListener","otherOptions","SeekBarHandler","rootNavigationGroup","cursorPosition","isScrubbing","scrubSpeedPercentage","isSeekBarWrapper","stopSeeking","getSeekBar","initializeOrUpdateCursorPosition","dispatchMouseMoveEvent","dispatchMouseClickEvent","from","seekBarWrapper","updateScrubSpeedPercentage","scrubSpeedResetTimeout","getIncrement","increment","resetCursorPosition","updateCursorPosition","initializeCursorPosition","playbackPositionMarker","querySelector","rect","startX","startY","getCursorPositionMouseEventInit","clientX","clientY","dispatchEvent","mouseDownHandler","mouseEventInit","dispatchMouseLeaveEvent","seekbarhandler_1","keymap_1","navigationGroups","group","activeNavigationGroups","updateEnabledNavigationGroup","groupIndex","other","handleKeyEvent","active","getActiveNavigationGroup","isDirection","isAction","seekBarHandler","unsubscribeVisibilityChangesFns","subscribeToNavigationGroupVisibilityChanges","attachKeyEventHandler","enableDefaultNavigationGroup","onShowHandler","onHideHandler","unsubscribeFromNavigationGroupVisibilityChanges","unsub","groupToEnable","idx","obj","values","disableStorageApi","shouldUseLocalStorage","localStorage","getItem","setItem","debug","setStorageApiDisabled","JSON","stringify","json","parse","totalSeconds","format","isNegative","hours","minutes","leftPadWithZeros","num","substr","adMessage","adMessagePlaceholderRegex","formatString","isLinearAdActive","indexOfActiveAd","getActiveAdBreak","getActiveAd","total","isLinear","leadingZeroes","numDecimalPlaces","leadingZeroesMatches","parseInt","decimalPlacesMatches","timeString","currentSubtitle","SUBTITLES_OFF_KEY","subtitles","list","subtitle","SubtitleAdded","addSubtitle","selectCurrentSubtitle","SubtitleRemoved","removeSubtitle","clearSubtitles","refreshSubtitles","offListItem","delay","repeat","timeoutOrIntervalId","suspended","clearInternal","setInterval","clearInterval","ecomodecontainer_1","modernUI","ecoModeContainer","unshift","mainSettingsPanelPage","subtitleSettingsPanelPage","subtitleSelectBox","subtitleSettingsOpenButton","modernCastReceiverUI","modernTvUI","subtitleListPanel","audioTrackListPanel","playbackToggleOverlay","subtitleToggleButton","audioToggleButton","spatialNavigation","buildDefaultUI","buildModernUI","buildDefaultSmallScreenUI","buildModernSmallScreenUI","buildDefaultCastReceiverUI","buildModernCastReceiverUI","buildDefaultTvUI","buildModernTvUI","volumecontroller_1","focusvisibilitytracker_1","subtitlesettingsmanager_1","playerUiOrUiVariants","updateConfig","onUiVariantResolve","onActiveUiChanged","uiVariants","subtitleSettingsManager","managerPlayerWrapper","PlayerWrapper","autoUiVariantResolve","VolumeController","getPlayer","playerSourceConfig","playerSourceUiConfig","updateSource","wrappedPlayer","uiVariantsWithoutCondition","PlaylistTransition","uiContainerElement","uiInstanceManagers","uiVariant","InternalUIInstanceManager","resolveUiVariant","adStartedEvent","requestsUi","currentUi","getWrappedPlayer","fireEventInUI","focusVisibilityTracker","localize","setLocalizationConfig","localizationConfig","getUiVariants","switchToUiVariant","uiVariantIndex","previousUi","nextUi","isConfigured","addUi","defaultContext","isFullscreen","clientWidth","switchingContext","nextUiVariant","matchesCondition","dom","configureControls","releaseUi","releaseControls","clearEventHandlers","uiInstanceManager","getTimelineMarkers","addTimelineMarker","timelineMarker","removeTimelineMarker","UIInstanceManager","playerWrapper","configureControlsTree","configured","configuredComponents","configuredComponents_1","constructor","releaseControlsTree","released","isReleased","childComponent","wrapper","eventHandlers","eventType","objectProtoPropertyNames","getOwnPropertyNames","getPrototypeOf","namesToIgnore","methods","properties","members_1","names","newNames","member","methods_1","method","properties_1","propertyDescriptor","propertyDescriptor_1","getOwnPropertyDescriptor","playerEventData","timestamp","uiSourced","visit","recursiveTreeWalker","setVolume","issuerName","setMuted","mute","unmute","isMuted","recallVolume","storeVolume","storedVolume","VolumeTransition","playerMuted","playerVolume","uiMuted","uiVolume","VolumeChanged","Muted","Unmuted","controller","setCueBoxPositionForVerticalWriting","cueContainerDom","subtitleOverlaySize","writingMode","Right","Top","setVttLine","setVttPositionAlign","positionAlign","DirectionPair","VttVerticalWriting","defaultLineNumber","Bottom","Left","setVttLineAlign","relativeCueBoxPosition","lineAlign","setCssForCenterLineAlign","subtitleOverLaySize","targetLine","relativeLinePosition","overlayReferenceEdge","line","snapToLines","cueContainer","GrowingRight","GrowingLeft","textAlign","align","containerSize","regionContainerDom","regionPositionX","viewportAnchorX","regionAnchorX","regionPositionY","viewportAnchorY","lines","regionAnchorY"],"mappings":"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","file":"bitmovinplayer-ui.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","/**\n * @category Utils\n */\nexport namespace ArrayUtils {\n /**\n * Removes an item from an array.\n * @param array the array that may contain the item to remove\n * @param item the item to remove from the array\n * @returns {any} the removed item or null if it wasn't part of the array\n */\n export function remove<T>(array: T[], item: T): T | null {\n let index = array.indexOf(item);\n\n if (index > -1) {\n return array.splice(index, 1)[0];\n } else {\n return null;\n }\n }\n}\n","import { ListItem, ListSelector, ListSelectorConfig } from './components/listselector';\nimport { UIInstanceManager } from './uimanager';\nimport { AudioTrackEvent, PlayerAPI, AudioTrack } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * Helper class to handle all audio tracks related events\n *\n * This class listens to player events as well as the `ListSelector` event if selection changed\n *\n * @category Utils\n */\nexport class AudioTrackSwitchHandler {\n\n private player: PlayerAPI;\n private listElement: ListSelector<ListSelectorConfig>;\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, element: ListSelector<ListSelectorConfig>, uimanager: UIInstanceManager) {\n this.player = player;\n this.listElement = element;\n this.uimanager = uimanager;\n\n this.bindSelectionEvent();\n this.bindPlayerEvents();\n this.refreshAudioTracks();\n }\n\n private bindSelectionEvent(): void {\n this.listElement.onItemSelected.subscribe((_, value: string) => {\n this.player.setAudio(value);\n });\n }\n\n private bindPlayerEvents(): void {\n // Update selection when selected track has changed\n this.player.on(this.player.exports.PlayerEvent.AudioChanged, this.selectCurrentAudioTrack);\n // Update tracks when source goes away\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, this.refreshAudioTracks);\n // Update tracks when the period within a source changes\n this.player.on(this.player.exports.PlayerEvent.PeriodSwitched, this.refreshAudioTracks);\n // Update tracks when a track is added or removed\n this.player.on(this.player.exports.PlayerEvent.AudioAdded, this.addAudioTrack);\n this.player.on(this.player.exports.PlayerEvent.AudioRemoved, this.removeAudioTrack);\n this.uimanager.getConfig().events.onUpdated.subscribe(this.refreshAudioTracks);\n }\n\n private addAudioTrack = (event: AudioTrackEvent) => {\n const audioTrack = event.track;\n if (!this.listElement.hasItem(audioTrack.id)) {\n this.listElement.addItem(audioTrack.id, i18n.getLocalizer(audioTrack.label), true);\n }\n };\n\n private removeAudioTrack = (event: AudioTrackEvent) => {\n const audioTrack = event.track;\n if (this.listElement.hasItem(audioTrack.id)) {\n this.listElement.removeItem(audioTrack.id);\n }\n };\n\n private selectCurrentAudioTrack = () => {\n let currentAudioTrack = this.player.getAudio();\n\n // HLS streams don't always provide this, so we have to check\n if (currentAudioTrack) {\n this.listElement.selectItem(currentAudioTrack.id);\n }\n };\n\n private refreshAudioTracks = () => {\n const audioTracks = this.player.getAvailableAudio();\n const audioTrackToListItem = (audioTrack: AudioTrack): ListItem => {\n return { key: audioTrack.id, label: audioTrack.label };\n };\n\n this.listElement.synchronizeItems(audioTracks.map(audioTrackToListItem));\n this.selectCurrentAudioTrack();\n };\n}\n","declare global {\n interface Navigator {\n msMaxTouchPoints?: number;\n }\n}\n\n/**\n * @category Utils\n */\nexport class BrowserUtils {\n // isMobile only needs to be evaluated once (it cannot change during a browser session)\n // Mobile detection according to Mozilla recommendation: \"In summary, we recommend looking for the string “Mobi”\n // anywhere in the User Agent to detect a mobile device.\"\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent\n static get isMobile(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Mobi/.test(navigator.userAgent);\n }\n\n static get isChrome(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Chrome/.test(navigator.userAgent);\n }\n\n static get isAndroid(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Android/.test(navigator.userAgent) && !this.isHisense;\n }\n\n static get isIOS(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /iPad|iPhone|iPod/.test(navigator.userAgent);\n }\n\n static get isMacIntel(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && navigator.platform === 'MacIntel';\n }\n\n static get isHisense(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Hisense/.test(navigator.userAgent);\n }\n\n static get isPlayStation(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /PlayStation/i.test(navigator.userAgent);\n }\n\n static get isWebOs(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return (\n navigator &&\n navigator.userAgent &&\n (navigator.userAgent.includes('Web0S') || navigator.userAgent.includes('NetCast'))\n );\n }\n\n static get isTizen(): boolean {\n if (!this.windowExists()) {\n return false;\n }\n return navigator && navigator.userAgent && /Tizen/.test(navigator.userAgent);\n }\n\n // https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/\n static get isTouchSupported() {\n if (!this.windowExists()) {\n return false;\n }\n return 'ontouchstart' in window || navigator && navigator.userAgent && (navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0);\n }\n\n private static windowExists(): boolean {\n return typeof window !== 'undefined';\n }\n}\n","import { ClickOverlay, ClickOverlayConfig } from './clickoverlay';\nimport { UIInstanceManager } from '../uimanager';\nimport { Ad, AdEvent, PlayerAPI } from 'bitmovin-player';\n\n/**\n * A simple click capture overlay for clickThroughUrls of ads.\n *\n * @category Components\n */\nexport class AdClickOverlay extends ClickOverlay {\n constructor(config: ClickOverlayConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n acceptsTouchWithUiHidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let clickThroughCallback: () => void = null;\n\n player.on(player.exports.PlayerEvent.AdStarted, (event: AdEvent) => {\n let ad = event.ad;\n this.setUrl(ad.clickThroughUrl);\n clickThroughCallback = ad.clickThroughUrlOpened;\n });\n\n // Clear click-through URL when ad has finished\n let adFinishedHandler = () => {\n this.setUrl(null);\n };\n\n player.on(player.exports.PlayerEvent.AdFinished, adFinishedHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adFinishedHandler);\n player.on(player.exports.PlayerEvent.AdError, adFinishedHandler);\n\n this.onClick.subscribe(() => {\n // Pause the ad when overlay is clicked\n player.pause('ui-ad-click-overlay');\n\n if (clickThroughCallback) {\n clickThroughCallback();\n }\n });\n }\n}\n","import {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport { AdEvent, LinearAd, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A label that displays a message about a running ad, optionally with a countdown.\n *\n * @category Components\n */\nexport class AdMessageLabel extends Label<LabelConfig> {\n\n constructor(config: LabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-label-ad-message',\n text: i18n.getLocalizer('ads.remainingTime') ,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let text = config.text;\n\n let updateMessageHandler = () => {\n this.setText(StringUtils.replaceAdMessagePlaceholders(i18n.performLocalization(text), null, player));\n };\n\n let adStartHandler = (event: AdEvent) => {\n let uiConfig = (event.ad as LinearAd).uiConfig;\n text = uiConfig && uiConfig.message || config.text;\n\n updateMessageHandler();\n\n player.on(player.exports.PlayerEvent.TimeChanged, updateMessageHandler);\n };\n\n let adEndHandler = () => {\n player.off(player.exports.PlayerEvent.TimeChanged, updateMessageHandler);\n };\n\n player.on(player.exports.PlayerEvent.AdStarted, adStartHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adEndHandler);\n player.on(player.exports.PlayerEvent.AdError, adEndHandler);\n player.on(player.exports.PlayerEvent.AdFinished, adEndHandler);\n }\n}","import { ButtonConfig, Button } from './button';\nimport { UIInstanceManager } from '../uimanager';\nimport { StringUtils } from '../stringutils';\nimport { AdEvent, LinearAd, PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for the {@link AdSkipButton}.\n *\n * @category Configs\n */\nexport interface AdSkipButtonConfig extends ButtonConfig {\n /**\n * Message which gets displayed during the countdown is active.\n * Supported placeholders: look at {@link StringUtils.replaceAdMessagePlaceholders}\n */\n untilSkippableMessage?: string;\n /**\n * Message displayed when the ad is skippable.\n * Supported placeholders: look at {@link StringUtils.replaceAdMessagePlaceholders}\n */\n skippableMessage?: string;\n}\n\n/**\n * A button that is displayed during ads and can be used to skip the ad.\n *\n * @category Buttons\n */\nexport class AdSkipButton extends Button<AdSkipButtonConfig> {\n\n constructor(config: AdSkipButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <AdSkipButtonConfig>{\n cssClass: 'ui-button-ad-skip',\n untilSkippableMessage: 'Skip ad in {remainingTime}',\n skippableMessage: 'Skip ad',\n acceptsTouchWithUiHidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let untilSkippableMessage = config.untilSkippableMessage;\n let skippableMessage = config.skippableMessage;\n let skipOffset = -1;\n\n let updateSkipMessageHandler = () => {\n this.show();\n\n // Update the skip message on the button\n if (player.getCurrentTime() < skipOffset) {\n this.setText(StringUtils.replaceAdMessagePlaceholders(untilSkippableMessage, skipOffset, player));\n this.disable();\n } else {\n this.setText(skippableMessage);\n this.enable();\n }\n };\n\n let adStartHandler = (event: AdEvent) => {\n let ad = event.ad as LinearAd;\n skipOffset = ad.skippableAfter;\n untilSkippableMessage = ad.uiConfig && ad.uiConfig.untilSkippableMessage || config.untilSkippableMessage;\n skippableMessage = ad.uiConfig && ad.uiConfig.skippableMessage || config.skippableMessage;\n\n // Display this button only if ad is skippable.\n // Non-skippable ads will return -1 for skippableAfter for player version < v8.3.0.\n if (typeof skipOffset === 'number' && skipOffset >= 0) {\n updateSkipMessageHandler();\n player.on(player.exports.PlayerEvent.TimeChanged, updateSkipMessageHandler);\n } else {\n this.hide();\n }\n };\n\n let adEndHandler = () => {\n player.off(player.exports.PlayerEvent.TimeChanged, updateSkipMessageHandler);\n };\n\n player.on(player.exports.PlayerEvent.AdStarted, adStartHandler);\n player.on(player.exports.PlayerEvent.AdSkipped, adEndHandler);\n player.on(player.exports.PlayerEvent.AdError, adEndHandler);\n player.on(player.exports.PlayerEvent.AdFinished, adEndHandler);\n\n this.onClick.subscribe(() => {\n // Try to skip the ad (this only works if it is skippable so we don't need to take extra care of that here)\n player.ads.skip();\n });\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles Apple AirPlay.\n *\n * @category Buttons\n */\nexport class AirPlayToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-airplaytogglebutton',\n text: i18n.getLocalizer('appleAirplay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n if (!player.isAirplayAvailable) {\n // If the player does not support Airplay (player 7.0), we just hide this component and skip configuration\n this.hide();\n return;\n }\n\n this.onClick.subscribe(() => {\n if (player.isAirplayAvailable()) {\n player.showAirplayTargetPicker();\n } else {\n if (console) {\n console.log('AirPlay unavailable');\n }\n }\n });\n\n const airPlayAvailableHandler = () => {\n if (player.isAirplayAvailable()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n const airPlayChangedHandler = () => {\n if (player.isAirplayActive()) {\n this.on();\n } else {\n this.off();\n }\n };\n\n player.on(player.exports.PlayerEvent.AirplayAvailable, airPlayAvailableHandler);\n player.on(player.exports.PlayerEvent.AirplayChanged, airPlayChangedHandler);\n\n // Startup init\n airPlayAvailableHandler(); // Hide button if AirPlay is not available\n airPlayChangedHandler();\n }\n}","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between 'auto' and the available audio qualities.\n *\n * @category Components\n */\nexport class AudioQualitySelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-audioqualityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let selectCurrentAudioQuality = () => {\n this.selectItem(player.getAudioQuality().id);\n };\n\n let updateAudioQualities = () => {\n let audioQualities = player.getAvailableAudioQualities();\n\n this.clearItems();\n\n // Add entry for automatic quality switching (default setting)\n this.addItem('auto', i18n.getLocalizer('auto'));\n\n // Add audio qualities\n for (let audioQuality of audioQualities) {\n this.addItem(audioQuality.id, audioQuality.label);\n }\n\n // Select initial quality\n selectCurrentAudioQuality();\n };\n\n this.onItemSelected.subscribe((sender: AudioQualitySelectBox, value: string) => {\n player.setAudioQuality(value);\n });\n\n // Update qualities when audio track has changed\n player.on(player.exports.PlayerEvent.AudioChanged, updateAudioQualities);\n // Update qualities when source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, updateAudioQualities);\n // Update qualities when the period within a source changes\n player.on(player.exports.PlayerEvent.PeriodSwitched, updateAudioQualities);\n // Update quality selection when quality is changed (from outside)\n player.on(player.exports.PlayerEvent.AudioQualityChanged, selectCurrentAudioQuality);\n if ((player.exports.PlayerEvent as any).AudioQualityAdded) {\n // Update qualities when their availability changed\n // TODO: remove any cast after next player release\n player.on((player.exports.PlayerEvent as any).AudioQualityAdded, updateAudioQualities);\n player.on((player.exports.PlayerEvent as any).AudioQualityRemoved, updateAudioQualities);\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(updateAudioQualities);\n }\n}","import {ListBox} from './listbox';\nimport {UIInstanceManager} from '../uimanager';\nimport {AudioTrackSwitchHandler} from '../audiotrackutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A element that is similar to a select box where the user can select a subtitle\n *\n * @category Components\n */\nexport class AudioTrackListBox extends ListBox {\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n new AudioTrackSwitchHandler(player, this, uimanager);\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport {AudioTrackSwitchHandler} from '../audiotrackutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A select box providing a selection between available audio tracks (e.g. different languages).\n *\n * @category Components\n */\nexport class AudioTrackSelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-audiotrackselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new AudioTrackSwitchHandler(player, this, uimanager);\n }\n}","import {ContainerConfig, Container} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for the {@link BufferingOverlay} component.\n *\n * @category Configs\n */\nexport interface BufferingOverlayConfig extends ContainerConfig {\n /**\n * Delay in milliseconds after which the buffering overlay will be displayed. Useful to bypass short stalls without\n * displaying the overlay. Set to 0 to display the overlay instantly.\n * Default: 1000ms (1 second)\n */\n showDelayMs?: number;\n}\n\n/**\n * Overlays the player and displays a buffering indicator.\n *\n * @category Components\n */\nexport class BufferingOverlay extends Container<BufferingOverlayConfig> {\n\n private indicators: Component<ComponentConfig>[];\n\n constructor(config: BufferingOverlayConfig = {}) {\n super(config);\n\n this.indicators = [\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-buffering-overlay-indicator', role: 'img' }),\n ];\n\n this.config = this.mergeConfig(config, <BufferingOverlayConfig>{\n cssClass: 'ui-buffering-overlay',\n hidden: true,\n components: this.indicators,\n showDelayMs: 1000,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n let overlayShowTimeout = new Timeout(config.showDelayMs, () => {\n this.show();\n });\n\n let showOverlay = () => {\n overlayShowTimeout.start();\n };\n\n let hideOverlay = () => {\n overlayShowTimeout.clear();\n this.hide();\n };\n\n player.on(player.exports.PlayerEvent.StallStarted, showOverlay);\n player.on(player.exports.PlayerEvent.StallEnded, hideOverlay);\n player.on(player.exports.PlayerEvent.Play, showOverlay);\n player.on(player.exports.PlayerEvent.Playing, hideOverlay);\n player.on(player.exports.PlayerEvent.Paused, hideOverlay);\n player.on(player.exports.PlayerEvent.Seek, showOverlay);\n player.on(player.exports.PlayerEvent.Seeked, hideOverlay);\n player.on(player.exports.PlayerEvent.TimeShift, showOverlay);\n player.on(player.exports.PlayerEvent.TimeShifted, hideOverlay);\n player.on(player.exports.PlayerEvent.SourceUnloaded, hideOverlay);\n\n // Show overlay if player is already stalled at init\n if (player.isStalled()) {\n this.show();\n }\n }\n}\n","import {ComponentConfig, Component} from './component';\nimport {DOM} from '../dom';\nimport {EventDispatcher, NoArgs, Event} from '../eventdispatcher';\nimport { LocalizableText , i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Button} component.\n *\n * @category Configs\n */\nexport interface ButtonConfig extends ComponentConfig {\n /**\n * The text as string or localize callback on the button.\n */\n text?: LocalizableText;\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n */\n ariaLabel?: LocalizableText;\n\n /**\n * Specifies whether the first touch event received by the {@link UIContainer} should be prevented or not.\n *\n * Default: false\n */\n acceptsTouchWithUiHidden?: boolean;\n}\n\n/**\n * A simple clickable button.\n *\n * @category Components\n */\nexport class Button<Config extends ButtonConfig> extends Component<Config> {\n\n private buttonEvents = {\n onClick: new EventDispatcher<Button<Config>, NoArgs>(),\n };\n\n constructor(config: Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-button',\n role: 'button',\n tabIndex: 0,\n acceptsTouchWithUiHidden: false,\n } as Config, this.config);\n }\n\n protected toDomElement(): DOM {\n const buttonElementAttributes: { [name: string]: string } = {\n 'id': this.config.id,\n 'aria-label': i18n.performLocalization(this.config.ariaLabel || this.config.text),\n 'class': this.getCssClasses(),\n 'type' : 'button',\n /**\n * WCAG20 standard to display if a button is pressed or not\n */\n 'aria-pressed': 'false',\n 'tabindex': this.config.tabIndex.toString(),\n };\n\n if (this.config.role != null) {\n buttonElementAttributes['role'] = this.config.role;\n }\n\n // Create the button element with the text label\n let buttonElement = new DOM('button', buttonElementAttributes, this).append(new DOM('span', {\n 'class': this.prefixCss('label'),\n }).html(i18n.performLocalization(this.config.text)));\n\n // Listen for the click event on the button element and trigger the corresponding event on the button component\n buttonElement.on('click', () => {\n this.onClickEvent();\n });\n\n return buttonElement;\n }\n\n /**\n * Sets text on the label of the button.\n * @param text the text to put into the label of the button\n */\n setText(text: LocalizableText): void {\n this.getDomElement().find('.' + this.prefixCss('label')).html(i18n.performLocalization(text));\n }\n\n protected onClickEvent() {\n this.buttonEvents.onClick.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the button is clicked.\n * @returns {Event<Button<Config>, NoArgs>}\n */\n get onClick(): Event<Button<Config>, NoArgs> {\n return this.buttonEvents.onClick.getEvent();\n }\n}\n","import {ContainerConfig, Container} from './container';\nimport {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport { CastStartedEvent, CastWaitingForDeviceEvent, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Overlays the player and displays the status of a Cast session.\n *\n * @category Components\n */\nexport class CastStatusOverlay extends Container<ContainerConfig> {\n\n private statusLabel: Label<LabelConfig>;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.statusLabel = new Label<LabelConfig>({ cssClass: 'ui-cast-status-label' });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-cast-status-overlay',\n components: [this.statusLabel],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n player.on(player.exports.PlayerEvent.CastWaitingForDevice,\n (event: CastWaitingForDeviceEvent) => {\n this.show();\n // Get device name and update status text while connecting\n let castDeviceName = event.castPayload.deviceName;\n this.statusLabel.setText(i18n.getLocalizer('connectingTo', { castDeviceName }));\n });\n player.on(player.exports.PlayerEvent.CastStarted, (event: CastStartedEvent) => {\n // Session is started or resumed\n // For cases when a session is resumed, we do not receive the previous events and therefore show the status panel\n // here too\n this.show();\n let castDeviceName = event.deviceName;\n this.statusLabel.setText(i18n.getLocalizer('playingOn', { castDeviceName }));\n });\n player.on(player.exports.PlayerEvent.CastStopped, (event) => {\n // Cast session gone, hide the status panel\n this.hide();\n });\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles casting to a Cast receiver.\n *\n * @category Buttons\n */\nexport class CastToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-casttogglebutton',\n text: i18n.getLocalizer('googleCast'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n if (player.isCastAvailable()) {\n if (player.isCasting()) {\n player.castStop();\n } else {\n player.castVideo();\n }\n } else {\n if (console) {\n console.log('Cast unavailable');\n }\n }\n });\n\n let castAvailableHander = () => {\n if (player.isCastAvailable()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n player.on(player.exports.PlayerEvent.CastAvailable, castAvailableHander);\n\n // Toggle button 'on' state\n player.on(player.exports.PlayerEvent.CastWaitingForDevice, () => {\n this.on();\n });\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n // When a session is resumed, there is no CastStart event, so we also need to toggle here for such cases\n this.on();\n });\n player.on(player.exports.PlayerEvent.CastStopped, () => {\n this.off();\n });\n\n // Startup init\n castAvailableHander(); // Hide button if Cast not available\n if (player.isCasting()) {\n this.on();\n }\n }\n}","import {UIContainer, UIContainerConfig} from './uicontainer';\nimport {UIInstanceManager} from '../uimanager';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * The base container for Cast receivers that contains all of the UI and takes care that the UI is shown on\n * certain playback events.\n *\n * @category Containers\n */\nexport class CastUIContainer extends UIContainer {\n\n private castUiHideTimeout: Timeout;\n\n constructor(config: UIContainerConfig) {\n super(config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n /*\n * Show UI on Cast devices at certain playback events\n *\n * Since a Cast receiver does not have a direct HCI, we show the UI on certain playback events to give the user\n * a chance to see on the screen what's going on, e.g. on play/pause or a seek the UI is shown and the user can\n * see the current time and position on the seek bar.\n * The UI is shown permanently while playback is paused, otherwise hides automatically after the configured\n * hide delay time.\n */\n\n let isUiShown = false;\n\n let hideUi = () => {\n uimanager.onControlsHide.dispatch(this);\n isUiShown = false;\n };\n\n this.castUiHideTimeout = new Timeout(config.hideDelay, hideUi);\n\n let showUi = () => {\n if (!isUiShown) {\n uimanager.onControlsShow.dispatch(this);\n isUiShown = true;\n }\n };\n\n let showUiPermanently = () => {\n showUi();\n this.castUiHideTimeout.clear();\n };\n\n let showUiWithTimeout = () => {\n showUi();\n this.castUiHideTimeout.start();\n };\n\n let showUiAfterSeek = () => {\n if (player.isPlaying()) {\n showUiWithTimeout();\n } else {\n showUiPermanently();\n }\n };\n\n player.on(player.exports.PlayerEvent.Play, showUiWithTimeout);\n player.on(player.exports.PlayerEvent.Paused, showUiPermanently);\n player.on(player.exports.PlayerEvent.Seek, showUiPermanently);\n player.on(player.exports.PlayerEvent.Seeked, showUiAfterSeek);\n\n uimanager.getConfig().events.onUpdated.subscribe(showUiWithTimeout);\n }\n\n release(): void {\n super.release();\n this.castUiHideTimeout.clear();\n }\n}","import {Button, ButtonConfig} from './button';\n\n/**\n * Configuration interface for a {@link ClickOverlay}.\n *\n * @category Configs\n */\nexport interface ClickOverlayConfig extends ButtonConfig {\n /**\n * The url to open when the overlay is clicked. Set to null to disable the click handler.\n */\n url?: string;\n}\n\n/**\n * A click overlay that opens an url in a new tab if clicked.\n *\n * @category Components\n */\nexport class ClickOverlay extends Button<ClickOverlayConfig> {\n\n constructor(config: ClickOverlayConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-clickoverlay',\n role: this.config.role,\n }, <ClickOverlayConfig>this.config);\n }\n\n initialize(): void {\n super.initialize();\n\n this.setUrl((<ClickOverlayConfig>this.config).url);\n let element = this.getDomElement();\n element.on('click', () => {\n if (element.data('url')) {\n window.open(element.data('url'), '_blank');\n }\n });\n }\n\n /**\n * Gets the URL that should be followed when the watermark is clicked.\n * @returns {string} the watermark URL\n */\n getUrl(): string {\n return this.getDomElement().data('url');\n }\n\n setUrl(url: string): void {\n if (url === undefined || url == null) {\n url = '';\n }\n this.getDomElement().data('url', url);\n }\n}","import {ButtonConfig, Button} from './button';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link CloseButton}.\n *\n * @category Configs\n */\nexport interface CloseButtonConfig extends ButtonConfig {\n /**\n * The component that should be closed when the button is clicked.\n */\n target: Component<ComponentConfig>;\n}\n\n/**\n * A button that closes (hides) a configured component.\n *\n * @category Buttons\n */\nexport class CloseButton extends Button<CloseButtonConfig> {\n\n constructor(config: CloseButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-closebutton',\n text: i18n.getLocalizer('close'),\n } as CloseButtonConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n this.onClick.subscribe(() => {\n config.target.hide();\n });\n }\n}","import {Guid} from '../guid';\nimport {DOM} from '../dom';\nimport {EventDispatcher, NoArgs, Event} from '../eventdispatcher';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n, LocalizableText } from '../localization/i18n';\n\n/**\n * Base configuration interface for a component.\n * Should be extended by components that want to add additional configuration options.\n *\n * @category Configs\n */\nexport interface ComponentConfig {\n /**\n * The HTML tag name of the component.\n * Default: 'div'\n */\n tag?: string;\n /**\n * The HTML ID of the component.\n * Default: automatically generated with pattern 'ui-id-{guid}'.\n */\n id?: string;\n\n /**\n * A prefix to prepend all CSS classes with.\n */\n cssPrefix?: string;\n\n /**\n * The CSS classes of the component. This is usually the class from where the component takes its styling.\n */\n cssClass?: string; // 'class' is a reserved keyword, so we need to make the name more complicated\n\n /**\n * Additional CSS classes of the component.\n */\n cssClasses?: string[];\n\n /**\n * Specifies if the component should be hidden at startup.\n * Default: false\n */\n hidden?: boolean;\n\n /**\n * Specifies if the component is enabled (interactive) or not.\n * Default: false\n */\n disabled?: boolean;\n\n /**\n * Specifies the component role for WCAG20 standard\n */\n role?: string;\n\n /**\n * WCAG20 requirement for screen reader navigation\n */\n tabIndex?: number;\n\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n */\n ariaLabel?: LocalizableText;\n}\n\nexport interface ComponentHoverChangedEventArgs extends NoArgs {\n /**\n * True is the component is hovered, else false.\n */\n hovered: boolean;\n}\n\nexport enum ViewMode {\n /**\n * Indicates that the component has entered a view mode where it must stay visible. Auto-hiding of this component\n * must be disabled as long as it resides in this state.\n */\n Persistent = 'persistent',\n\n /**\n * The control can be hidden at any time.\n */\n Temporary = 'temporary',\n}\n\nexport interface ViewModeChangedEventArgs extends NoArgs {\n /**\n * The `ViewMode` the control is currently in.\n */\n mode: ViewMode;\n}\n\n/**\n * The base class of the UI framework.\n * Each component must extend this class and optionally the config interface.\n *\n * @category Components\n */\nexport class Component<Config extends ComponentConfig> {\n\n /**\n * The classname that is attached to the element when it is in the hidden state.\n * @type {string}\n */\n private static readonly CLASS_HIDDEN = 'hidden';\n\n /**\n * The classname that is attached to the element when it is in the disabled state.\n * @type {string}\n */\n private static readonly CLASS_DISABLED = 'disabled';\n\n /**\n * Configuration object of this component.\n */\n protected config: Config;\n\n /**\n * The component's DOM element.\n */\n private element: DOM;\n\n /**\n * Flag that keeps track of the hidden state.\n */\n private hidden: boolean;\n\n /**\n * Flat that keeps track of the disabled state.\n */\n private disabled: boolean;\n\n /**\n * Flag that keeps track of the hover state.\n */\n private hovered: boolean;\n\n /**\n * The current view mode of the component.\n */\n private viewMode: ViewMode;\n\n /**\n * The list of events that this component offers. These events should always be private and only directly\n * accessed from within the implementing component.\n *\n * Because TypeScript does not support private properties with the same name on different class hierarchy levels\n * (i.e. superclass and subclass cannot contain a private property with the same name), the default naming\n * convention for the event list of a component that should be followed by subclasses is the concatenation of the\n * camel-cased class name + 'Events' (e.g. SubClass extends Component => subClassEvents).\n * See {@link #componentEvents} for an example.\n *\n * Event properties should be named in camel case with an 'on' prefix and in the present tense. Async events may\n * have a start event (when the operation starts) in the present tense, and must have an end event (when the\n * operation ends) in the past tense (or present tense in special cases (e.g. onStart/onStarted or onPlay/onPlaying).\n * See {@link #componentEvents#onShow} for an example.\n *\n * Each event should be accompanied with a protected method named by the convention eventName + 'Event'\n * (e.g. onStartEvent), that actually triggers the event by calling {@link EventDispatcher#dispatch dispatch} and\n * passing a reference to the component as first parameter. Components should always trigger their events with these\n * methods. Implementing this pattern gives subclasses means to directly listen to the events by overriding the\n * method (and saving the overhead of passing a handler to the event dispatcher) and more importantly to trigger\n * these events without having access to the private event list.\n * See {@link #onShow} for an example.\n *\n * To provide external code the possibility to listen to this component's events (subscribe, unsubscribe, etc.),\n * each event should also be accompanied by a public getter function with the same name as the event's property,\n * that returns the {@link Event} obtained from the event dispatcher by calling {@link EventDispatcher#getEvent}.\n * See {@link #onShow} for an example.\n *\n * Full example for an event representing an example action in a example component:\n *\n * <code>\n * // Define an example component class with an example event\n * class ExampleComponent extends Component<ComponentConfig> {\n *\n * private exampleComponentEvents = {\n * onExampleAction: new EventDispatcher<ExampleComponent, NoArgs>()\n * }\n *\n * // constructor and other stuff...\n *\n * protected onExampleActionEvent() {\n * this.exampleComponentEvents.onExampleAction.dispatch(this);\n * }\n *\n * get onExampleAction(): Event<ExampleComponent, NoArgs> {\n * return this.exampleComponentEvents.onExampleAction.getEvent();\n * }\n * }\n *\n * // Create an instance of the component somewhere\n * var exampleComponentInstance = new ExampleComponent();\n *\n * // Subscribe to the example event on the component\n * exampleComponentInstance.onExampleAction.subscribe(function (sender: ExampleComponent) {\n * console.log('onExampleAction of ' + sender + ' has fired!');\n * });\n * </code>\n */\n private componentEvents = {\n onShow: new EventDispatcher<Component<Config>, NoArgs>(),\n onHide: new EventDispatcher<Component<Config>, NoArgs>(),\n onViewModeChanged: new EventDispatcher<Component<Config>, ViewModeChangedEventArgs>(),\n onHoverChanged: new EventDispatcher<Component<Config>, ComponentHoverChangedEventArgs>(),\n onEnabled: new EventDispatcher<Component<Config>, NoArgs>(),\n onDisabled: new EventDispatcher<Component<Config>, NoArgs>(),\n };\n\n /**\n * Constructs a component with an optionally supplied config. All subclasses must call the constructor of their\n * superclass and then merge their configuration into the component's configuration.\n * @param config the configuration for the component\n */\n constructor(config: ComponentConfig = {}) {\n // Create the configuration for this component\n this.config = <Config>this.mergeConfig(config, {\n tag: 'div',\n id: '{{PREFIX}}-id-' + Guid.next(),\n cssPrefix: '{{PREFIX}}',\n cssClass: 'ui-component',\n cssClasses: [],\n hidden: false,\n disabled: false,\n }, {});\n this.viewMode = ViewMode.Temporary;\n }\n\n /**\n * Initializes the component, e.g. by applying config settings.\n * This method must not be called from outside the UI framework.\n *\n * This method is automatically called by the {@link UIInstanceManager}. If the component is an inner component of\n * some component, and thus encapsulated abd managed internally and never directly exposed to the UIManager,\n * this method must be called from the managing component's {@link #initialize} method.\n */\n initialize(): void {\n this.hidden = this.config.hidden;\n this.disabled = this.config.disabled;\n\n // Hide the component at initialization if it is configured to be hidden\n if (this.isHidden()) {\n this.hidden = false; // Set flag to false for the following hide() call to work (hide() checks the flag)\n this.hide();\n }\n\n // Disable the component at initialization if it is configured to be disabled\n if (this.isDisabled()) {\n this.disabled = false; // Set flag to false for the following disable() call to work (disable() checks the flag)\n this.disable();\n }\n }\n\n /**\n * Configures the component for the supplied Player and UIInstanceManager. This is the place where all the magic\n * happens, where components typically subscribe and react to events (on their DOM element, the Player, or the\n * UIInstanceManager), and basically everything that makes them interactive.\n * This method is called only once, when the UIManager initializes the UI.\n *\n * Subclasses usually overwrite this method to add their own functionality.\n *\n * @param player the player which this component controls\n * @param uimanager the UIInstanceManager that manages this component\n */\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n this.onShow.subscribe(() => uimanager.onComponentShow.dispatch(this));\n this.onHide.subscribe(() => uimanager.onComponentHide.dispatch(this));\n this.onViewModeChanged.subscribe((_, args) => uimanager.onComponentViewModeChanged.dispatch(this, args));\n\n // Track the hovered state of the element\n this.getDomElement().on('mouseenter', () => this.onHoverChangedEvent(true));\n this.getDomElement().on('mouseleave', () => this.onHoverChangedEvent(false));\n }\n\n /**\n * Releases all resources and dependencies that the component holds. Player, DOM, and UIManager events are\n * automatically removed during release and do not explicitly need to be removed here.\n * This method is called by the UIManager when it releases the UI.\n *\n * Subclasses that need to release resources should override this method and call super.release().\n */\n release(): void {\n // Nothing to do here, override where necessary\n }\n\n /**\n * Generate the DOM element for this component.\n *\n * Subclasses usually overwrite this method to extend or replace the DOM element with their own design.\n */\n protected toDomElement(): DOM {\n let element = new DOM(this.config.tag, {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': this.config.role,\n }, this);\n\n return element;\n }\n\n /**\n * Returns the DOM element of this component. Creates the DOM element if it does not yet exist.\n *\n * Should not be overwritten by subclasses.\n *\n * @returns {DOM}\n */\n getDomElement(): DOM {\n if (!this.element) {\n this.element = this.toDomElement();\n }\n\n return this.element;\n }\n\n /**\n * Checks if this component has a DOM element.\n */\n hasDomElement(): boolean {\n return Boolean(this.element);\n }\n\n setAriaLabel(label: LocalizableText): void {\n this.setAriaAttr('label', i18n.performLocalization(label));\n }\n\n setAriaAttr(name: string, value: string) {\n this.getDomElement().attr(`aria-${name}`, value);\n }\n\n /**\n * Merges a configuration with a default configuration and a base configuration from the superclass.\n *\n * @param config the configuration settings for the components, as usually passed to the constructor\n * @param defaults a default configuration for settings that are not passed with the configuration\n * @param base configuration inherited from a superclass\n * @returns {Config}\n */\n protected mergeConfig<Config>(config: Config, defaults: Config, base: Config): Config {\n // Extend default config with supplied config\n let merged = Object.assign({}, base, defaults, config);\n\n // Return the extended config\n return merged;\n }\n\n /**\n * Helper method that returns a string of all CSS classes of the component.\n *\n * @returns {string}\n */\n protected getCssClasses(): string {\n // Merge all CSS classes into single array\n let flattenedArray = [this.config.cssClass].concat(this.config.cssClasses);\n // Prefix classes\n flattenedArray = flattenedArray.map((css) => {\n return this.prefixCss(css);\n });\n // Join array values into a string\n let flattenedString = flattenedArray.join(' ');\n // Return trimmed string to prevent whitespace at the end from the join operation\n return flattenedString.trim();\n }\n\n protected prefixCss(cssClassOrId: string): string {\n return this.config.cssPrefix + '-' + cssClassOrId;\n }\n\n /**\n * Returns the configuration object of the component.\n * @returns {Config}\n */\n public getConfig(): Config {\n return this.config;\n }\n\n /**\n * Hides the component if shown.\n * This method basically transfers the component into the hidden state. Actual hiding is done via CSS.\n */\n hide() {\n if (!this.hidden) {\n this.hidden = true;\n this.getDomElement().addClass(this.prefixCss(Component.CLASS_HIDDEN));\n this.onHideEvent();\n }\n }\n\n /**\n * Shows the component if hidden.\n */\n show() {\n if (this.hidden) {\n this.getDomElement().removeClass(this.prefixCss(Component.CLASS_HIDDEN));\n this.hidden = false;\n this.onShowEvent();\n }\n }\n\n /**\n * Determines if the component is hidden.\n * @returns {boolean} true if the component is hidden, else false\n */\n isHidden(): boolean {\n return this.hidden;\n }\n\n /**\n * Determines if the component is shown.\n * @returns {boolean} true if the component is visible, else false\n */\n isShown(): boolean {\n return !this.isHidden();\n }\n\n /**\n * Toggles the hidden state by hiding the component if it is shown, or showing it if hidden.\n */\n toggleHidden() {\n if (this.isHidden()) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n /**\n * Disables the component.\n * This method basically transfers the component into the disabled state. Actual disabling is done via CSS or child\n * components. (e.g. Button needs to unsubscribe click listeners)\n */\n disable(): void {\n if (!this.disabled) {\n this.disabled = true;\n this.getDomElement().addClass(this.prefixCss(Component.CLASS_DISABLED));\n this.onDisabledEvent();\n }\n }\n\n /**\n * Enables the component.\n * This method basically transfers the component into the enabled state. Actual enabling is done via CSS or child\n * components. (e.g. Button needs to subscribe click listeners)\n */\n enable(): void {\n if (this.disabled) {\n this.getDomElement().removeClass(this.prefixCss(Component.CLASS_DISABLED));\n this.disabled = false;\n this.onEnabledEvent();\n }\n }\n\n /**\n * Determines if the component is disabled.\n * @returns {boolean} true if the component is disabled, else false\n */\n isDisabled(): boolean {\n return this.disabled;\n }\n\n /**\n * Determines if the component is enabled.\n * @returns {boolean} true if the component is enabled, else false\n */\n isEnabled(): boolean {\n return !this.isDisabled();\n }\n\n /**\n * Determines if the component is currently hovered.\n * @returns {boolean} true if the component is hovered, else false\n */\n isHovered(): boolean {\n return this.hovered;\n }\n\n /**\n * Fires the onShow event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onShowEvent(): void {\n this.componentEvents.onShow.dispatch(this);\n }\n\n /**\n * Fires the onHide event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onHideEvent(): void {\n this.componentEvents.onHide.dispatch(this);\n }\n\n /**\n * Fires the onEnabled event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onEnabledEvent(): void {\n this.componentEvents.onEnabled.dispatch(this);\n }\n\n /**\n * Fires the onDisabled event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onDisabledEvent(): void {\n this.componentEvents.onDisabled.dispatch(this);\n }\n\n /**\n * Fires the onViewModeChanged event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onViewModeChangedEvent(mode: ViewMode): void {\n if (this.viewMode === mode) {\n return;\n }\n\n this.viewMode = mode;\n this.componentEvents.onViewModeChanged.dispatch(this, { mode });\n }\n\n /**\n * Fires the onHoverChanged event.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n */\n protected onHoverChangedEvent(hovered: boolean): void {\n this.hovered = hovered;\n this.componentEvents.onHoverChanged.dispatch(this, { hovered: hovered });\n }\n\n /**\n * Gets the event that is fired when the component is showing.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onShow(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onShow.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is hiding.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onHide(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onHide.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is enabling.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onEnabled(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onEnabled.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component is disabling.\n * See the detailed explanation on event architecture on the {@link #componentEvents events list}.\n * @returns {Event<Component<Config>, NoArgs>}\n */\n get onDisabled(): Event<Component<Config>, NoArgs> {\n return this.componentEvents.onDisabled.getEvent();\n }\n\n /**\n * Gets the event that is fired when the component's hover-state is changing.\n * @returns {Event<Component<Config>, ComponentHoverChangedEventArgs>}\n */\n get onHoverChanged(): Event<Component<Config>, ComponentHoverChangedEventArgs> {\n return this.componentEvents.onHoverChanged.getEvent();\n }\n\n /**\n * Gets the event that is fired when the `ViewMode` of this component has changed.\n * @returns {Event<Component<Config>, ViewModeChangedEventArgs>}\n */\n get onViewModeChanged(): Event<Component<Config>, ViewModeChangedEventArgs> {\n return this.componentEvents.onViewModeChanged.getEvent();\n }\n}","import { ComponentConfig, Component, ViewModeChangedEventArgs, ViewMode } from './component';\nimport {DOM} from '../dom';\nimport {ArrayUtils} from '../arrayutils';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Container}.\n *\n * @category Configs\n */\nexport interface ContainerConfig extends ComponentConfig {\n /**\n * Child components of the container.\n */\n components?: Component<ComponentConfig>[];\n}\n\n/**\n * A container component that can contain a collection of child components.\n * Components can be added at construction time through the {@link ContainerConfig#components} setting, or later\n * through the {@link Container#addComponent} method. The UIManager automatically takes care of all components, i.e. it\n * initializes and configures them automatically.\n *\n * In the DOM, the container consists of an outer <div> (that can be configured by the config) and an inner wrapper\n * <div> that contains the components. This double-<div>-structure is often required to achieve many advanced effects\n * in CSS and/or JS, e.g. animations and certain formatting with absolute positioning.\n *\n * DOM example:\n * <code>\n * <div class='ui-container'>\n * <div class='container-wrapper'>\n * ... child components ...\n * </div>\n * </div>\n * </code>\n *\n * @category Components\n */\nexport class Container<Config extends ContainerConfig> extends Component<Config> {\n\n /**\n * A reference to the inner element that contains the components of the container.\n */\n private innerContainerElement: DOM;\n private componentsToAdd: Component<ComponentConfig>[];\n private componentsToRemove: Component<ComponentConfig>[];\n private componentsInPersistentViewMode: number;\n\n constructor(config: Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-container',\n components: [],\n } as Config, this.config);\n\n this.componentsToAdd = [];\n this.componentsToRemove = [];\n this.componentsInPersistentViewMode = 0;\n }\n\n /**\n * Adds a child component to the container.\n * @param component the component to add\n */\n addComponent(component: Component<ComponentConfig>) {\n this.config.components.push(component);\n this.componentsToAdd.push(component);\n }\n\n /**\n * Removes a child component from the container.\n * @param component the component to remove\n * @returns {boolean} true if the component has been removed, false if it is not contained in this container\n */\n removeComponent(component: Component<ComponentConfig>): boolean {\n if (ArrayUtils.remove(this.config.components, component) != null) {\n this.componentsToRemove.push(component);\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Gets an array of all child components in this container.\n * @returns {Component<ComponentConfig>[]}\n */\n getComponents(): Component<ComponentConfig>[] {\n return this.config.components;\n }\n\n /**\n * Removes all child components from the container.\n */\n removeComponents(): void {\n for (let component of this.getComponents().slice()) {\n this.removeComponent(component);\n }\n }\n\n /**\n * Updates the DOM of the container with the current components.\n */\n protected updateComponents(): void {\n /* We cannot just clear the container to remove all elements and then re-add those that should stay, because\n * IE looses the innerHTML of unattached elements, leading to empty elements within the container (e.g. missing\n * subtitle text in SubtitleLabel).\n * Instead, we keep a list of elements to add and remove, leaving remaining elements alone. By keeping them in\n * the DOM, their content gets preserved in all browsers.\n */\n let component;\n\n while ((component = this.componentsToRemove.shift()) !== undefined) {\n component.getDomElement().remove();\n }\n\n while ((component = this.componentsToAdd.shift()) !== undefined) {\n this.innerContainerElement.append(component.getDomElement());\n }\n }\n\n protected toDomElement(): DOM {\n // Create the container element (the outer <div>)\n let containerElement = new DOM(this.config.tag, {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': this.config.role,\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n }, this);\n\n // Create the inner container element (the inner <div>) that will contain the components\n let innerContainer = new DOM(this.config.tag, {\n 'class': this.prefixCss('container-wrapper'),\n });\n this.innerContainerElement = innerContainer;\n\n for (let initialComponent of this.config.components) {\n this.componentsToAdd.push(initialComponent);\n }\n this.updateComponents();\n\n containerElement.append(innerContainer);\n\n return containerElement;\n }\n\n protected suspendHideTimeout(): void {\n // to be implemented in subclass\n }\n\n protected resumeHideTimeout(): void {\n // to be implemented in subclass\n }\n\n protected trackComponentViewMode(mode: ViewMode) {\n if (mode === ViewMode.Persistent) {\n this.componentsInPersistentViewMode++;\n } else if (mode === ViewMode.Temporary) {\n this.componentsInPersistentViewMode = Math.max(this.componentsInPersistentViewMode - 1, 0);\n }\n\n if (this.componentsInPersistentViewMode > 0) {\n // There is at least one component that must not be hidden,\n // therefore the hide timeout must be suspended\n this.suspendHideTimeout();\n } else {\n this.resumeHideTimeout();\n }\n }\n}","import {ContainerConfig, Container} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {UIUtils} from '../uiutils';\nimport {Spacer} from './spacer';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { BrowserUtils } from '../browserutils';\nimport {Component, ComponentConfig} from './component';\nimport {SettingsPanel} from './settingspanel';\n\n/**\n * Configuration interface for the {@link ControlBar}.\n *\n * @category Configs\n */\nexport interface ControlBarConfig extends ContainerConfig {\n // nothing yet\n}\n\n/**\n * A container for main player control components, e.g. play toggle button, seek bar, volume control, fullscreen toggle\n * button.\n *\n * @category Components\n */\nexport class ControlBar extends Container<ControlBarConfig> {\n\n constructor(config: ControlBarConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-controlbar',\n hidden: true,\n role: 'region',\n ariaLabel: i18n.getLocalizer('controlBar'),\n }, <ControlBarConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n // Counts how many components are hovered and block hiding of the control bar\n let hoverStackCount = 0;\n let isSettingsPanelShown = false;\n\n // Only enabling this for platforms without touch input.\n // Enabling this for touch devices causes the UI to not disappear after hideDelay seconds,\n // because `mouseleave` event is not emitted.\n // Instead, it will stay visible until another manual interaction is performed.\n if (uimanager.getConfig().disableAutoHideWhenHovered && !BrowserUtils.isTouchSupported) {\n // Track hover status of child components\n UIUtils.traverseTree(this, (component) => {\n // Do not track hover status of child containers or spacers, only of 'real' controls\n if (component instanceof Container || component instanceof Spacer) {\n return;\n }\n\n // Subscribe hover event and keep a count of the number of hovered children\n component.onHoverChanged.subscribe((_, args) => {\n if (args.hovered) {\n hoverStackCount++;\n } else {\n hoverStackCount--;\n }\n });\n });\n }\n\n if (BrowserUtils.isMobile) {\n uimanager.onComponentShow.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof SettingsPanel) {\n isSettingsPanelShown = true;\n }\n });\n\n uimanager.onComponentHide.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof SettingsPanel) {\n isSettingsPanelShown = false;\n }\n });\n }\n\n uimanager.onControlsShow.subscribe(() => {\n this.show();\n });\n\n uimanager.onPreviewControlsHide.subscribe((sender, args) => {\n // Cancel the hide event if hovered child components block hiding or if the settings panel is active on mobile.\n args.cancel = args.cancel || (hoverStackCount > 0 || isSettingsPanelShown);\n });\n\n uimanager.onControlsHide.subscribe(() => {\n this.hide();\n });\n }\n}\n","import { PlayerAPI, SegmentPlaybackEvent, VideoQuality } from 'bitmovin-player';\r\nimport { i18n } from '../localization/i18n';\r\nimport { Container, ContainerConfig } from './container';\r\nimport { EcoModeToggleButton } from './ecomodetogglebutton';\r\nimport { Label, LabelConfig } from './label';\r\nimport { SettingsPanelItem } from './settingspanelitem';\r\n\r\n/**\r\n * @category Containers\r\n */\r\nexport class EcoModeContainer extends Container<ContainerConfig> {\r\n private ecoModeSavedEmissionsItem: SettingsPanelItem;\r\n private ecoModeToggleButtonItem: SettingsPanelItem;\r\n private emissionsSavedLabel: Label<LabelConfig>;\r\n private savedEmissons = 0;\r\n private currentEnergyEmission: number;\r\n\r\n constructor(config: ContainerConfig = {}) {\r\n super(config);\r\n\r\n const ecoModeToggleButton = new EcoModeToggleButton();\r\n const labelEcoMode = new Label({\r\n text: i18n.getLocalizer('ecoMode.title'),\r\n for: ecoModeToggleButton.getConfig().id,\r\n id: 'ecomodelabel',\r\n });\r\n this.emissionsSavedLabel = new Label({\r\n text: `${this.savedEmissons.toFixed(4)} gCO2`,\r\n cssClass: 'ui-label-savedEnergy',\r\n });\r\n\r\n this.ecoModeToggleButtonItem = new SettingsPanelItem(labelEcoMode, ecoModeToggleButton);\r\n this.ecoModeSavedEmissionsItem = new SettingsPanelItem('Saved Emissions', this.emissionsSavedLabel, {\r\n hidden: true,\r\n });\r\n\r\n this.addComponent(this.ecoModeToggleButtonItem);\r\n this.addComponent(this.ecoModeSavedEmissionsItem);\r\n\r\n ecoModeToggleButton.onToggleOn.subscribe(() => {\r\n this.ecoModeSavedEmissionsItem.show();\r\n this.onToggleCallback();\r\n });\r\n\r\n ecoModeToggleButton.onToggleOff.subscribe(() => {\r\n this.ecoModeSavedEmissionsItem.hide();\r\n this.onToggleCallback();\r\n });\r\n }\r\n\r\n private onToggleCallback: () => void;\r\n\r\n public setOnToggleCallback(callback: () => void) {\r\n this.onToggleCallback = callback;\r\n }\r\n\r\n configure(player: PlayerAPI): void {\r\n player.on(player.exports.PlayerEvent.SegmentPlayback, (segment: SegmentPlaybackEvent) => {\r\n if (!segment.mimeType.includes('video')) {\r\n return;\r\n }\r\n\r\n const { height, width, bitrate, frameRate } = segment.mediaInfo;\r\n const {\r\n height: maxHeight,\r\n bitrate: maxBitrate,\r\n width: maxWidth,\r\n } = this.getMaxQualityAvailable(player.getAvailableVideoQualities());\r\n\r\n const currentEnergyKwh = this.calculateEnergyConsumption(frameRate, height, width, bitrate, segment.duration);\r\n\r\n const maxEnergyKwh = this.calculateEnergyConsumption(\r\n frameRate,\r\n maxHeight,\r\n maxWidth,\r\n maxBitrate,\r\n segment.duration,\r\n );\r\n\r\n if (this.ecoModeSavedEmissionsItem.isShown()) {\r\n this.updateSavedEmissions(currentEnergyKwh, maxEnergyKwh, this.emissionsSavedLabel);\r\n }\r\n });\r\n }\r\n\r\n updateSavedEmissions(\r\n currentEnergyConsuption: number,\r\n maxEnergyConsuption: number,\r\n emissionsSavedLabel: Label<LabelConfig>,\r\n ) {\r\n // 475 is the average carbon intensity of all countries in gCO2/kWh\r\n const averageCarbonIntensity = 475;\r\n\r\n this.currentEnergyEmission = currentEnergyConsuption * averageCarbonIntensity;\r\n const maxEnergyEmisson = maxEnergyConsuption * averageCarbonIntensity;\r\n this.savedEmissons += maxEnergyEmisson - this.currentEnergyEmission;\r\n emissionsSavedLabel.setText(this.savedEmissons.toFixed(4) + ' gCO2');\r\n }\r\n\r\n /**\r\n * The calculations are based on the following paper: https://arxiv.org/pdf/2210.05444.pdf\r\n */\r\n calculateEnergyConsumption(fps: number, height: number, width: number, bitrate: number, duration: number): number {\r\n const fpsWeight = 0.035;\r\n const pixeldWeight = 5.76e-9;\r\n const birateWeight = 6.97e-6;\r\n const constantOffset = 8.52;\r\n const bitrateInternetWeight = 3.24e-5;\r\n const internetConnectionOffset = 1.15;\r\n const videoCodec = 4.16;\r\n\r\n const energyConsumptionW =\r\n fpsWeight * fps +\r\n pixeldWeight * height * width +\r\n (birateWeight + bitrateInternetWeight) * (bitrate / 1000) +\r\n videoCodec +\r\n constantOffset +\r\n internetConnectionOffset;\r\n\r\n // Convert energy consumption from Watts (W) to Kilowatt-hours (kWh) for the given time duration of the segment\r\n const energyConsumptionKwh = (energyConsumptionW * duration) / 3.6e6;\r\n\r\n return energyConsumptionKwh;\r\n }\r\n getMaxQualityAvailable(availableVideoQualities: VideoQuality[]) {\r\n const sortedQualities = availableVideoQualities.sort((a, b) => a.bitrate - b.bitrate);\r\n return sortedQualities[sortedQualities.length - 1];\r\n }\r\n}\r\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\r\nimport { UIInstanceManager } from '../uimanager';\r\nimport { DynamicAdaptationConfig, PlayerAPI, VideoQualityChangedEvent } from 'bitmovin-player';\r\nimport { i18n } from '../localization/i18n';\r\n\r\n/**\r\n * @category Buttons\r\n */\r\nexport class EcoModeToggleButton extends ToggleButton<ToggleButtonConfig> {\r\n private adaptationConfig: DynamicAdaptationConfig;\r\n\r\n constructor(config: ToggleButtonConfig = {}) {\r\n super(config);\r\n\r\n const defaultConfig: ToggleButtonConfig = {\r\n text: i18n.getLocalizer('ecoMode'),\r\n cssClass: 'ui-ecomodetogglebutton',\r\n onClass: 'on',\r\n offClass: 'off',\r\n ariaLabel: i18n.getLocalizer('ecoMode'),\r\n };\r\n\r\n this.config = this.mergeConfig(config, defaultConfig, this.config);\r\n }\r\n\r\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\r\n super.configure(player, uimanager);\r\n\r\n if (this.areAdaptationApisAvailable(player)) {\r\n this.onClick.subscribe(() => {\r\n this.toggle();\r\n });\r\n\r\n this.onToggleOn.subscribe(() => {\r\n this.enableEcoMode(player);\r\n player.setVideoQuality('auto');\r\n });\r\n\r\n this.onToggleOff.subscribe(() => {\r\n this.disableEcoMode(player);\r\n });\r\n\r\n player.on(player.exports.PlayerEvent.VideoQualityChanged, (quality: VideoQualityChangedEvent) => {\r\n if (quality.targetQuality.id !== 'auto') {\r\n this.off();\r\n this.disableEcoMode(player);\r\n }\r\n });\r\n } else {\r\n super.disable();\r\n }\r\n\r\n }\r\n\r\n private areAdaptationApisAvailable(player: PlayerAPI): boolean {\r\n const isGetConfigAvailable = Boolean(player.adaptation.getConfig && typeof player.adaptation.getConfig === 'function');\r\n const isSetConfigAvailable = Boolean(player.adaptation.setConfig && typeof player.adaptation.setConfig === 'function');\r\n\r\n return Boolean(player.adaptation && isGetConfigAvailable && isSetConfigAvailable);\r\n }\r\n\r\n enableEcoMode(player: PlayerAPI): void {\r\n this.adaptationConfig = player.adaptation.getConfig();\r\n const codec = player.getAvailableVideoQualities()[0].codec;\r\n\r\n if (codec.includes('avc')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 720 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n if (codec.includes('hvc') || codec.includes('hev')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 1080 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n if (codec.includes('av1') || codec.includes('av01')) {\r\n player.adaptation.setConfig({\r\n resolution: { maxSelectableVideoHeight: 1440 },\r\n limitToPlayerSize: true,\r\n });\r\n }\r\n }\r\n\r\n disableEcoMode(player: PlayerAPI): void {\r\n player.adaptation.setConfig(this.adaptationConfig);\r\n }\r\n}\r\n","import {ContainerConfig, Container} from './container';\nimport {Label, LabelConfig} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {TvNoiseCanvas} from './tvnoisecanvas';\nimport { ErrorUtils } from '../errorutils';\nimport { ErrorEvent, PlayerAPI, PlayerEventBase } from 'bitmovin-player';\nimport {\n isMobileV3PlayerAPI,\n MobileV3PlayerAPI, MobileV3PlayerErrorEvent, MobileV3PlayerEvent, MobileV3SourceErrorEvent,\n} from '../mobilev3playerapi';\n\nexport interface ErrorMessageTranslator {\n (error: ErrorEvent | MobileV3PlayerErrorEvent): string;\n}\n\nexport interface ErrorMessageMap {\n [code: number]: string | ErrorMessageTranslator;\n}\n\n/**\n * Configuration interface for the {@link ErrorMessageOverlay}.\n *\n * @category Configs\n */\nexport interface ErrorMessageOverlayConfig extends ContainerConfig {\n /**\n * Allows overwriting of the error messages displayed in the overlay for customization and localization.\n * This is either a function that receives any {@link ErrorEvent} as parameter and translates error messages,\n * or a map of error codes that overwrites specific error messages with a plain string or a function that\n * receives the {@link ErrorEvent} as parameter and returns a customized string.\n * The translation functions can be used to extract data (e.g. parameters) from the original error message.\n *\n * Example 1 (catch-all translation function):\n * <code>\n * errorMessageOverlayConfig = {\n * messages: function(error) {\n * switch (error.code) {\n * // Overwrite error 1000 'Unknown error'\n * case 1000:\n * return 'Houston, we have a problem'\n *\n * // Transform error 1201 'The downloaded manifest is invalid' to uppercase\n * case 1201:\n * var description = ErrorUtils.defaultErrorMessages[error.code];\n * return description.toUpperCase();\n *\n * // Customize error 1207 'The manifest could not be loaded'\n * case 1207:\n * var statusCode = error.data.statusCode;\n * return 'Manifest loading failed with HTTP error ' + statusCode;\n * }\n * // Return unmodified error message for all other errors\n * return error.message;\n * }\n * };\n * </code>\n *\n * Example 2 (translating specific errors):\n * <code>\n * errorMessageOverlayConfig = {\n * messages: {\n * // Overwrite error 1000 'Unknown error'\n * 1000: 'Houston, we have a problem',\n *\n * // Transform error 1201 'Unsupported manifest format' to uppercase\n * 1201: function(error) {\n * var description = ErrorUtils.defaultErrorMessages[error.code];\n * return description.toUpperCase();\n * },\n *\n * // Customize error 1207 'The manifest could not be loaded'\n * 1207: function(error) {\n * var statusCode = error.data.statusCode;\n * return 'Manifest loading failed with HTTP error ' + statusCode;\n * }\n * }\n * };\n * </code>\n */\n messages?: ErrorMessageMap | ErrorMessageTranslator;\n}\n\n/**\n * Overlays the player and displays error messages.\n *\n * @category Components\n */\nexport class ErrorMessageOverlay extends Container<ErrorMessageOverlayConfig> {\n\n private errorLabel: Label<LabelConfig>;\n private tvNoiseBackground: TvNoiseCanvas;\n\n constructor(config: ErrorMessageOverlayConfig = {}) {\n super(config);\n\n this.errorLabel = new Label<LabelConfig>({ cssClass: 'ui-errormessage-label' });\n this.tvNoiseBackground = new TvNoiseCanvas();\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-errormessage-overlay',\n components: [this.tvNoiseBackground, this.errorLabel],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI | MobileV3PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n const handleErrorMessage = (\n event: ErrorEvent | MobileV3SourceErrorEvent | MobileV3PlayerErrorEvent,\n message: string,\n ) => {\n const customizedMessage = customizeErrorMessage(uimanager.getConfig().errorMessages || config.messages, event);\n if (customizedMessage) {\n message = customizedMessage;\n }\n\n this.display(message);\n };\n\n if (isMobileV3PlayerAPI(player)) {\n const errorEventHandler = (event: MobileV3SourceErrorEvent | MobileV3PlayerErrorEvent) => {\n const message = ErrorUtils.defaultMobileV3ErrorMessageTranslator(event);\n handleErrorMessage(event, message);\n };\n\n player.on(MobileV3PlayerEvent.PlayerError, errorEventHandler);\n player.on(MobileV3PlayerEvent.SourceError, errorEventHandler);\n } else {\n player.on(player.exports.PlayerEvent.Error, (event: ErrorEvent) => {\n let message = ErrorUtils.defaultWebErrorMessageTranslator(event);\n handleErrorMessage(event, message);\n });\n }\n\n player.on(player.exports.PlayerEvent.SourceLoaded, (event: PlayerEventBase) => {\n if (this.isShown()) {\n this.tvNoiseBackground.stop();\n this.hide();\n }\n });\n }\n\n display(errorMessage: string): void {\n this.errorLabel.setText(errorMessage);\n this.tvNoiseBackground.start();\n this.show();\n }\n\n release(): void {\n super.release();\n\n // Canvas rendering must be explicitly stopped, else it just continues forever and hogs resources\n this.tvNoiseBackground.stop();\n }\n}\n\nfunction customizeErrorMessage(\n errorMessages: ErrorMessageTranslator | ErrorMessageMap,\n event: ErrorEvent | MobileV3PlayerErrorEvent | MobileV3SourceErrorEvent,\n): string | undefined {\n if (!errorMessages) {\n return undefined;\n }\n\n // Process message vocabularies\n if (typeof errorMessages === 'function') {\n // Translation function for all errors\n return errorMessages(event);\n }\n if (errorMessages[event.code]) {\n // It's not a translation function, so it must be a map of strings or translation functions\n const customMessage = errorMessages[event.code];\n\n return typeof customMessage === 'string' ? customMessage : customMessage(event);\n }\n}\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles the player between windowed and fullscreen view.\n *\n * @category Buttons\n */\nexport class FullscreenToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-fullscreentogglebutton',\n text: i18n.getLocalizer('fullscreen'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const isFullScreenAvailable = () => {\n return player.isViewModeAvailable(player.exports.ViewMode.Fullscreen);\n };\n\n const fullscreenStateHandler = () => {\n player.getViewMode() === player.exports.ViewMode.Fullscreen ? this.on() : this.off();\n };\n\n const fullscreenAvailabilityChangedHandler = () => {\n isFullScreenAvailable() ? this.show() : this.hide();\n };\n\n player.on(player.exports.PlayerEvent.ViewModeChanged, fullscreenStateHandler);\n\n // Available only in our native SDKs for now\n if ((player.exports.PlayerEvent as any).ViewModeAvailabilityChanged) {\n player.on(\n (player.exports.PlayerEvent as any).ViewModeAvailabilityChanged,\n fullscreenAvailabilityChangedHandler,\n );\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(fullscreenAvailabilityChangedHandler);\n\n this.onClick.subscribe(() => {\n if (!isFullScreenAvailable()) {\n if (console) {\n console.log('Fullscreen unavailable');\n }\n return;\n }\n\n const targetViewMode =\n player.getViewMode() === player.exports.ViewMode.Fullscreen\n ? player.exports.ViewMode.Inline\n : player.exports.ViewMode.Fullscreen;\n\n player.setViewMode(targetViewMode);\n });\n\n // Startup init\n fullscreenAvailabilityChangedHandler();\n fullscreenStateHandler();\n }\n}\n","import {PlaybackToggleButton, PlaybackToggleButtonConfig} from './playbacktogglebutton';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI, PlayerEventBase, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that overlays the video and toggles between playback and pause.\n *\n * @category Buttons\n */\nexport class HugePlaybackToggleButton extends PlaybackToggleButton {\n\n constructor(config: PlaybackToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-hugeplaybacktogglebutton',\n text: i18n.getLocalizer('playPause'),\n role: 'button',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // Update button state through API events\n super.configure(player, uimanager, false);\n\n // Set enterFullscreenOnInitialPlayback if set in the uimanager config\n if (typeof uimanager.getConfig().enterFullscreenOnInitialPlayback === 'boolean') {\n this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;\n }\n\n let togglePlayback = () => {\n if (player.isPlaying() || this.isPlayInitiated) {\n player.pause('ui');\n } else {\n player.play('ui');\n }\n };\n\n let toggleFullscreen = () => {\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n player.setViewMode(player.exports.ViewMode.Inline);\n } else {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n };\n\n let firstPlay = true;\n let clickTime = 0;\n let doubleClickTime = 0;\n\n /*\n * YouTube-style toggle button handling\n *\n * The goal is to prevent a short pause or playback interval between a click, that toggles playback, and a\n * double click, that toggles fullscreen. In this naive approach, the first click would e.g. start playback,\n * the second click would be detected as double click and toggle to fullscreen, and as second normal click stop\n * playback, which results is a short playback interval with max length of the double click detection\n * period (usually 500ms).\n *\n * To solve this issue, we defer handling of the first click for 200ms, which is almost unnoticeable to the user,\n * and just toggle playback if no second click (double click) has been registered during this period. If a double\n * click is registered, we just toggle the fullscreen. In the first 200ms, undesired playback changes thus cannot\n * happen. If a double click is registered within 500ms, we undo the playback change and switch fullscreen mode.\n * In the end, this method basically introduces a 200ms observing interval in which playback changes are prevented\n * if a double click happens.\n */\n this.onClick.subscribe(() => {\n // Directly start playback on first click of the button.\n // This is a required workaround for mobile browsers where video playback needs to be triggered directly\n // by the user. A deferred playback start through the timeout below is not considered as user action and\n // therefore ignored by mobile browsers.\n if (firstPlay) {\n // Try to start playback. Then we wait for Play and only when it arrives, we disable the firstPlay flag.\n // If we disable the flag here, onClick was triggered programmatically instead of by a user interaction, and\n // playback is blocked (e.g. on mobile devices due to the programmatic play() call), we loose the chance to\n // ever start playback through a user interaction again with this button.\n togglePlayback();\n\n if (this.config.enterFullscreenOnInitialPlayback) {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n\n return;\n }\n\n let now = Date.now();\n\n if (now - clickTime < 200) {\n // We have a double click inside the 200ms interval, just toggle fullscreen mode\n toggleFullscreen();\n doubleClickTime = now;\n return;\n } else if (now - clickTime < 500) {\n // We have a double click inside the 500ms interval, undo playback toggle and toggle fullscreen mode\n toggleFullscreen();\n togglePlayback();\n doubleClickTime = now;\n return;\n }\n\n clickTime = now;\n\n setTimeout(() => {\n if (Date.now() - doubleClickTime > 200) {\n // No double click detected, so we toggle playback and wait what happens next\n togglePlayback();\n }\n }, 200);\n });\n\n player.on(player.exports.PlayerEvent.Play, () => {\n // Playback has really started, we can disable the flag to switch to normal toggle button handling\n firstPlay = false;\n });\n\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n // if playback could not be started, reset the first play flag as we need the user interaction to start\n firstPlay = true;\n }\n });\n\n const suppressPlayButtonTransitionAnimation = () => {\n // Disable the current animation\n this.setTransitionAnimationsEnabled(false);\n\n // Enable the transition animations for the next state change\n this.onToggle.subscribeOnce(() => {\n this.setTransitionAnimationsEnabled(true);\n });\n };\n\n // Hide the play button animation when the UI is loaded (it should only be animated on state changes)\n suppressPlayButtonTransitionAnimation();\n\n const isAutoplayEnabled = player.getConfig().playback && Boolean(player.getConfig().playback.autoplay);\n // We only know if an autoplay attempt is upcoming if the player is not yet ready. It the player is already ready,\n // the attempt might be upcoming or might have already happened, but we don't have to handle that because we can\n // simply rely on isPlaying and the play state events.\n const isAutoplayUpcoming = !player.getSource() && isAutoplayEnabled;\n\n // Hide the play button when the player is already playing or autoplay is upcoming\n if (player.isPlaying() || isAutoplayUpcoming) {\n // Hide the play button (switch to playing state)\n this.on();\n // Disable the animation of the playing state switch\n suppressPlayButtonTransitionAnimation();\n\n // Show the play button without an animation if a play attempt is blocked\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n suppressPlayButtonTransitionAnimation();\n }\n });\n }\n }\n\n protected toDomElement(): DOM {\n let buttonElement = super.toDomElement();\n\n // Add child that contains the play button image\n // Setting the image directly on the button does not work together with scaling animations, because the button\n // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined\n // to the size if the image, it can scale inside the player without overshooting.\n buttonElement.append(new DOM('div', {\n 'class': this.prefixCss('image'),\n }));\n\n return buttonElement;\n }\n\n /**\n * Enables or disables the play state transition animations of the play button image. Can be used to suppress\n * animations.\n * @param {boolean} enabled true to enable the animations (default), false to disable them\n */\n protected setTransitionAnimationsEnabled(enabled: boolean): void {\n const noTransitionAnimationsClass = this.prefixCss('no-transition-animations');\n\n if (enabled) {\n this.getDomElement().removeClass(noTransitionAnimationsClass);\n } else if (!this.getDomElement().hasClass(noTransitionAnimationsClass)) {\n this.getDomElement().addClass(noTransitionAnimationsClass);\n }\n }\n}\n","import {ButtonConfig, Button} from './button';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button to play/replay a video.\n *\n * @category Buttons\n */\nexport class HugeReplayButton extends Button<ButtonConfig> {\n\n constructor(config: ButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-hugereplaybutton',\n text: i18n.getLocalizer('replay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n player.play('ui');\n });\n }\n\n protected toDomElement(): DOM {\n let buttonElement = super.toDomElement();\n\n // Add child that contains the play button image\n // Setting the image directly on the button does not work together with scaling animations, because the button\n // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined\n // to the size if the image, it can scale inside the player without overshooting.\n buttonElement.append(new DOM('div', {\n 'class': this.prefixCss('image'),\n }));\n\n return buttonElement;\n }\n}","import {ListSelector, ListSelectorConfig} from './listselector';\nimport {DOM} from '../dom';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Components\n */\nexport class ItemSelectionList extends ListSelector<ListSelectorConfig> {\n\n private static readonly CLASS_SELECTED = 'selected';\n\n private listElement: DOM;\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n tag: 'ul',\n cssClass: 'ui-itemselectionlist',\n }, this.config);\n }\n\n protected isActive(): boolean {\n return this.items.length > 1;\n }\n\n protected toDomElement(): DOM {\n let listElement = new DOM('ul', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n }, this);\n\n this.listElement = listElement;\n this.updateDomItems();\n\n return listElement;\n }\n\n protected updateDomItems(selectedValue: string = null) {\n // Delete all children\n this.listElement.empty();\n\n let selectedListItem: DOM = null;\n\n const selectItem = (listItem: DOM) => {\n listItem.addClass(this.prefixCss(ItemSelectionList.CLASS_SELECTED));\n };\n\n const deselectItem = (listItem: DOM) => {\n listItem.removeClass(this.prefixCss(ItemSelectionList.CLASS_SELECTED));\n };\n\n for (let item of this.items) {\n let listItem = new DOM('li', {\n 'type': 'li',\n 'class': this.prefixCss('ui-selectionlistitem'),\n }).append(new DOM('a', {\n }).html(i18n.performLocalization(item.label)));\n\n if (!selectedListItem) {\n if (selectedValue == null) { // If there is no pre-selected value, select the first one\n selectedListItem = listItem;\n } else if (String(selectedValue) === item.key) { // convert selectedValue to string to catch 'null'/null case\n selectedListItem = listItem;\n }\n }\n\n // Handle list item selections\n listItem.on('click', () => {\n // Deselect the previous item (if there was a selected item)\n if (selectedListItem) {\n deselectItem(selectedListItem);\n }\n\n // Select the clicked item\n selectedListItem = listItem;\n selectItem(listItem);\n\n // Fire the event\n this.onItemSelectedEvent(item.key, false);\n });\n\n // Select default item\n if (selectedListItem) {\n selectItem(selectedListItem);\n }\n\n this.listElement.append(listItem);\n }\n }\n\n protected onItemAddedEvent(value: string) {\n super.onItemAddedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemRemovedEvent(value: string) {\n super.onItemRemovedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemSelectedEvent(value: string, updateDomItems: boolean = true) {\n super.onItemSelectedEvent(value);\n if (updateDomItems) {\n this.updateDomItems(value);\n }\n }\n}\n","import {ComponentConfig, Component} from './component';\nimport {DOM} from '../dom';\nimport {EventDispatcher, Event, NoArgs} from '../eventdispatcher';\nimport { LocalizableText, i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link Label} component.\n *\n * @category Configs\n */\nexport interface LabelConfig extends ComponentConfig {\n /**\n * The text as string or localize callback on the label.\n */\n text?: LocalizableText;\n\n /**\n * WCAG20 standard: Associate label to form control.\n */\n for?: string;\n}\n\n/**\n * A simple text label.\n *\n * DOM example:\n * <code>\n * <span class='ui-label'>...some text...</span>\n * </code>\n *\n * @category Components\n */\nexport class Label<Config extends LabelConfig> extends Component<Config> {\n\n private text: LocalizableText;\n\n private labelEvents = {\n onClick: new EventDispatcher<Label<Config>, NoArgs>(),\n onTextChanged: new EventDispatcher<Label<Config>, string>(),\n };\n\n constructor(config: Config = {} as Config) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-label',\n } as Config, this.config);\n this.text = this.config.text;\n }\n\n protected toDomElement(): DOM {\n const tagName = this.config.for != null ? 'label' : 'span';\n\n let labelElement = new DOM(tagName, {\n 'id': this.config.id,\n 'for': this.config.for,\n 'class': this.getCssClasses(),\n }, this).html(i18n.performLocalization(this.text));\n\n labelElement.on('click', () => {\n this.onClickEvent();\n });\n\n return labelElement;\n }\n\n /**\n * Set the text on this label.\n * @param text\n */\n setText(text: LocalizableText) {\n if (text === this.text) {\n return;\n }\n\n this.text = text;\n const localizedText = i18n.performLocalization(text);\n this.getDomElement().html(localizedText);\n this.onTextChangedEvent(localizedText);\n }\n\n /**\n * Gets the text on this label.\n * @return {string} The text on the label\n */\n getText(): string {\n return i18n.performLocalization(this.text);\n }\n\n /**\n * Clears the text on this label.\n */\n clearText() {\n this.getDomElement().html('');\n this.onTextChangedEvent(null);\n }\n\n /**\n * Tests if the label is empty and does not contain any text.\n * @return {boolean} True if the label is empty, else false\n */\n isEmpty(): boolean {\n return !this.text;\n }\n\n /**\n * Fires the {@link #onClick} event.\n * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method\n * and calling the super method.\n */\n protected onClickEvent() {\n this.labelEvents.onClick.dispatch(this);\n }\n\n /**\n * Fires the {@link #onClick} event.\n * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method\n * and calling the super method.\n */\n protected onTextChangedEvent(text: string) {\n this.labelEvents.onTextChanged.dispatch(this, text);\n }\n\n /**\n * Gets the event that is fired when the label is clicked.\n * @returns {Event<Label<LabelConfig>, NoArgs>}\n */\n get onClick(): Event<Label<LabelConfig>, NoArgs> {\n return this.labelEvents.onClick.getEvent();\n }\n\n /**\n * Gets the event that is fired when the text on the label is changed.\n * @returns {Event<Label<LabelConfig>, string>}\n */\n get onTextChanged(): Event<Label<LabelConfig>, string> {\n return this.labelEvents.onTextChanged.getEvent();\n }\n}\n","import { ToggleButton, ToggleButtonConfig } from './togglebutton';\nimport { ListItem, ListSelector, ListSelectorConfig } from './listselector';\nimport {DOM} from '../dom';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { ArrayUtils } from '../arrayutils';\n\n/**\n * A element to select a single item out of a list of available items.\n *\n * DOM example:\n * <code>\n * <div class='ui-listbox'>\n * <button class='ui-listbox-button'>label</button>\n * ...\n * </div\n * </code>\n *\n * @category Components\n */\n// TODO: change ListSelector to extends container in v4 to improve usage of ListBox.\n// Currently we are creating the dom element of the list box with child elements manually here.\n// But this functionality is already covered within the Container component.\nexport class ListBox extends ListSelector<ListSelectorConfig> {\n private listBoxElement: DOM;\n private components: ListBoxItemButton[] = [];\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-listbox',\n } as ListSelectorConfig, this.config);\n }\n\n public configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // Subscribe before super call to receive initial events\n this.onItemAdded.subscribe(this.addListBoxDomItem);\n this.onItemRemoved.subscribe(this.removeListBoxDomItem);\n this.onItemSelected.subscribe(this.refreshSelectedItem);\n\n super.configure(player, uimanager);\n }\n\n protected toDomElement(): DOM {\n let listBoxElement = new DOM('div', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n }, this);\n\n this.listBoxElement = listBoxElement;\n this.createListBoxDomItems();\n this.refreshSelectedItem();\n\n return listBoxElement;\n }\n\n private createListBoxDomItems() {\n // Delete all children\n this.listBoxElement.empty();\n this.components = [];\n\n // Add updated children\n for (let item of this.items) {\n this.addListBoxDomItem(this, item.key);\n }\n }\n\n private removeListBoxDomItem = (_: ListBox, key: string) => {\n const component = this.getComponentForKey(key);\n if (component) {\n component.getDomElement().remove();\n ArrayUtils.remove(this.components, component);\n }\n };\n\n private addListBoxDomItem = (_: ListBox, key: string) => {\n const component = this.getComponentForKey(key);\n const newItem = this.getItemForKey(key);\n if (component) {\n // Update existing component\n component.setText(newItem.label);\n } else {\n const listBoxItemButton = this.buildListBoxItemButton(newItem);\n\n listBoxItemButton.onClick.subscribe(() => {\n this.handleSelectionChange(listBoxItemButton);\n });\n\n this.components.push(listBoxItemButton);\n this.listBoxElement.append(listBoxItemButton.getDomElement());\n }\n };\n\n private refreshSelectedItem = () => {\n // This gets called twice because the first time is triggered when the user clicks on the ListBoxItemButton. And the\n // second call comes from the player event when the actual item is selected (Subtitle / AudioTrack in this case).\n // As this is a generic component we can't prohibit this behaviour. We need to treat this component as it acts\n // independent from PlayerEvents and on the other hand we need to react to PlayerEvents as it could be triggered\n // from outside.\n\n for (let item of this.items) {\n const component = this.getComponentForKey(item.key);\n if (component) {\n String(component.key) === String(this.selectedItem) ? component.on() : component.off();\n }\n }\n };\n\n private buildListBoxItemButton(listItem: ListItem): ListBoxItemButton {\n return new ListBoxItemButton({\n key: listItem.key,\n text: listItem.label,\n ariaLabel: listItem.ariaLabel,\n });\n }\n\n private getComponentForKey(key: string): ListBoxItemButton {\n return this.components.find((c) => key === c.key);\n }\n\n private handleSelectionChange = (sender: ListBoxItemButton) => {\n this.onItemSelectedEvent(sender.key);\n };\n}\n\ninterface ListBoxItemButtonConfig extends ToggleButtonConfig {\n /**\n * key to identify selected item. Similar to the value attribute of an select option.\n */\n key: string;\n}\n\nclass ListBoxItemButton extends ToggleButton<ListBoxItemButtonConfig> {\n\n constructor(config: ListBoxItemButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-listbox-button',\n onClass: 'selected',\n offClass: '',\n } as ListBoxItemButtonConfig, this.config);\n }\n\n get key(): string {\n return (this.config as ListBoxItemButtonConfig).key;\n }\n}\n","import {Component, ComponentConfig} from './component';\nimport {EventDispatcher, Event} from '../eventdispatcher';\nimport {ArrayUtils} from '../arrayutils';\nimport { LocalizableText, i18n } from '../localization/i18n';\n\n/**\n * A map of items (key/value -> label} for a {@link ListSelector} in a {@link ListSelectorConfig}.\n */\nexport interface ListItem {\n key: string;\n label: LocalizableText;\n sortedInsert?: boolean;\n ariaLabel?: string;\n}\n\n/**\n * Filter function that can be used to filter out list items added through {@link ListSelector.addItem}.\n *\n * This is intended to be used in conjunction with subclasses that populate themselves automatically\n * via the player API, e.g. {@link SubtitleSelectBox}.\n */\nexport interface ListItemFilter {\n /**\n * Takes a list item and decides whether it should pass or be discarded.\n * @param {ListItem} listItem the item to apply the filter to\n * @returns {boolean} true to let the item pass through the filter, false to discard the item\n */\n (listItem: ListItem): boolean;\n}\n\n/**\n * Translator function to translate labels of list items added through {@link ListSelector.addItem}.\n *\n * This is intended to be used in conjunction with subclasses that populate themselves automatically\n * via the player API, e.g. {@link SubtitleSelectBox}.\n */\nexport interface ListItemLabelTranslator {\n /**\n * Takes a list item, optionally changes the label, and returns the new label.\n * @param {ListItem} listItem the item to translate\n * @returns {string} the translated or original label\n */\n (listItem: ListItem): string;\n}\n\n/**\n * Configuration interface for a {@link ListSelector}.\n *\n * @category Configs\n */\nexport interface ListSelectorConfig extends ComponentConfig {\n items?: ListItem[];\n filter?: ListItemFilter;\n translator?: ListItemLabelTranslator;\n}\n\nexport abstract class ListSelector<Config extends ListSelectorConfig> extends Component<ListSelectorConfig> {\n\n protected items: ListItem[];\n protected selectedItem: string;\n\n private listSelectorEvents = {\n onItemAdded: new EventDispatcher<ListSelector<Config>, string>(),\n onItemRemoved: new EventDispatcher<ListSelector<Config>, string>(),\n onItemSelected: new EventDispatcher<ListSelector<Config>, string>(),\n };\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n items: [],\n cssClass: 'ui-listselector',\n }, this.config);\n\n this.items = this.config.items;\n }\n\n private getItemIndex(key: string): number {\n for (let i = 0; i < this.items.length; i++) {\n if (this.items[i].key === key) {\n return i;\n }\n }\n\n return -1;\n }\n\n /**\n * Returns all current items of this selector.\n * * @returns {ListItem[]}\n */\n getItems(): ListItem[] {\n return this.items;\n }\n\n /**\n * Checks if the specified item is part of this selector.\n * @param key the key of the item to check\n * @returns {boolean} true if the item is part of this selector, else false\n */\n hasItem(key: string): boolean {\n return this.getItemIndex(key) > -1;\n }\n\n /**\n * Adds an item to this selector by doing a sorted insert or by appending the element to the end of the list of items.\n * If an item with the specified key already exists, it is replaced.\n * @param key the key of the item to add\n * @param label the (human-readable) label of the item to add\n * @param sortedInsert whether the item should be added respecting the order of keys\n * @param ariaLabel custom aria label for the listItem\n */\n addItem(key: string, label: LocalizableText, sortedInsert = false, ariaLabel = '') {\n const listItem = { key: key, label: i18n.performLocalization(label), ...(ariaLabel && { ariaLabel })};\n\n // Apply filter function\n if (this.config.filter && !this.config.filter(listItem)) {\n return;\n }\n\n // Apply translator function\n if (this.config.translator) {\n listItem.label = this.config.translator(listItem);\n }\n\n // Try to remove key first to get overwrite behavior and avoid duplicate keys\n this.removeItem(key); // This will trigger an ItemRemoved and an ItemAdded event\n\n // Add the item to the list\n if (sortedInsert) {\n const index = this.items.findIndex(entry => entry.key > key);\n if (index < 0) {\n this.items.push(listItem);\n } else {\n this.items.splice(index, 0, listItem);\n }\n } else {\n this.items.push(listItem);\n }\n this.onItemAddedEvent(key);\n }\n\n /**\n * Removes an item from this selector.\n * @param key the key of the item to remove\n * @returns {boolean} true if removal was successful, false if the item is not part of this selector\n */\n removeItem(key: string): boolean {\n let index = this.getItemIndex(key);\n if (index > -1) {\n ArrayUtils.remove(this.items, this.items[index]);\n this.onItemRemovedEvent(key);\n return true;\n }\n\n return false;\n }\n\n /**\n * Selects an item from the items in this selector.\n * @param key the key of the item to select\n * @returns {boolean} true is the selection was successful, false if the selected item is not part of the selector\n */\n selectItem(key: string): boolean {\n if (key === this.selectedItem) {\n // itemConfig is already selected, suppress any further action\n return true;\n }\n\n let index = this.getItemIndex(key);\n\n if (index > -1) {\n this.selectedItem = key;\n this.onItemSelectedEvent(key);\n return true;\n }\n\n return false;\n }\n\n /**\n * Returns the key of the selected item.\n * @returns {string} the key of the selected item or null if no item is selected\n */\n getSelectedItem(): string | null {\n return this.selectedItem;\n }\n\n /**\n * Returns the items for the given key or undefined if no item with the given key exists.\n * @param key the key of the item to return\n * @returns {ListItem} the item with the requested key. Undefined if no item with the given key exists.\n */\n getItemForKey(key: string): ListItem {\n return this.items.find((item) => item.key === key);\n }\n\n /**\n * Synchronize the current items of this selector with the given ones. This will remove and add items selectively.\n * For each removed item the ItemRemovedEvent and for each added item the ItemAddedEvent will be triggered. Favour\n * this method over using clearItems and adding all items again afterwards.\n * @param newItems\n */\n synchronizeItems(newItems: ListItem[]): void {\n newItems\n .filter((item) => !this.hasItem(item.key))\n .forEach((item) => this.addItem(item.key, item.label, item.sortedInsert, item.ariaLabel));\n\n this.items\n .filter((item) => newItems.filter((i) => i.key === item.key).length === 0)\n .forEach((item) => this.removeItem(item.key));\n }\n\n /**\n * Removes all items from this selector.\n */\n clearItems() {\n // local copy for iteration after clear\n let items = this.items;\n // clear items\n this.items = [];\n\n // clear the selection as the selected item is also removed\n this.selectedItem = null;\n\n // fire events\n for (let item of items) {\n this.onItemRemovedEvent(item.key);\n }\n }\n\n /**\n * Returns the number of items in this selector.\n * @returns {number}\n */\n itemCount(): number {\n return Object.keys(this.items).length;\n }\n\n protected onItemAddedEvent(key: string) {\n this.listSelectorEvents.onItemAdded.dispatch(this, key);\n }\n\n protected onItemRemovedEvent(key: string) {\n this.listSelectorEvents.onItemRemoved.dispatch(this, key);\n }\n\n protected onItemSelectedEvent(key: string) {\n this.listSelectorEvents.onItemSelected.dispatch(this, key);\n }\n\n /**\n * Gets the event that is fired when an item is added to the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemAdded(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemAdded.getEvent();\n }\n\n /**\n * Gets the event that is fired when an item is removed from the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemRemoved(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemRemoved.getEvent();\n }\n\n /**\n * Gets the event that is fired when an item is selected from the list of items.\n * @returns {Event<ListSelector<Config>, string>}\n */\n get onItemSelected(): Event<ListSelector<Config>, string> {\n return this.listSelectorEvents.onItemSelected.getEvent();\n }\n}","import {LabelConfig, Label} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Enumerates the types of content that the {@link MetadataLabel} can display.\n */\nexport enum MetadataLabelContent {\n /**\n * Title of the data source.\n */\n Title,\n /**\n * Description fo the data source.\n */\n Description,\n}\n\n/**\n * Configuration interface for {@link MetadataLabel}.\n *\n * @category Configs\n */\nexport interface MetadataLabelConfig extends LabelConfig {\n /**\n * The type of content that should be displayed in the label.\n */\n content: MetadataLabelContent;\n}\n\n/**\n * A label that can be configured to display certain metadata.\n *\n * @category Labels\n */\nexport class MetadataLabel extends Label<MetadataLabelConfig> {\n\n constructor(config: MetadataLabelConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['label-metadata', 'label-metadata-' + MetadataLabelContent[config.content].toLowerCase()],\n } as MetadataLabelConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let uiconfig = uimanager.getConfig();\n\n let init = () => {\n switch (config.content) {\n case MetadataLabelContent.Title:\n this.setText(uiconfig.metadata.title);\n break;\n case MetadataLabelContent.Description:\n this.setText(uiconfig.metadata.description);\n break;\n }\n };\n\n let unload = () => {\n this.setText(null);\n };\n\n // Init label\n init();\n // Clear labels when source is unloaded\n player.on(player.exports.PlayerEvent.SourceUnloaded, unload);\n\n uimanager.getConfig().events.onUpdated.subscribe(init);\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles Apple macOS picture-in-picture mode.\n *\n * @category Buttons\n */\nexport class PictureInPictureToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-piptogglebutton',\n text: i18n.getLocalizer('pictureInPicture'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const isPictureInPictureAvailable = () => {\n return player.isViewModeAvailable(player.exports.ViewMode.PictureInPicture);\n };\n\n const pictureInPictureStateHandler = () => {\n player.getViewMode() === player.exports.ViewMode.PictureInPicture ? this.on() : this.off();\n };\n\n const pictureInPictureAvailabilityChangedHandler = () => {\n isPictureInPictureAvailable() ? this.show() : this.hide();\n };\n\n player.on(player.exports.PlayerEvent.ViewModeChanged, pictureInPictureStateHandler);\n\n // Available only in our native SDKs for now\n if ((player.exports.PlayerEvent as any).ViewModeAvailabilityChanged) {\n player.on(\n (player.exports.PlayerEvent as any).ViewModeAvailabilityChanged,\n pictureInPictureAvailabilityChangedHandler,\n );\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(pictureInPictureAvailabilityChangedHandler);\n\n this.onClick.subscribe(() => {\n if (!isPictureInPictureAvailable()) {\n if (console) {\n console.log('PIP unavailable');\n }\n return;\n }\n\n const targetViewMode =\n player.getViewMode() === player.exports.ViewMode.PictureInPicture\n ? player.exports.ViewMode.Inline\n : player.exports.ViewMode.PictureInPicture;\n\n player.setViewMode(targetViewMode);\n });\n\n // Startup init\n pictureInPictureAvailabilityChangedHandler(); // Hide button if PIP not available\n pictureInPictureStateHandler();\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection of different playback speeds.\n *\n * @category Components\n */\nexport class PlaybackSpeedSelectBox extends SelectBox {\n protected defaultPlaybackSpeeds: number[];\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n this.defaultPlaybackSpeeds = [0.25, 0.5, 1, 1.5, 2];\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-playbackspeedselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addDefaultItems();\n\n this.onItemSelected.subscribe((sender: PlaybackSpeedSelectBox, value: string) => {\n player.setPlaybackSpeed(parseFloat(value));\n this.selectItem(value);\n });\n\n const setDefaultValue = (): void => {\n const playbackSpeed = player.getPlaybackSpeed();\n this.setSpeed(playbackSpeed);\n };\n\n player.on(player.exports.PlayerEvent.PlaybackSpeedChanged, setDefaultValue);\n uimanager.getConfig().events.onUpdated.subscribe(setDefaultValue);\n }\n\n setSpeed(speed: number): void {\n if (!this.selectItem(String(speed))) {\n // a playback speed was set which is not in the list, add it to the list to show it to the user\n this.clearItems();\n this.addDefaultItems([speed]);\n this.selectItem(String(speed));\n }\n }\n\n addDefaultItems(customItems: number[] = []): void {\n const sortedSpeeds = this.defaultPlaybackSpeeds.concat(customItems).sort();\n\n sortedSpeeds.forEach(element => {\n if (element !== 1) {\n this.addItem(String(element), `${element}x`);\n } else {\n this.addItem(String(element), i18n.getLocalizer('normal'));\n }\n });\n }\n\n clearItems(): void {\n this.items = [];\n this.selectedItem = null;\n }\n}","import {LabelConfig, Label} from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\nimport {PlayerUtils} from '../playerutils';\nimport {StringUtils} from '../stringutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\nexport enum PlaybackTimeLabelMode {\n /**\n * Displays the current time\n */\n CurrentTime,\n /**\n * Displays the duration of the content\n */\n TotalTime,\n /**\n * Displays the current time and the duration of the content\n * Format: ${currentTime} / ${totalTime}\n */\n CurrentAndTotalTime,\n /**\n * Displays the remaining time of the content\n */\n RemainingTime,\n}\n\n/**\n * @category Configs\n */\nexport interface PlaybackTimeLabelConfig extends LabelConfig {\n /**\n * The type of which time should be displayed in the label.\n * Default: PlaybackTimeLabelMode.CurrentAndTotalTime\n */\n timeLabelMode?: PlaybackTimeLabelMode;\n /**\n * Boolean if the label should be hidden in live playback\n */\n hideInLivePlayback?: boolean;\n}\n\n/**\n * A label that display the current playback time and the total time through {@link PlaybackTimeLabel#setTime setTime}\n * or any string through {@link PlaybackTimeLabel#setText setText}.\n *\n * @category Labels\n */\nexport class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {\n\n private timeFormat: string;\n\n constructor(config: PlaybackTimeLabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <PlaybackTimeLabelConfig>{\n cssClass: 'ui-playbacktimelabel',\n timeLabelMode: PlaybackTimeLabelMode.CurrentAndTotalTime,\n hideInLivePlayback: false,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let live = false;\n let liveCssClass = this.prefixCss('ui-playbacktimelabel-live');\n let liveEdgeCssClass = this.prefixCss('ui-playbacktimelabel-live-edge');\n let minWidth = 0;\n\n let liveClickHandler = () => {\n player.timeShift(0);\n };\n\n let updateLiveState = () => {\n // Player is playing a live stream when the duration is infinite\n live = player.isLive();\n\n // Attach/detach live marker class\n if (live) {\n this.getDomElement().addClass(liveCssClass);\n this.setText(i18n.getLocalizer('live'));\n if (config.hideInLivePlayback) {\n this.hide();\n }\n this.onClick.subscribe(liveClickHandler);\n updateLiveTimeshiftState();\n } else {\n this.getDomElement().removeClass(liveCssClass);\n this.getDomElement().removeClass(liveEdgeCssClass);\n this.show();\n this.onClick.unsubscribe(liveClickHandler);\n }\n };\n\n let updateLiveTimeshiftState = () => {\n if (!live) {\n return;\n }\n\n // The player is only at the live edge iff the stream is not shifted and it is actually playing or playback has\n // never been started (meaning it isn't paused). A player that is paused is always behind the live edge.\n // An exception is made for live streams without a timeshift window, because here we \"stop\" playback instead\n // of pausing it (from a UI perspective), so we keep the live edge indicator on because a play would always\n // resume at the live edge.\n const isTimeshifted = player.getTimeShift() < 0;\n const isTimeshiftAvailable = player.getMaxTimeShift() < 0;\n if (!isTimeshifted && (!player.isPaused() || !isTimeshiftAvailable)) {\n this.getDomElement().addClass(liveEdgeCssClass);\n } else {\n this.getDomElement().removeClass(liveEdgeCssClass);\n }\n };\n\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n live = args.live;\n updateLiveState();\n });\n liveStreamDetector.detect(); // Initial detection\n\n let playbackTimeHandler = () => {\n if (!live && player.getDuration() !== Infinity) {\n this.setTime(\n PlayerUtils.getCurrentTimeRelativeToSeekableRange(player),\n player.getDuration());\n }\n\n // To avoid 'jumping' in the UI by varying label sizes due to non-monospaced fonts,\n // we gradually increase the min-width with the content to reach a stable size.\n let width = this.getDomElement().width();\n if (width > minWidth) {\n minWidth = width;\n this.getDomElement().css({\n 'min-width': minWidth + 'px',\n });\n }\n };\n\n let updateTimeFormatBasedOnDuration = () => {\n // Set time format depending on source duration\n this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ?\n StringUtils.FORMAT_HHMMSS : StringUtils.FORMAT_MMSS;\n playbackTimeHandler();\n };\n\n player.on(player.exports.PlayerEvent.TimeChanged, playbackTimeHandler);\n player.on(player.exports.PlayerEvent.Ready, updateTimeFormatBasedOnDuration);\n player.on(player.exports.PlayerEvent.Seeked, playbackTimeHandler);\n\n player.on(player.exports.PlayerEvent.TimeShift, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.TimeShifted, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.Playing, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.Paused, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.StallStarted, updateLiveTimeshiftState);\n player.on(player.exports.PlayerEvent.StallEnded, updateLiveTimeshiftState);\n\n let init = () => {\n // Reset min-width when a new source is ready (especially for switching VOD/Live modes where the label content\n // changes)\n minWidth = 0;\n this.getDomElement().css({\n 'min-width': null,\n });\n\n updateTimeFormatBasedOnDuration();\n };\n uimanager.getConfig().events.onUpdated.subscribe(init);\n\n init();\n }\n\n /**\n * Sets the current playback time and total duration.\n * @param playbackSeconds the current playback time in seconds\n * @param durationSeconds the total duration in seconds\n */\n setTime(playbackSeconds: number, durationSeconds: number) {\n let currentTime = StringUtils.secondsToTime(playbackSeconds, this.timeFormat);\n let totalTime = StringUtils.secondsToTime(durationSeconds, this.timeFormat);\n\n switch ((<PlaybackTimeLabelConfig>this.config).timeLabelMode) {\n case PlaybackTimeLabelMode.CurrentTime:\n this.setText(`${currentTime}`);\n break;\n case PlaybackTimeLabelMode.TotalTime:\n this.setText(`${totalTime}`);\n break;\n case PlaybackTimeLabelMode.CurrentAndTotalTime:\n this.setText(`${currentTime} / ${totalTime}`);\n break;\n case PlaybackTimeLabelMode.RemainingTime:\n this.setText(`${StringUtils.secondsToTime(durationSeconds - playbackSeconds, this.timeFormat)}`);\n break;\n }\n }\n\n /**\n * Sets the current time format\n * @param timeFormat the time format\n */\n protected setTimeFormat(timeFormat: string): void {\n this.timeFormat = timeFormat;\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport {PlayerUtils} from '../playerutils';\nimport { PlayerAPI, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface PlaybackToggleButtonConfig extends ToggleButtonConfig {\n /**\n * Specify whether the player should be set to enter fullscreen by clicking on the playback toggle button\n * when initiating the initial playback.\n * Default is false.\n */\n enterFullscreenOnInitialPlayback?: boolean;\n}\n\n/**\n * A button that toggles between playback and pause.\n *\n * @category Buttons\n */\nexport class PlaybackToggleButton extends ToggleButton<PlaybackToggleButtonConfig> {\n\n private static readonly CLASS_STOPTOGGLE = 'stoptoggle';\n protected isPlayInitiated: boolean;\n\n constructor(config: PlaybackToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-playbacktogglebutton',\n text: i18n.getLocalizer('play'),\n onAriaLabel: i18n.getLocalizer('pause'),\n offAriaLabel: i18n.getLocalizer('play'),\n }, this.config);\n\n this.isPlayInitiated = false;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager, handleClickEvent: boolean = true): void {\n super.configure(player, uimanager);\n\n // Set enterFullscreenOnInitialPlayback if set in the uimanager config\n if (typeof uimanager.getConfig().enterFullscreenOnInitialPlayback === 'boolean') {\n this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;\n }\n\n let isSeeking = false;\n let firstPlay = true;\n\n // Handler to update button state based on player state\n let playbackStateHandler = () => {\n // If the UI is currently seeking, playback is temporarily stopped but the buttons should\n // not reflect that and stay as-is (e.g indicate playback while seeking).\n if (isSeeking) {\n return;\n }\n\n if (player.isPlaying() || this.isPlayInitiated) {\n this.on();\n } else {\n this.off();\n }\n };\n\n // Call handler upon these events\n player.on(player.exports.PlayerEvent.Play, (e) => {\n this.isPlayInitiated = true;\n firstPlay = false;\n playbackStateHandler();\n });\n\n player.on(player.exports.PlayerEvent.Paused, (e) => {\n this.isPlayInitiated = false;\n playbackStateHandler();\n });\n\n player.on(player.exports.PlayerEvent.Playing, (e) => {\n this.isPlayInitiated = false;\n playbackStateHandler();\n });\n // after unloading + loading a new source, the player might be in a different playing state (from playing into stopped)\n player.on(player.exports.PlayerEvent.SourceLoaded, playbackStateHandler);\n uimanager.getConfig().events.onUpdated.subscribe(playbackStateHandler);\n player.on(player.exports.PlayerEvent.SourceUnloaded, playbackStateHandler);\n // when playback finishes, player turns to paused mode\n player.on(player.exports.PlayerEvent.PlaybackFinished, playbackStateHandler);\n player.on(player.exports.PlayerEvent.CastStarted, playbackStateHandler);\n\n // When a playback attempt is rejected with warning 5008, we switch the button state back to off\n // This is required for blocked autoplay, because there is no Paused event in such case\n player.on(player.exports.PlayerEvent.Warning, (event: WarningEvent) => {\n if (event.code === player.exports.WarningCode.PLAYBACK_COULD_NOT_BE_STARTED) {\n this.isPlayInitiated = false;\n firstPlay = true;\n this.off();\n }\n });\n\n const updateLiveState = () => {\n const showStopToggle = player.isLive() && !PlayerUtils.isTimeShiftAvailable(player);\n\n if (showStopToggle) {\n this.getDomElement().addClass(this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE));\n } else {\n this.getDomElement().removeClass(this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE));\n }\n };\n\n // Detect absence of timeshifting on live streams and add tagging class to convert button icons to play/stop\n let timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(() => updateLiveState());\n liveStreamDetector.onLiveChanged.subscribe(() => updateLiveState());\n\n timeShiftDetector.detect(); // Initial detection\n liveStreamDetector.detect();\n\n if (handleClickEvent) {\n // Control player by button events\n // When a button event triggers a player API call, events are fired which in turn call the event handler\n // above that updated the button state.\n this.onClick.subscribe(() => {\n if (player.isPlaying() || this.isPlayInitiated) {\n player.pause('ui');\n } else {\n player.play('ui');\n\n if (firstPlay && this.config.enterFullscreenOnInitialPlayback) {\n player.setViewMode(player.exports.ViewMode.Fullscreen);\n }\n }\n });\n }\n\n // Track UI seeking status\n uimanager.onSeek.subscribe(() => {\n isSeeking = true;\n });\n uimanager.onSeeked.subscribe(() => {\n isSeeking = false;\n });\n\n // Startup init\n playbackStateHandler();\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {HugePlaybackToggleButton} from './hugeplaybacktogglebutton';\n\n/**\n * @category Configs\n */\nexport interface PlaybackToggleOverlayConfig extends ContainerConfig {\n /**\n * Specify whether the player should be set to enter fullscreen by clicking on the playback toggle button\n * when initiating the initial playback.\n * Default is false.\n */\n enterFullscreenOnInitialPlayback?: boolean;\n}\n\n/**\n * Overlays the player and displays error messages.\n *\n * @category Components\n */\nexport class PlaybackToggleOverlay extends Container<PlaybackToggleOverlayConfig> {\n\n private playbackToggleButton: HugePlaybackToggleButton;\n\n constructor(config: PlaybackToggleOverlayConfig = {}) {\n super(config);\n\n this.playbackToggleButton = new HugePlaybackToggleButton({\n enterFullscreenOnInitialPlayback: Boolean(config.enterFullscreenOnInitialPlayback),\n });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-playbacktoggle-overlay',\n components: [this.playbackToggleButton],\n }, this.config);\n }\n}","import { Button, ButtonConfig } from './button';\nimport { i18n } from '../localization/i18n';\nimport { PlayerAPI, SeekEvent, TimeShiftEvent } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerUtils } from '../playerutils';\n\n/**\n * @category Configs\n */\nexport interface QuickSeekButtonConfig extends ButtonConfig {\n /**\n * Specify how many seconds the player should seek forward/backwards in the stream.\n * Negative values mean a backwards seek, positive values mean a forward seek.\n * Default is -10.\n */\n seekSeconds?: number;\n}\n\n/**\n * @category Buttons\n */\nexport class QuickSeekButton extends Button<QuickSeekButtonConfig> {\n private currentSeekTarget: number | null;\n private player: PlayerAPI;\n\n constructor(config: QuickSeekButtonConfig = {}) {\n super(config);\n this.currentSeekTarget = null;\n\n this.config = this.mergeConfig(\n config,\n {\n seekSeconds: -10,\n cssClass: 'ui-quickseekbutton',\n },\n this.config,\n );\n\n const seekDirection = this.config.seekSeconds < 0 ? 'rewind' : 'forward';\n\n this.config.text = this.config.text || i18n.getLocalizer(`quickseek.${seekDirection}`);\n this.config.ariaLabel = this.config.ariaLabel || i18n.getLocalizer(`quickseek.${seekDirection}`);\n\n this.getDomElement().data(this.prefixCss('seek-direction'), seekDirection);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n this.player = player;\n\n let isLive: boolean;\n let hasTimeShift: boolean;\n\n const switchVisibility = (isLive: boolean, hasTimeShift: boolean) => {\n if (isLive && !hasTimeShift) {\n this.hide();\n } else {\n this.show();\n }\n };\n\n const timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(\n (sender, args: PlayerUtils.TimeShiftAvailabilityChangedArgs) => {\n hasTimeShift = args.timeShiftAvailable;\n switchVisibility(isLive, hasTimeShift);\n },\n );\n\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: PlayerUtils.LiveStreamDetectorEventArgs) => {\n isLive = args.live;\n switchVisibility(isLive, hasTimeShift);\n });\n\n // Initial detection\n timeShiftDetector.detect();\n liveStreamDetector.detect();\n\n this.onClick.subscribe(() => {\n if (isLive && !hasTimeShift) {\n // If no DVR window is available, the button should be hidden anyway, so this is to be absolutely sure\n return;\n }\n\n if (isLive && this.config.seekSeconds > 0 && player.getTimeShift() === 0) {\n // Don't do anything if the player is already on the live edge\n return;\n }\n\n const currentPosition =\n this.currentSeekTarget !== null\n ? this.currentSeekTarget\n : isLive\n ? player.getTimeShift()\n : player.getCurrentTime();\n\n const newSeekTime = currentPosition + this.config.seekSeconds;\n\n if (isLive) {\n const clampedValue = PlayerUtils.clampValueToRange(newSeekTime, player.getMaxTimeShift(), 0);\n player.timeShift(clampedValue);\n } else {\n const clampedValue = PlayerUtils.clampValueToRange(newSeekTime, 0, player.getDuration());\n player.seek(clampedValue);\n }\n });\n\n this.player.on(this.player.exports.PlayerEvent.Seek, this.onSeek);\n this.player.on(this.player.exports.PlayerEvent.Seeked, this.onSeekedOrTimeShifted);\n this.player.on(this.player.exports.PlayerEvent.TimeShift, this.onTimeShift);\n this.player.on(this.player.exports.PlayerEvent.TimeShifted, this.onSeekedOrTimeShifted);\n }\n\n private onSeek = (event: SeekEvent): void => {\n this.currentSeekTarget = event.seekTarget;\n };\n\n private onSeekedOrTimeShifted = () => {\n this.currentSeekTarget = null;\n };\n\n private onTimeShift = (event: TimeShiftEvent): void => {\n this.currentSeekTarget = this.player.getTimeShift() + (event.target - event.position);\n }\n\n release(): void {\n this.player.off(this.player.exports.PlayerEvent.Seek, this.onSeek);\n this.player.off(this.player.exports.PlayerEvent.Seeked, this.onSeekedOrTimeShifted);\n this.player.off(this.player.exports.PlayerEvent.TimeShift, this.onTimeShift);\n this.player.off(this.player.exports.PlayerEvent.TimeShifted, this.onSeekedOrTimeShifted);\n this.currentSeekTarget = null;\n this.player = null;\n }\n}\n","import {ContainerConfig, Container} from './container';\nimport {Component, ComponentConfig} from './component';\nimport {DOM} from '../dom';\nimport {UIInstanceManager} from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport {HugeReplayButton} from './hugereplaybutton';\nimport { UIRecommendationConfig } from '../uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Overlays the player and displays recommended videos.\n *\n * @category Containers\n */\nexport class RecommendationOverlay extends Container<ContainerConfig> {\n\n private replayButton: HugeReplayButton;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.replayButton = new HugeReplayButton();\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-recommendation-overlay',\n hidden: true,\n components: [this.replayButton],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let clearRecommendations = () => {\n for (let component of this.getComponents().slice()) {\n if (component instanceof RecommendationItem) {\n this.removeComponent(component);\n }\n }\n this.updateComponents();\n this.getDomElement().removeClass(this.prefixCss('recommendations'));\n };\n\n let setupRecommendations = () => {\n clearRecommendations();\n\n const recommendations = uimanager.getConfig().recommendations;\n\n if (recommendations.length > 0) {\n let index = 1;\n for (let item of recommendations) {\n this.addComponent(new RecommendationItem({\n itemConfig: item,\n cssClasses: ['recommendation-item-' + (index++)],\n }));\n }\n this.updateComponents(); // create container DOM elements\n\n this.getDomElement().addClass(this.prefixCss('recommendations'));\n }\n };\n\n uimanager.getConfig().events.onUpdated.subscribe(setupRecommendations);\n // Remove recommendations and hide overlay when source is unloaded\n player.on(player.exports.PlayerEvent.SourceUnloaded, () => {\n clearRecommendations();\n this.hide();\n });\n // Display recommendations when playback has finished\n player.on(player.exports.PlayerEvent.PlaybackFinished, () => {\n this.show();\n });\n // Hide recommendations when playback starts, e.g. a restart\n player.on(player.exports.PlayerEvent.Play, () => {\n this.hide();\n });\n\n // Init on startup\n setupRecommendations();\n }\n}\n\n/**\n * Configuration interface for the {@link RecommendationItem}\n */\ninterface RecommendationItemConfig extends ComponentConfig {\n itemConfig: UIRecommendationConfig;\n}\n\n/**\n * An item of the {@link RecommendationOverlay}. Used only internally in {@link RecommendationOverlay}.\n */\nclass RecommendationItem extends Component<RecommendationItemConfig> {\n\n constructor(config: RecommendationItemConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-recommendation-item',\n itemConfig: null, // this must be passed in from outside\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n let config = this.config.itemConfig;\n\n let itemElement = new DOM('a', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'href': config.url,\n }, this).css({ 'background-image': `url(${config.thumbnail})` });\n\n let bgElement = new DOM('div', {\n 'class': this.prefixCss('background'),\n });\n itemElement.append(bgElement);\n\n let titleElement = new DOM('span', {\n 'class': this.prefixCss('title'),\n }).append(new DOM('span', {\n 'class': this.prefixCss('innertitle'),\n }).html(config.title));\n itemElement.append(titleElement);\n\n let timeElement = new DOM('span', {\n 'class': this.prefixCss('duration'),\n }).append(new DOM('span', {\n 'class': this.prefixCss('innerduration'),\n }).html(config.duration ? StringUtils.secondsToTime(config.duration) : ''));\n itemElement.append(timeElement);\n\n return itemElement;\n }\n}","import { ButtonConfig, Button } from './button';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { PlayerUtils } from '../playerutils';\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\n\n/**\n * A button to play/replay a video.\n *\n * @category Buttons\n */\nexport class ReplayButton extends Button<ButtonConfig> {\n\n constructor(config: ButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-replaybutton',\n text: i18n.getLocalizer('replay'),\n ariaLabel: i18n.getLocalizer('replay'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n if (player.isLive()) {\n this.hide();\n }\n\n const liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n if (args.live) {\n this.hide();\n } else {\n this.show();\n }\n });\n\n this.onClick.subscribe(() => {\n if (!player.hasEnded()) {\n player.seek(0);\n // Not calling `play` will keep the play/pause state as is\n } else {\n // If playback has already ended, calling `play` will automatically restart from the beginning\n player.play('ui');\n }\n });\n }\n}\n","import { ExtendedPlayerAPI, GroupPlaybackSuspension, GroupPlaybackSuspensionReason } from './../groupplaybackapi';\nimport { Component, ComponentConfig } from './component';\nimport { DOM } from '../dom';\nimport { Event, EventDispatcher, NoArgs } from '../eventdispatcher';\nimport { SeekBarLabel } from './seekbarlabel';\nimport { UIInstanceManager, SeekPreviewArgs } from '../uimanager';\nimport { Timeout } from '../timeout';\nimport { PlayerUtils } from '../playerutils';\nimport TimeShiftAvailabilityChangedArgs = PlayerUtils.TimeShiftAvailabilityChangedArgs;\nimport LiveStreamDetectorEventArgs = PlayerUtils.LiveStreamDetectorEventArgs;\nimport { TimelineMarker } from '../uiconfig';\nimport { PlayerAPI, PlayerEventBase } from 'bitmovin-player';\nimport { StringUtils } from '../stringutils';\nimport { SeekBarType, SeekBarController } from './seekbarcontroller';\nimport { i18n } from '../localization/i18n';\nimport { BrowserUtils } from '../browserutils';\nimport { TimelineMarkersHandler } from './timelinemarkershandler';\nimport { getMinBufferLevel } from './seekbarbufferlevel';\n\n/**\n * Configuration interface for the {@link SeekBar} component.\n *\n * @category Configs\n */\nexport interface SeekBarConfig extends ComponentConfig {\n /**\n * The label above the seek position.\n */\n label?: SeekBarLabel;\n /**\n * Bar will be vertical instead of horizontal if set to true.\n */\n vertical?: boolean;\n /**\n * The interval in milliseconds in which the playback position on the seek bar will be updated. The shorter the\n * interval, the smoother it looks and the more resource intense it is. The update interval will be kept as steady\n * as possible to avoid jitter.\n * Set to -1 to disable smooth updating and update it on player TimeChanged events instead.\n * Default: 50 (50ms = 20fps).\n */\n smoothPlaybackPositionUpdateIntervalMs?: number;\n\n /**\n * Used for seekBar control increments and decrements\n */\n keyStepIncrements?: { leftRight: number, upDown: number };\n\n /**\n * Used to enable/disable snapping to markers on the seek bar when seeking near them.\n * Default: true\n */\n snappingEnabled?: boolean;\n\n /**\n * Defines tolerance for snapping to markers, if snapping to seek bar markers is enabled.\n */\n snappingRange?: number;\n\n /**\n * Used to enable/disable seek preview\n */\n enableSeekPreview?: boolean;\n}\n\n/**\n * Event argument interface for a seek preview event.\n */\nexport interface SeekPreviewEventArgs extends SeekPreviewArgs {\n /**\n * Tells if the seek preview event comes from a scrubbing.\n */\n scrubbing: boolean;\n}\n\n/**\n * @category Components\n */\nexport interface SeekBarMarker {\n marker: TimelineMarker;\n position: number;\n duration?: number;\n element?: DOM;\n}\n\n/**\n * A seek bar to seek within the player's media. It displays the current playback position, amount of buffed data, seek\n * target, and keeps status about an ongoing seek.\n *\n * The seek bar displays different 'bars':\n * - the playback position, i.e. the position in the media at which the player current playback pointer is positioned\n * - the buffer position, which usually is the playback position plus the time span that is already buffered ahead\n * - the seek position, used to preview to where in the timeline a seek will jump to\n *\n * @category Components\n */\nexport class SeekBar extends Component<SeekBarConfig> {\n\n public static readonly SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED = -1;\n\n /**\n * The CSS class that is added to the DOM element while the seek bar is in 'seeking' state.\n */\n private static readonly CLASS_SEEKING = 'seeking';\n\n private seekBar: DOM;\n private seekBarPlaybackPosition: DOM;\n private seekBarPlaybackPositionMarker: DOM;\n private seekBarBufferPosition: DOM;\n private seekBarSeekPosition: DOM;\n private seekBarBackdrop: DOM;\n\n private label: SeekBarLabel;\n\n private seekBarMarkersContainer: DOM;\n private timelineMarkersHandler: TimelineMarkersHandler;\n\n private uiBoundingRect: DOMRect;\n\n private player: PlayerAPI;\n private uiManager: UIInstanceManager;\n\n protected seekBarType: SeekBarType;\n\n protected isUiShown: boolean;\n\n /**\n * Buffer of the the current playback position. The position must be buffered in case the element\n * needs to be refreshed with {@link #refreshPlaybackPosition}.\n * @type {number}\n */\n private playbackPositionPercentage = 0;\n\n private smoothPlaybackPositionUpdater: Timeout;\n private pausedTimeshiftUpdater: Timeout;\n\n private isUserSeeking = false;\n\n private seekBarEvents = {\n /**\n * Fired when a scrubbing seek operation is started.\n */\n onSeek: new EventDispatcher<SeekBar, NoArgs>(),\n /**\n * Fired during a scrubbing seek to indicate that the seek preview (i.e. the video frame) should be updated.\n */\n onSeekPreview: new EventDispatcher<SeekBar, SeekPreviewEventArgs>(),\n /**\n * Fired when a scrubbing seek has finished or when a direct seek is issued.\n */\n onSeeked: new EventDispatcher<SeekBar, number>(),\n };\n\n constructor(config: SeekBarConfig = {}) {\n super(config);\n\n const keyStepIncrements = this.config.keyStepIncrements || {\n leftRight: 1,\n upDown: 5,\n };\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-seekbar',\n vertical: false,\n smoothPlaybackPositionUpdateIntervalMs: 50,\n keyStepIncrements,\n ariaLabel: i18n.getLocalizer('seekBar'),\n tabIndex: 0,\n snappingRange: 1,\n enableSeekPreview: true,\n snappingEnabled: true,\n }, this.config);\n\n this.label = this.config.label;\n }\n\n initialize(): void {\n super.initialize();\n\n if (this.hasLabel()) {\n this.getLabel().initialize();\n }\n }\n\n protected setAriaSliderMinMax(min: string, max: string) {\n this.getDomElement().attr('aria-valuemin', min);\n this.getDomElement().attr('aria-valuemax', max);\n }\n\n private setAriaSliderValues() {\n if (this.seekBarType === SeekBarType.Live) {\n const timeshiftValue = Math.ceil(this.player.getTimeShift()).toString();\n this.getDomElement().attr('aria-valuenow', timeshiftValue);\n this.getDomElement().attr('aria-valuetext', `${i18n.performLocalization(i18n.getLocalizer('seekBar.timeshift'))} ${i18n.performLocalization(i18n.getLocalizer('seekBar.value'))}: ${timeshiftValue}`);\n } else if (this.seekBarType === SeekBarType.Vod) {\n const ariaValueText = `${StringUtils.secondsToText(this.player.getCurrentTime())} ${i18n.performLocalization(i18n.getLocalizer('seekBar.durationText'))} ${StringUtils.secondsToText(this.player.getDuration())}`;\n this.getDomElement().attr('aria-valuenow', Math.floor(this.player.getCurrentTime()).toString());\n this.getDomElement().attr('aria-valuetext', ariaValueText);\n }\n }\n\n private getPlaybackPositionPercentage(): number {\n if (this.player.isLive()) {\n return 100 - (100 / this.player.getMaxTimeShift() * this.player.getTimeShift());\n }\n\n return 100 / this.player.getDuration() * this.getRelativeCurrentTime();\n }\n\n private updateBufferLevel(playbackPositionPercentage: number): void {\n\n let bufferLoadedPercentageLevel: number;\n if (this.player.isLive()) {\n // Always show full buffer for live streams\n bufferLoadedPercentageLevel = 100;\n } else {\n bufferLoadedPercentageLevel = playbackPositionPercentage + getMinBufferLevel(this.player);\n }\n\n this.setBufferPosition(bufferLoadedPercentageLevel);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager, configureSeek: boolean = true): void {\n super.configure(player, uimanager);\n\n this.player = player;\n this.uiManager = uimanager;\n\n // Apply scaling transform to the backdrop bar to have all bars rendered similarly\n // (the call must be up here to be executed for the volume slider as well)\n this.setPosition(this.seekBarBackdrop, 100);\n\n // Add seekbar controls to the seekbar\n const seekBarController = new SeekBarController(this.config.keyStepIncrements, player, uimanager.getConfig().volumeController);\n\n seekBarController.setSeekBarControls(this.getDomElement(), () => this.seekBarType);\n\n // The configureSeek flag can be used by subclasses to disable configuration as seek bar. E.g. the volume\n // slider is reusing this component but adds its own functionality, and does not need the seek functionality.\n // This is actually a hack, the proper solution would be for both seek bar and volume sliders to extend\n // a common base slider component and implement their functionality there.\n if (!configureSeek) {\n this.seekBarType = SeekBarType.Volume;\n\n return;\n }\n\n uimanager.onControlsShow.subscribe(() => {\n this.isUiShown = true;\n if (!player.isLive() && !this.smoothPlaybackPositionUpdater.isActive()) {\n playbackPositionHandler(null, true);\n this.smoothPlaybackPositionUpdater.start();\n }\n });\n\n uimanager.onControlsHide.subscribe(() => {\n this.isUiShown = false;\n if (this.smoothPlaybackPositionUpdater.isActive()) {\n this.smoothPlaybackPositionUpdater.clear();\n }\n });\n\n let isPlaying = false;\n let scrubbing = false;\n let isPlayerSeeking = false;\n let suspension: GroupPlaybackSuspension | undefined;\n\n // Update playback and buffer positions\n let playbackPositionHandler = (event: PlayerEventBase = null, forceUpdate: boolean = false) => {\n if (this.isUserSeeking) {\n // We caught a seek preview seek, do not update the seekbar\n return;\n }\n\n let playbackPositionPercentage = this.getPlaybackPositionPercentage();\n\n this.updateBufferLevel(playbackPositionPercentage);\n\n // The segment request finished is used to help the playback position move, when the smooth playback position is not enabled.\n // At the same time when the user is scrubbing, we also move the position of the seekbar to display a preview during scrubbing.\n // When the user is scrubbing we do not record this as a user seek operation, as the user has yet to finish their seek,\n // but we should not move the playback position to not create a jumping behaviour.\n if (scrubbing && event && event.type === player.exports.PlayerEvent.SegmentRequestFinished && playbackPositionPercentage !== this.playbackPositionPercentage) {\n playbackPositionPercentage = this.playbackPositionPercentage;\n }\n\n if (player.isLive()) {\n if (player.getMaxTimeShift() === 0) {\n // This case must be explicitly handled to avoid division by zero\n this.setPlaybackPosition(100);\n } else {\n if (!this.isSeeking()) {\n this.setPlaybackPosition(playbackPositionPercentage);\n }\n\n this.setAriaSliderMinMax(player.getMaxTimeShift().toString(), '0');\n }\n } else {\n // Update playback position only in paused state or in the initial startup state where player is neither\n // paused nor playing. Playback updates are handled in the Timeout below.\n const isInInitialStartupState = this.config.smoothPlaybackPositionUpdateIntervalMs === SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED\n || forceUpdate || player.isPaused();\n const isNeitherPausedNorPlaying = player.isPaused() === player.isPlaying();\n\n if ((isInInitialStartupState || isNeitherPausedNorPlaying) && !this.isSeeking()) {\n this.setPlaybackPosition(playbackPositionPercentage);\n }\n\n this.setAriaSliderMinMax('0', player.getDuration().toString());\n }\n\n if (this.isUiShown) {\n this.setAriaSliderValues();\n }\n };\n\n // Update seekbar upon these events\n // init playback position when the player is ready\n player.on(player.exports.PlayerEvent.Ready, playbackPositionHandler);\n // update playback position when it changes\n player.on(player.exports.PlayerEvent.TimeChanged, playbackPositionHandler);\n // update bufferlevel when buffering is complete\n player.on(player.exports.PlayerEvent.StallEnded, playbackPositionHandler);\n // update playback position when a timeshift has finished\n player.on(player.exports.PlayerEvent.TimeShifted, playbackPositionHandler);\n // update bufferlevel when a segment has been downloaded\n player.on(player.exports.PlayerEvent.SegmentRequestFinished, playbackPositionHandler);\n\n this.configureLivePausedTimeshiftUpdater(player, uimanager, playbackPositionHandler);\n\n // Seek handling\n let onPlayerSeek = () => {\n isPlayerSeeking = true;\n this.setSeeking(true);\n scrubbing = false;\n };\n\n let onPlayerSeeked = (event: PlayerEventBase = null) => {\n isPlayerSeeking = false;\n this.setSeeking(false);\n\n // update playback position when a seek has finished\n playbackPositionHandler(event, true);\n };\n\n let restorePlayingState = function () {\n // Continue playback after seek if player was playing when seek started\n if (isPlaying) {\n // use the same issuer here as in the pause on seek\n player.play('ui-seek');\n }\n };\n\n player.on(player.exports.PlayerEvent.Seek, onPlayerSeek);\n player.on(player.exports.PlayerEvent.Seeked, onPlayerSeeked);\n player.on(player.exports.PlayerEvent.TimeShift, onPlayerSeek);\n player.on(player.exports.PlayerEvent.TimeShifted, onPlayerSeeked);\n\n let isGroupPlaybackAPIAvailable = (player: PlayerAPI): player is ExtendedPlayerAPI => {\n return !!(player as ExtendedPlayerAPI).groupPlayback;\n };\n\n this.onSeek.subscribe((sender) => {\n // track seeking status so we can catch events from seek preview seeks\n this.isUserSeeking = true;\n // Notify UI manager of started seek\n uimanager.onSeek.dispatch(sender);\n\n if (isGroupPlaybackAPIAvailable(player) && player.groupPlayback.hasJoined() && !suspension) {\n suspension = player.groupPlayback.beginSuspension(GroupPlaybackSuspensionReason.UserIsScrubbing);\n }\n\n // Save current playback state before performing the seek\n if (!isPlayerSeeking) {\n isPlaying = player.isPlaying();\n\n // Pause playback while seeking\n if (isPlaying) {\n // use a different issuer here, as play/pause on seek is not \"really\" triggerd by the user\n player.pause('ui-seek');\n }\n }\n });\n\n this.onSeekPreview.subscribe((sender: SeekBar, args: SeekPreviewEventArgs) => {\n // Notify UI manager of seek preview\n uimanager.onSeekPreview.dispatch(sender, args);\n scrubbing = args.scrubbing;\n });\n\n // Set enableSeekPreview if set in the uimanager config\n if (typeof uimanager.getConfig().enableSeekPreview === 'boolean') {\n this.config.enableSeekPreview = uimanager.getConfig().enableSeekPreview;\n }\n\n // Rate-limited scrubbing seek\n if (this.config.enableSeekPreview) {\n this.onSeekPreview.subscribeRateLimited(this.seekWhileScrubbing, 200);\n }\n\n this.onSeeked.subscribe((sender, percentage) => {\n this.isUserSeeking = false;\n\n // Do the seek\n this.seek(percentage);\n\n // Notify UI manager of finished seek\n uimanager.onSeeked.dispatch(sender);\n\n // Continue playback after seek if player was playing when seek started\n restorePlayingState();\n\n if (isGroupPlaybackAPIAvailable(player) && player.groupPlayback.hasJoined() && suspension) {\n const proposedPlaybackTime = this.getTargetSeekPosition(percentage);\n player.groupPlayback.endSuspension(suspension, { proposedPlaybackTime });\n suspension = undefined;\n }\n });\n\n if (this.hasLabel()) {\n // Configure a seekbar label that is internal to the seekbar)\n this.getLabel().configure(player, uimanager);\n }\n\n // Hide seekbar for live sources without timeshift\n let isLive = false;\n let hasTimeShift = false;\n let switchVisibility = (isLive: boolean, hasTimeShift: boolean) => {\n if (isLive && !hasTimeShift) {\n this.hide();\n } else {\n this.show();\n }\n playbackPositionHandler(null, true);\n this.refreshPlaybackPosition();\n };\n let liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);\n liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {\n isLive = args.live;\n if (isLive && this.smoothPlaybackPositionUpdater != null) {\n this.smoothPlaybackPositionUpdater.clear();\n this.seekBarType = SeekBarType.Live;\n } else {\n this.seekBarType = SeekBarType.Vod;\n }\n switchVisibility(isLive, hasTimeShift);\n });\n let timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);\n timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe((sender, args: TimeShiftAvailabilityChangedArgs) => {\n hasTimeShift = args.timeShiftAvailable;\n switchVisibility(isLive, hasTimeShift);\n });\n // Initial detection\n liveStreamDetector.detect();\n timeShiftDetector.detect();\n\n // Refresh the playback position when the player resized or the UI is configured. The playback position marker\n // is positioned absolutely and must therefore be updated when the size of the seekbar changes.\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n this.refreshPlaybackPosition();\n this.uiBoundingRect = this.uiManager.getUI().getDomElement().get(0).getBoundingClientRect();\n });\n // Additionally, when this code is called, the seekbar is not part of the UI yet and therefore does not have a size,\n // resulting in a wrong initial position of the marker. Refreshing it once the UI is configured solved this issue.\n uimanager.onConfigured.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n // It can also happen when a new source is loaded\n player.on(player.exports.PlayerEvent.SourceLoaded, () => {\n this.refreshPlaybackPosition();\n });\n // Add markers when a source is loaded or update when a marker is added or removed\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n playbackPositionHandler();\n });\n\n // Set the snappingRange if set in the uimanager config\n if (typeof uimanager.getConfig().seekbarSnappingRange === 'number') {\n this.config.snappingRange = uimanager.getConfig().seekbarSnappingRange;\n }\n\n if (typeof uimanager.getConfig().seekbarSnappingEnabled === 'boolean') {\n this.config.snappingEnabled = uimanager.getConfig().seekbarSnappingEnabled;\n }\n\n // Initialize seekbar\n playbackPositionHandler(); // Set the playback position\n this.setBufferPosition(0);\n this.setSeekPosition(0);\n if (this.config.smoothPlaybackPositionUpdateIntervalMs !== SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED) {\n this.configureSmoothPlaybackPositionUpdater(player, uimanager);\n }\n\n // Initialize markers\n this.initializeTimelineMarkers(player, uimanager);\n }\n\n private initializeTimelineMarkers(player: PlayerAPI, uimanager: UIInstanceManager): void {\n const timelineMarkerConfig = {\n cssPrefix: this.config.cssPrefix,\n snappingRange: this.config.snappingRange,\n };\n this.timelineMarkersHandler = new TimelineMarkersHandler(timelineMarkerConfig, () => this.seekBar.width(), this.seekBarMarkersContainer);\n this.timelineMarkersHandler.initialize(player, uimanager);\n }\n\n private seekWhileScrubbing = (sender: SeekBar, args: SeekPreviewEventArgs) => {\n if (args.scrubbing) {\n this.seek(args.position);\n }\n };\n\n private getTargetSeekPosition = (percentage: number) => {\n let target: number;\n if (this.player.isLive()) {\n const maxTimeShift = this.player.getMaxTimeShift();\n target = maxTimeShift - (maxTimeShift * (percentage / 100));\n } else {\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(this.player, 0);\n const relativeSeekTarget = this.player.getDuration() * (percentage / 100);\n target = relativeSeekTarget + seekableRangeStart;\n }\n\n return target;\n }\n\n private seek = (percentage: number) => {\n const targetPlaybackPosition = this.getTargetSeekPosition(percentage);\n if (this.player.isLive()) {\n this.player.timeShift(targetPlaybackPosition, 'ui');\n } else {\n this.player.seek(targetPlaybackPosition, 'ui');\n }\n };\n\n /**\n * Update seekbar while a live stream with DVR window is paused.\n * The playback position stays still and the position indicator visually moves towards the back.\n */\n private configureLivePausedTimeshiftUpdater(\n player: PlayerAPI,\n uimanager: UIInstanceManager,\n playbackPositionHandler: () => void,\n ): void {\n // Regularly update the playback position while the timeout is active\n this.pausedTimeshiftUpdater = new Timeout(1000, playbackPositionHandler, true);\n\n // Start updater when a live stream with timeshift window is paused\n player.on(player.exports.PlayerEvent.Paused, () => {\n if (player.isLive() && player.getMaxTimeShift() < 0) {\n this.pausedTimeshiftUpdater.start();\n }\n });\n\n // Stop updater when playback continues (no matter if the updater was started before)\n player.on(player.exports.PlayerEvent.Play, () => this.pausedTimeshiftUpdater.clear());\n }\n\n private configureSmoothPlaybackPositionUpdater(player: PlayerAPI, uimanager: UIInstanceManager): void {\n /*\n * Playback position update\n *\n * We do not update the position directly from the TimeChanged event, because it arrives very jittery and\n * results in a jittery position indicator since the CSS transition time is statically set.\n * To work around this issue, we maintain a local playback position that is updated in a stable regular interval\n * and kept in sync with the player.\n */\n let currentTimeSeekBar = 0;\n let currentTimePlayer = 0;\n let updateIntervalMs = 50;\n let currentTimeUpdateDeltaSecs = updateIntervalMs / 1000;\n\n this.smoothPlaybackPositionUpdater = new Timeout(updateIntervalMs, () => {\n if (this.isSeeking()) {\n return;\n }\n\n currentTimeSeekBar += currentTimeUpdateDeltaSecs;\n\n try {\n currentTimePlayer = this.getRelativeCurrentTime();\n } catch (error) {\n // Detect if the player has been destroyed and stop updating if so\n if (error instanceof player.exports.PlayerAPINotAvailableError) {\n this.smoothPlaybackPositionUpdater.clear();\n }\n\n // If the current time cannot be read it makes no sense to continue\n return;\n }\n\n // Sync currentTime of seekbar to player\n let currentTimeDelta = currentTimeSeekBar - currentTimePlayer;\n // If the delta is larger that 2 secs, directly jump the seekbar to the\n // player time instead of smoothly fast forwarding/rewinding.\n if (Math.abs(currentTimeDelta) > 2) {\n currentTimeSeekBar = currentTimePlayer;\n }\n // If currentTimeDelta is negative and below the adjustment threshold,\n // the player is ahead of the seekbar and we 'fast forward' the seekbar\n else if (currentTimeDelta <= -currentTimeUpdateDeltaSecs) {\n currentTimeSeekBar += currentTimeUpdateDeltaSecs;\n }\n // If currentTimeDelta is positive and above the adjustment threshold,\n // the player is behind the seekbar and we 'rewind' the seekbar\n else if (currentTimeDelta >= currentTimeUpdateDeltaSecs) {\n currentTimeSeekBar -= currentTimeUpdateDeltaSecs;\n }\n\n let playbackPositionPercentage = 100 / player.getDuration() * currentTimeSeekBar;\n this.setPlaybackPosition(playbackPositionPercentage);\n }, true);\n\n let startSmoothPlaybackPositionUpdater = () => {\n if (!player.isLive()) {\n currentTimeSeekBar = this.getRelativeCurrentTime();\n this.smoothPlaybackPositionUpdater.start();\n }\n };\n\n let stopSmoothPlaybackPositionUpdater = () => {\n this.smoothPlaybackPositionUpdater.clear();\n };\n\n player.on(player.exports.PlayerEvent.Play, startSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Playing, startSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Paused, stopSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.PlaybackFinished, stopSmoothPlaybackPositionUpdater);\n player.on(player.exports.PlayerEvent.Seeked, () => {\n currentTimeSeekBar = this.getRelativeCurrentTime();\n });\n player.on(player.exports.PlayerEvent.SourceUnloaded, stopSmoothPlaybackPositionUpdater);\n\n if (player.isPlaying()) {\n startSmoothPlaybackPositionUpdater();\n }\n }\n\n private getRelativeCurrentTime(): number {\n return PlayerUtils.getCurrentTimeRelativeToSeekableRange(this.player);\n }\n\n release(): void {\n super.release();\n\n if (this.smoothPlaybackPositionUpdater) { // object must not necessarily exist, e.g. in volume slider subclass\n this.smoothPlaybackPositionUpdater.clear();\n }\n\n if (this.pausedTimeshiftUpdater) {\n this.pausedTimeshiftUpdater.clear();\n }\n\n if (this.config.enableSeekPreview) {\n this.onSeekPreview.unsubscribe(this.seekWhileScrubbing);\n }\n }\n\n protected toDomElement(): DOM {\n if (this.config.vertical) {\n this.config.cssClasses.push('vertical');\n }\n\n let seekBarContainer = new DOM('div', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'role': 'slider',\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n 'tabindex': this.config.tabIndex.toString(),\n }, this);\n\n let seekBar = new DOM('div', {\n 'class': this.prefixCss('seekbar'),\n });\n this.seekBar = seekBar;\n\n // Indicator that shows the buffer fill level\n let seekBarBufferLevel = new DOM('div', {\n 'class': this.prefixCss('seekbar-bufferlevel'),\n });\n this.seekBarBufferPosition = seekBarBufferLevel;\n\n // Indicator that shows the current playback position\n let seekBarPlaybackPosition = new DOM('div', {\n 'class': this.prefixCss('seekbar-playbackposition'),\n });\n this.seekBarPlaybackPosition = seekBarPlaybackPosition;\n\n // A marker of the current playback position, e.g. a dot or line\n let seekBarPlaybackPositionMarker = new DOM('div', {\n 'class': this.prefixCss('seekbar-playbackposition-marker'),\n });\n this.seekBarPlaybackPositionMarker = seekBarPlaybackPositionMarker;\n\n // Indicator that show where a seek will go to\n let seekBarSeekPosition = new DOM('div', {\n 'class': this.prefixCss('seekbar-seekposition'),\n });\n this.seekBarSeekPosition = seekBarSeekPosition;\n\n // Indicator that shows the full seekbar\n let seekBarBackdrop = new DOM('div', {\n 'class': this.prefixCss('seekbar-backdrop'),\n });\n this.seekBarBackdrop = seekBarBackdrop;\n\n let seekBarChapterMarkersContainer = new DOM('div', {\n 'class': this.prefixCss('seekbar-markers'),\n });\n this.seekBarMarkersContainer = seekBarChapterMarkersContainer;\n\n seekBar.append(this.seekBarBackdrop, this.seekBarBufferPosition, this.seekBarSeekPosition,\n this.seekBarPlaybackPosition, this.seekBarMarkersContainer, this.seekBarPlaybackPositionMarker);\n\n let seeking = false;\n\n // Define handler functions so we can attach/remove them later\n let mouseTouchMoveHandler = (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n // Avoid propagation to VR handler\n if (this.player.vr != null) {\n e.stopPropagation();\n }\n\n const offset = this.getOffset(e);\n const targetPercentage = 100 * offset;\n const seekPositionPx = offset * this.seekBar.width();\n\n this.setSeekPosition(targetPercentage);\n this.setPlaybackPosition(targetPercentage);\n this.onSeekPreviewEvent(targetPercentage, seekPositionPx, true);\n };\n\n let mouseTouchUpHandler = (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n // Remove handlers, seek operation is finished\n new DOM(document).off('touchmove mousemove', mouseTouchMoveHandler);\n new DOM(document).off('touchend mouseup', mouseTouchUpHandler);\n\n let targetPercentage = 100 * this.getOffset(e);\n\n if (this.config.snappingEnabled) {\n const matchingMarker = this.timelineMarkersHandler?.getMarkerAtPosition(targetPercentage);\n targetPercentage = matchingMarker ? matchingMarker.position : targetPercentage;\n }\n\n this.setSeeking(false);\n seeking = false;\n\n // Fire seeked event\n this.onSeekedEvent(targetPercentage);\n };\n\n // A seek always start with a touchstart or mousedown directly on the seekbar.\n // To track a mouse seek also outside the seekbar (for touch events this works automatically),\n // so the user does not need to take care that the mouse always stays on the seekbar, we attach the mousemove\n // and mouseup handlers to the whole document. A seek is triggered when the user lifts the mouse key.\n // A seek mouse gesture is thus basically a click with a long time frame between down and up events.\n seekBar.on('touchstart mousedown', (e: MouseEvent | TouchEvent) => {\n let isTouchEvent = BrowserUtils.isTouchSupported && this.isTouchEvent(e);\n\n // Prevent selection of DOM elements (also prevents mousedown if current event is touchstart)\n e.preventDefault();\n // Avoid propagation to VR handler\n if (this.player.vr != null) {\n e.stopPropagation();\n }\n\n this.setSeeking(true); // Set seeking class on DOM element\n seeking = true; // Set seek tracking flag\n\n // Fire seeked event\n this.onSeekEvent();\n\n // Add handler to track the seek operation over the whole document\n new DOM(document).on(isTouchEvent ? 'touchmove' : 'mousemove', mouseTouchMoveHandler);\n new DOM(document).on(isTouchEvent ? 'touchend' : 'mouseup', mouseTouchUpHandler);\n });\n\n // Display seek target indicator when mouse hovers or finger slides over seekbar\n seekBar.on('touchmove mousemove', (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n if (seeking) {\n mouseTouchMoveHandler(e);\n }\n\n const offset = this.getOffset(e);\n const seekPositionPercentage = 100 * offset;\n const seekPositionPx = offset * this.seekBar.width();\n\n this.setSeekPosition(seekPositionPercentage);\n this.onSeekPreviewEvent(seekPositionPercentage, seekPositionPx, false);\n\n if (this.hasLabel() && this.getLabel().isHidden()) {\n this.getLabel().show();\n }\n });\n\n // Hide seek target indicator when mouse or finger leaves seekbar\n seekBar.on('touchend mouseleave', (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n\n this.setSeekPosition(0);\n\n if (this.hasLabel()) {\n this.getLabel().hide();\n }\n });\n\n seekBarContainer.append(seekBar);\n\n if (this.label) {\n seekBarContainer.append(this.label.getDomElement());\n }\n\n return seekBarContainer;\n }\n\n /**\n * Gets the horizontal offset of a mouse/touch event point from the left edge of the seek bar.\n * @param eventPageX the pageX coordinate of an event to calculate the offset from\n * @returns {number} a number in the range of [0, 1], where 0 is the left edge and 1 is the right edge\n */\n private getHorizontalOffset(eventPageX: number): number {\n let elementOffsetPx = this.seekBar.offset().left;\n let widthPx = this.seekBar.width();\n let offsetPx = eventPageX - elementOffsetPx;\n let offset = 1 / widthPx * offsetPx;\n\n return this.sanitizeOffset(offset);\n }\n\n /**\n * Gets the vertical offset of a mouse/touch event point from the bottom edge of the seek bar.\n * @param eventPageY the pageX coordinate of an event to calculate the offset from\n * @returns {number} a number in the range of [0, 1], where 0 is the bottom edge and 1 is the top edge\n */\n private getVerticalOffset(eventPageY: number): number {\n let elementOffsetPx = this.seekBar.offset().top;\n let widthPx = this.seekBar.height();\n let offsetPx = eventPageY - elementOffsetPx;\n let offset = 1 / widthPx * offsetPx;\n\n return 1 - this.sanitizeOffset(offset);\n }\n\n /**\n * Gets the mouse or touch event offset for the current configuration (horizontal or vertical).\n * @param e the event to calculate the offset from\n * @returns {number} a number in the range of [0, 1]\n * @see #getHorizontalOffset\n * @see #getVerticalOffset\n */\n private getOffset(e: MouseEvent | TouchEvent): number {\n if (BrowserUtils.isTouchSupported && this.isTouchEvent(e)) {\n if (this.config.vertical) {\n return this.getVerticalOffset(e.type === 'touchend' ? e.changedTouches[0].pageY : e.touches[0].pageY);\n } else {\n return this.getHorizontalOffset(e.type === 'touchend' ? e.changedTouches[0].pageX : e.touches[0].pageX);\n }\n }\n else if (e instanceof MouseEvent) {\n if (this.config.vertical) {\n return this.getVerticalOffset(e.pageY);\n } else {\n return this.getHorizontalOffset(e.pageX);\n }\n }\n else {\n if (console) {\n console.warn('invalid event');\n }\n return 0;\n }\n }\n\n /**\n * Sanitizes the mouse offset to the range of [0, 1].\n *\n * When tracking the mouse outside the seek bar, the offset can be outside the desired range and this method\n * limits it to the desired range. E.g. a mouse event left of the left edge of a seek bar yields an offset below\n * zero, but to display the seek target on the seek bar, we need to limit it to zero.\n *\n * @param offset the offset to sanitize\n * @returns {number} the sanitized offset.\n */\n private sanitizeOffset(offset: number) {\n // Since we track mouse moves over the whole document, the target can be outside the seek range,\n // and we need to limit it to the [0, 1] range.\n if (offset < 0) {\n offset = 0;\n } else if (offset > 1) {\n offset = 1;\n }\n\n return offset;\n }\n\n /**\n * Sets the position of the playback position indicator.\n * @param percent a number between 0 and 100 as returned by the player\n */\n setPlaybackPosition(percent: number) {\n this.playbackPositionPercentage = percent;\n\n // Set position of the bar\n this.setPosition(this.seekBarPlaybackPosition, percent);\n\n // Set position of the marker\n let totalSize = (this.config.vertical ? (this.seekBar.height() - this.seekBarPlaybackPositionMarker.height()) : this.seekBar.width());\n let px = (totalSize) / 100 * percent;\n if (this.config.vertical) {\n px = this.seekBar.height() - px - this.seekBarPlaybackPositionMarker.height();\n }\n\n let style = this.config.vertical ?\n // -ms-transform required for IE9\n // -webkit-transform required for Android 4.4 WebView\n {\n 'transform': 'translateY(' + px + 'px)',\n '-ms-transform': 'translateY(' + px + 'px)',\n '-webkit-transform': 'translateY(' + px + 'px)',\n } :\n {\n 'transform': 'translateX(' + px + 'px)',\n '-ms-transform': 'translateX(' + px + 'px)',\n '-webkit-transform': 'translateX(' + px + 'px)',\n };\n this.seekBarPlaybackPositionMarker.css(style);\n }\n\n /**\n * Refreshes the playback position. Can be used by subclasses to refresh the position when\n * the size of the component changes.\n */\n protected refreshPlaybackPosition() {\n this.setPlaybackPosition(this.playbackPositionPercentage);\n }\n\n /**\n * Sets the position until which media is buffered.\n * @param percent a number between 0 and 100\n */\n setBufferPosition(percent: number) {\n this.setPosition(this.seekBarBufferPosition, percent);\n }\n\n /**\n * Sets the position where a seek, if executed, would jump to.\n * @param percent a number between 0 and 100\n */\n setSeekPosition(percent: number) {\n this.setPosition(this.seekBarSeekPosition, percent);\n }\n\n /**\n * Set the actual position (width or height) of a DOM element that represent a bar in the seek bar.\n * @param element the element to set the position for\n * @param percent a number between 0 and 100\n */\n private setPosition(element: DOM, percent: number) {\n let scale = percent / 100;\n\n // When the scale is exactly 1 or very near 1 (and the browser internally rounds it to 1), browsers seem to render\n // the elements differently and the height gets slightly off, leading to mismatching heights when e.g. the buffer\n // level bar has a width of 1 and the playback position bar has a width < 1. A jittering buffer level around 1\n // leads to an even worse flickering effect.\n // Various changes in CSS styling and DOM hierarchy did not solve the issue so the workaround is to avoid a scale\n // of exactly 1.\n if (scale >= 0.99999 && scale <= 1.00001) {\n scale = 0.99999;\n }\n\n let style = this.config.vertical ?\n // -ms-transform required for IE9\n // -webkit-transform required for Android 4.4 WebView\n {\n 'transform': 'scaleY(' + scale + ')',\n '-ms-transform': 'scaleY(' + scale + ')',\n '-webkit-transform': 'scaleY(' + scale + ')',\n } :\n {\n 'transform': 'scaleX(' + scale + ')',\n '-ms-transform': 'scaleX(' + scale + ')',\n '-webkit-transform': 'scaleX(' + scale + ')',\n };\n element.css(style);\n }\n\n /**\n * Puts the seek bar into or out of seeking state by adding/removing a class to the DOM element. This can be used\n * to adjust the styling while seeking.\n *\n * @param seeking should be true when entering seek state, false when exiting the seek state\n */\n setSeeking(seeking: boolean) {\n if (seeking) {\n this.getDomElement().addClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n } else {\n this.getDomElement().removeClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n }\n }\n\n /**\n * Checks if the seek bar is currently in the seek state.\n * @returns {boolean} true if in seek state, else false\n */\n isSeeking(): boolean {\n return this.getDomElement().hasClass(this.prefixCss(SeekBar.CLASS_SEEKING));\n }\n\n /**\n * Checks if the seek bar has a {@link SeekBarLabel}.\n * @returns {boolean} true if the seek bar has a label, else false\n */\n hasLabel(): boolean {\n return this.label != null;\n }\n\n /**\n * Gets the label of this seek bar.\n * @returns {SeekBarLabel} the label if this seek bar has a label, else null\n */\n getLabel(): SeekBarLabel | null {\n return this.label;\n }\n\n protected onSeekEvent() {\n this.seekBarEvents.onSeek.dispatch(this);\n }\n\n private updateLabelPosition = (pixelPosition: number) => {\n if (!this.uiBoundingRect) {\n this.uiBoundingRect = this.uiManager.getUI().getDomElement().get(0).getBoundingClientRect();\n }\n\n this.label.setPositionInBounds(pixelPosition, this.uiBoundingRect);\n };\n\n protected onSeekPreviewEvent(percentage: number, targetOffsetPx: number, scrubbing: boolean) {\n let snappedMarker = this.timelineMarkersHandler && this.timelineMarkersHandler.getMarkerAtPosition(percentage);\n\n let seekPositionPercentage = percentage;\n\n if (snappedMarker) {\n if (snappedMarker.duration > 0) {\n if (percentage < snappedMarker.position) {\n // Snap the position to the start of the interval if the seek is within the left snap margin\n // We know that we are within a snap margin when we are outside the marker interval but still\n // have a snappedMarker\n seekPositionPercentage = snappedMarker.position;\n } else if (percentage > snappedMarker.position + snappedMarker.duration) {\n // Snap the position to the end of the interval if the seek is within the right snap margin\n seekPositionPercentage = snappedMarker.position + snappedMarker.duration;\n }\n } else {\n // Position markers always snap to their marker position\n seekPositionPercentage = snappedMarker.position;\n }\n }\n\n if (this.label) {\n this.updateLabelPosition(targetOffsetPx);\n }\n\n this.seekBarEvents.onSeekPreview.dispatch(this, {\n scrubbing: scrubbing,\n position: seekPositionPercentage,\n marker: snappedMarker,\n });\n }\n\n protected onSeekedEvent(percentage: number) {\n this.seekBarEvents.onSeeked.dispatch(this, percentage);\n }\n\n /**\n * Gets the event that is fired when a scrubbing seek operation is started.\n * @returns {Event<SeekBar, NoArgs>}\n */\n get onSeek(): Event<SeekBar, NoArgs> {\n return this.seekBarEvents.onSeek.getEvent();\n }\n\n /**\n * Gets the event that is fired during a scrubbing seek (to indicate that the seek preview, i.e. the video frame,\n * should be updated), or during a normal seek preview when the seek bar is hovered (and the seek target,\n * i.e. the seek bar label, should be updated).\n * @returns {Event<SeekBar, SeekPreviewEventArgs>}\n */\n get onSeekPreview(): Event<SeekBar, SeekPreviewEventArgs> {\n return this.seekBarEvents.onSeekPreview.getEvent();\n }\n\n /**\n * Gets the event that is fired when a scrubbing seek has finished or when a direct seek is issued.\n * @returns {Event<SeekBar, number>}\n */\n get onSeeked(): Event<SeekBar, number> {\n return this.seekBarEvents.onSeeked.getEvent();\n }\n\n\n protected onShowEvent(): void {\n super.onShowEvent();\n\n // Refresh the position of the playback position when the seek bar becomes visible. To correctly set the position,\n // the DOM element must be fully initialized an have its size calculated, because the position is set as an absolute\n // value calculated from the size. This required size is not known when it is hidden.\n // For such cases, we refresh the position here in onShow because here it is guaranteed that the component knows\n // its size and can set the position correctly.\n this.refreshPlaybackPosition();\n }\n\n /**\n * Checks if TouchEvent is supported.\n * @returns {boolean} true if TouchEvent not undefined, else false\n */\n isTouchEvent(e: UIEvent): e is TouchEvent {\n return window.TouchEvent && e instanceof TouchEvent;\n }\n}\n","import {PlayerAPI} from 'bitmovin-player';\n\nexport function getMinBufferLevel(player: PlayerAPI): number {\n\n const playerDuration = player.getDuration();\n\n const videoBufferLength = player.getVideoBufferLength();\n const audioBufferLength = player.getAudioBufferLength();\n // Calculate the buffer length which is the smaller length of the audio and video buffers. If one of these\n // buffers is not available, we set it's value to MAX_VALUE to make sure that the other real value is taken\n // as the buffer length.\n let bufferLength = Math.min(\n videoBufferLength != null ? videoBufferLength : Number.MAX_VALUE,\n audioBufferLength != null ? audioBufferLength : Number.MAX_VALUE);\n // If both buffer lengths are missing, we set the buffer length to zero\n if (bufferLength === Number.MAX_VALUE) {\n bufferLength = 0;\n }\n\n return 100 / playerDuration * bufferLength;\n}\n","import { UIUtils } from '../uiutils';\nimport { DOM } from '../dom';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { VolumeController } from '../volumecontroller';\n\nexport enum SeekBarType {\n Vod,\n Live,\n Volume,\n}\n\ninterface Range {\n min: number;\n max: number;\n}\n\ninterface KeyStepIncrementsConfig {\n leftRight: number;\n upDown: number;\n}\n\nconst coerceValueIntoRange = (\n value: number,\n range: Range,\n cb: (value: number) => void,\n) => {\n if (value < range.min) {\n cb(range.min);\n } else if (value > range.max) {\n cb(range.max);\n } else {\n cb(value);\n }\n};\n\n/**\n * @category Utils\n */\nexport class SeekBarController {\n protected keyStepIncrements: KeyStepIncrementsConfig;\n protected player: PlayerAPI;\n protected volumeController: VolumeController;\n\n constructor(\n keyStepIncrements: KeyStepIncrementsConfig,\n player: PlayerAPI,\n volumeController: VolumeController,\n ) {\n this.keyStepIncrements = keyStepIncrements;\n this.player = player;\n this.volumeController = volumeController;\n }\n\n protected arrowKeyControls(\n currentValue: number,\n range: Range,\n valueUpdate: (value: number) => void,\n ) {\n const controlValue = Math.floor(currentValue);\n\n return {\n left: () => coerceValueIntoRange(controlValue - this.keyStepIncrements.leftRight, range, valueUpdate),\n right: () => coerceValueIntoRange(controlValue + this.keyStepIncrements.leftRight, range, valueUpdate),\n up: () => coerceValueIntoRange(controlValue + this.keyStepIncrements.upDown, range, valueUpdate),\n down: () => coerceValueIntoRange(controlValue - this.keyStepIncrements.upDown, range, valueUpdate),\n home: () => coerceValueIntoRange(range.min, range, valueUpdate),\n end: () => coerceValueIntoRange(range.max, range, valueUpdate),\n };\n }\n\n protected seekBarControls(type: SeekBarType) {\n if (type === SeekBarType.Live) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.arrowKeyControls(this.player.getTimeShift(), { min: this.player.getMaxTimeShift(), max: 0 }, this.player.timeShift);\n } else if (type === SeekBarType.Vod) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.arrowKeyControls(this.player.getCurrentTime(), { min: 0, max: this.player.getDuration() }, this.player.seek);\n } else if (type === SeekBarType.Volume && this.volumeController != null) {\n const volumeTransition = this.volumeController.startTransition();\n return this.arrowKeyControls(this.player.getVolume(), { min: 0, max: 100 }, volumeTransition.finish.bind(volumeTransition));\n }\n }\n\n public setSeekBarControls(domElement: DOM, type: () => SeekBarType) {\n domElement.on('keydown', (e: KeyboardEvent) => {\n const controls = this.seekBarControls(type());\n switch (e.keyCode) {\n case UIUtils.KeyCode.LeftArrow: {\n controls.left();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.RightArrow: {\n controls.right();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.UpArrow: {\n controls.up();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.DownArrow: {\n controls.down();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.Home: {\n controls.home();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.End: {\n controls.end();\n e.preventDefault();\n break;\n }\n case UIUtils.KeyCode.Space: {\n this.player.isPlaying() ? this.player.pause() : this.player.play();\n e.preventDefault();\n break;\n }\n }\n });\n }\n}","import {Container, ContainerConfig} from './container';\nimport {Label, LabelConfig} from './label';\nimport {Component, ComponentConfig} from './component';\nimport { UIInstanceManager } from '../uimanager';\nimport {StringUtils} from '../stringutils';\nimport {ImageLoader} from '../imageloader';\nimport {CssProperties} from '../dom';\nimport { PlayerAPI, Thumbnail } from 'bitmovin-player';\nimport { SeekBar, SeekPreviewEventArgs } from './seekbar';\nimport { PlayerUtils } from '../playerutils';\n\n/**\n * Configuration interface for a {@link SeekBarLabel}.\n *\n * @category Configs\n */\nexport interface SeekBarLabelConfig extends ContainerConfig {\n // nothing yet\n}\n\n/**\n * A label for a {@link SeekBar} that can display the seek target time, a thumbnail, and title (e.g. chapter title).\n *\n * @category Components\n */\nexport class SeekBarLabel extends Container<SeekBarLabelConfig> {\n\n private timeLabel: Label<LabelConfig>;\n private titleLabel: Label<LabelConfig>;\n private thumbnail: Component<ComponentConfig>;\n\n private thumbnailImageLoader: ImageLoader;\n\n private timeFormat: string;\n\n private appliedMarkerCssClasses: string[] = [];\n private player: PlayerAPI;\n private uiManager: UIInstanceManager;\n private readonly container: Container<ContainerConfig>;\n private readonly caret: Label<LabelConfig>;\n\n constructor(config: SeekBarLabelConfig = {}) {\n super(config);\n\n this.timeLabel = new Label({ cssClasses: ['seekbar-label-time'] });\n this.titleLabel = new Label({ cssClasses: ['seekbar-label-title'] });\n this.thumbnail = new Component({ cssClasses: ['seekbar-thumbnail'], role: 'img' });\n this.thumbnailImageLoader = new ImageLoader();\n\n this.container = new Container({\n components: [\n this.thumbnail,\n new Container({\n components: [this.titleLabel, this.timeLabel],\n cssClass: 'seekbar-label-metadata',\n }),\n ],\n cssClass: 'seekbar-label-inner',\n });\n\n this.caret = new Label({ cssClasses: ['seekbar-label-caret'] });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-seekbar-label',\n components: [this.container, this.caret],\n hidden: true,\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.player = player;\n this.uiManager = uimanager;\n uimanager.onSeekPreview.subscribeRateLimited(this.handleSeekPreview, 100);\n\n let init = () => {\n // Set time format depending on source duration\n this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ?\n StringUtils.FORMAT_HHMMSS : StringUtils.FORMAT_MMSS;\n // Set initial state of title and thumbnail to handle sourceLoaded when switching to a live-stream\n this.setTitleText(null);\n this.setThumbnail(null);\n };\n\n uimanager.getConfig().events.onUpdated.subscribe(init);\n init();\n }\n\n private handleSeekPreview = (sender: SeekBar, args: SeekPreviewEventArgs) => {\n if (this.player.isLive()) {\n let maxTimeShift = this.player.getMaxTimeShift();\n let timeShiftPreview = maxTimeShift - maxTimeShift * (args.position / 100);\n\n this.setTime(timeShiftPreview);\n\n // In case of a live stream the player expects the time passed into the getThumbnail as a wallClockTime and not\n // as a relative timeShift value.\n const convertTimeShiftPreviewToWallClockTime = (targetTimeShift: number): number => {\n const currentTimeShift = this.player.getTimeShift();\n const currentTime = this.player.getCurrentTime();\n\n const wallClockTimeOfLiveEdge = currentTime - currentTimeShift;\n return wallClockTimeOfLiveEdge + targetTimeShift;\n };\n\n const wallClockTime = convertTimeShiftPreviewToWallClockTime(timeShiftPreview);\n this.setThumbnail(this.player.getThumbnail(wallClockTime));\n\n } else {\n let time = this.player.getDuration() * (args.position / 100);\n this.setTime(time);\n\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(this.player, 0);\n const absoluteSeekTarget = time + seekableRangeStart;\n this.setThumbnail(this.player.getThumbnail(absoluteSeekTarget));\n }\n\n if (args.marker) {\n this.setTitleText(args.marker.marker.title);\n } else {\n this.setTitleText(null);\n }\n\n // Remove CSS classes from previous marker\n if (this.appliedMarkerCssClasses.length > 0) {\n this.getDomElement().removeClass(this.appliedMarkerCssClasses.join(' '));\n this.appliedMarkerCssClasses = [];\n }\n\n // Add CSS classes of current marker\n if (args.marker) {\n const cssClasses = (args.marker.marker.cssClasses || []).map(cssClass => this.prefixCss(cssClass));\n this.getDomElement().addClass(cssClasses.join(' '));\n this.appliedMarkerCssClasses = cssClasses;\n }\n };\n\n public setPositionInBounds(seekPositionPx: number, bounds: DOMRect) {\n this.getDomElement().css('left', seekPositionPx + 'px');\n\n // Check parent container as it has a padding that needs to be considered\n const labelBounding = this.container.getDomElement().get(0).parentElement.getBoundingClientRect();\n\n let preventOverflowOffset = 0;\n if (labelBounding.right > bounds.right) {\n preventOverflowOffset = labelBounding.right - bounds.right;\n } else if (labelBounding.left < bounds.left) {\n preventOverflowOffset = labelBounding.left - bounds.left;\n }\n\n if (preventOverflowOffset !== 0) {\n this.getDomElement().css('left', seekPositionPx - preventOverflowOffset + 'px');\n\n this.caret.getDomElement().css('transform', `translateX(${preventOverflowOffset}px)`);\n } else {\n this.caret.getDomElement().css('transform', null);\n }\n }\n\n /**\n * Sets arbitrary text on the label.\n * @param text the text to show on the label\n */\n setText(text: string) {\n this.timeLabel.setText(text);\n }\n\n /**\n * Sets a time to be displayed on the label.\n * @param seconds the time in seconds to display on the label\n */\n setTime(seconds: number) {\n this.setText(StringUtils.secondsToTime(seconds, this.timeFormat));\n }\n\n /**\n * Sets the text on the title label.\n * @param text the text to show on the label\n */\n setTitleText(text = '') {\n this.titleLabel.setText(text);\n }\n\n /**\n * Sets or removes a thumbnail on the label.\n * @param thumbnail the thumbnail to display on the label or null to remove a displayed thumbnail\n */\n setThumbnail(thumbnail: Thumbnail = null) {\n let thumbnailElement = this.thumbnail.getDomElement();\n\n if (thumbnail == null) {\n thumbnailElement.css({\n 'background-image': null,\n 'display': null,\n 'width': null,\n 'height': null,\n });\n }\n else {\n // We use the thumbnail image loader to make sure the thumbnail is loaded and it's size is known before be can\n // calculate the CSS properties and set them on the element.\n this.thumbnailImageLoader.load(thumbnail.url, (url, width, height) => {\n // can be checked like that because x/y/w/h are either all present or none\n // https://www.w3.org/TR/media-frags/#naming-space\n if (thumbnail.x !== undefined) {\n thumbnailElement.css(this.thumbnailCssSprite(thumbnail, width, height));\n } else {\n thumbnailElement.css(this.thumbnailCssSingleImage(thumbnail, width, height));\n }\n });\n }\n }\n\n private thumbnailCssSprite(thumbnail: Thumbnail, width: number, height: number): CssProperties {\n let thumbnailCountX = width / thumbnail.width;\n let thumbnailCountY = height / thumbnail.height;\n\n let thumbnailIndexX = thumbnail.x / thumbnail.width;\n let thumbnailIndexY = thumbnail.y / thumbnail.height;\n\n let sizeX = 100 * thumbnailCountX;\n let sizeY = 100 * thumbnailCountY;\n\n let offsetX = 100 * thumbnailIndexX;\n let offsetY = 100 * thumbnailIndexY;\n\n let aspectRatio = 1 / thumbnail.width * thumbnail.height;\n\n // The thumbnail size is set by setting the CSS 'width' and 'padding-bottom' properties. 'padding-bottom' is\n // used because it is relative to the width and can be used to set the aspect ratio of the thumbnail.\n // A default value for width is set in the stylesheet and can be overwritten from there or anywhere else.\n return {\n 'display': 'inherit',\n 'background-image': `url(${thumbnail.url})`,\n 'padding-bottom': `${100 * aspectRatio}%`,\n 'background-size': `${sizeX}% ${sizeY}%`,\n 'background-position': `-${offsetX}% -${offsetY}%`,\n };\n }\n\n private thumbnailCssSingleImage(thumbnail: Thumbnail, width: number, height: number): CssProperties {\n let aspectRatio = 1 / width * height;\n\n return {\n 'display': 'inherit',\n 'background-image': `url(${thumbnail.url})`,\n 'padding-bottom': `${100 * aspectRatio}%`,\n 'background-size': `100% 100%`,\n 'background-position': `0 0`,\n };\n }\n\n release(): void {\n super.release();\n\n this.uiManager.onSeekPreview.unsubscribe(this.handleSeekPreview);\n }\n}\n","import { ListSelector, ListSelectorConfig } from './listselector';\nimport { DOM } from '../dom';\nimport { i18n } from '../localization/i18n';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { UIContainer } from './uicontainer';\nimport { PlayerUtils } from '../playerutils';\nimport { ViewMode } from './component';\n\nconst DocumentDropdownClosedEvents = [\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'pointermove',\n 'click',\n 'keydown',\n 'keypress',\n 'keyup',\n 'blur',\n];\n\nconst SelectDropdownClosedEvents = [\n 'change',\n 'keyup',\n 'mouseup',\n];\n\nconst DropdownOpenedEvents: [string, (event: Event) => boolean][] = [\n ['click', () => true],\n ['keydown', (event: KeyboardEvent) => [' ', 'ArrowUp', 'ArrowDown'].includes(event.key)],\n ['mousedown', () => true],\n];\n\nconst Timeout = 100;\n\n/**\n * A simple select box providing the possibility to select a single item out of a list of available items.\n *\n * DOM example:\n * <code>\n * <select class='ui-selectbox'>\n * <option value='key'>label</option>\n * ...\n * </select>\n * </code>\n *\n * @category Components\n */\n\nexport class SelectBox extends ListSelector<ListSelectorConfig> {\n private selectElement: DOM | undefined;\n private dropdownCloseListenerTimeoutId = 0;\n private removeDropdownCloseListeners = () => {};\n private uiContainer: UIContainer | undefined;\n private removeDropdownOpenedListeners = () => {};\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-selectbox',\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n this.selectElement = new DOM('select', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'aria-label': i18n.performLocalization(this.config.ariaLabel),\n }, this);\n\n this.onDisabled.subscribe(this.closeDropdown);\n this.onHide.subscribe(this.closeDropdown);\n this.addDropdownOpenedListeners();\n this.updateDomItems();\n\n this.selectElement.on('change', this.onChange);\n\n return this.selectElement;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager) {\n super.configure(player, uimanager);\n this.uiContainer = uimanager.getUI();\n this.uiContainer?.onPlayerStateChange().subscribe(this.onPlayerStateChange);\n }\n\n private readonly onChange = () => {\n let value = this.selectElement.val();\n this.onItemSelectedEvent(value, false);\n };\n\n private getSelectElement() {\n return this.selectElement?.get()?.[0];\n }\n\n protected updateDomItems(selectedValue: string = null) {\n if (this.selectElement === undefined) {\n return;\n }\n\n // Delete all children\n this.selectElement.empty();\n\n // Add updated children\n for (let item of this.items) {\n let optionElement = new DOM('option', {\n 'value': String(item.key),\n }).html(i18n.performLocalization(item.label));\n\n if (item.key === String(selectedValue)) { // convert selectedValue to string to catch 'null'/null case\n optionElement.attr('selected', 'selected');\n }\n\n this.selectElement.append(optionElement);\n }\n }\n\n protected onItemAddedEvent(value: string) {\n super.onItemAddedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemRemovedEvent(value: string) {\n super.onItemRemovedEvent(value);\n this.updateDomItems(this.selectedItem);\n }\n\n protected onItemSelectedEvent(value: string, updateDomItems: boolean = true) {\n super.onItemSelectedEvent(value);\n if (updateDomItems) {\n this.updateDomItems(value);\n }\n }\n\n public readonly closeDropdown = () => {\n const select = this.getSelectElement();\n\n if (select === undefined) {\n return;\n }\n\n select.blur();\n };\n\n private readonly onPlayerStateChange = (_: UIContainer, state: PlayerUtils.PlayerState) => {\n if ([PlayerUtils.PlayerState.Idle, PlayerUtils.PlayerState.Finished].includes(state)) {\n this.closeDropdown();\n }\n };\n\n private onDropdownOpened = () => {\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n this.dropdownCloseListenerTimeoutId = window.setTimeout(() => this.addDropdownCloseListeners(), Timeout);\n this.onViewModeChangedEvent(ViewMode.Persistent);\n };\n\n private onDropdownClosed = () => {\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n this.removeDropdownCloseListeners();\n this.onViewModeChangedEvent(ViewMode.Temporary);\n };\n\n private addDropdownCloseListeners() {\n this.removeDropdownCloseListeners();\n\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n\n DocumentDropdownClosedEvents.forEach(event => document.addEventListener(event, this.onDropdownClosed, true));\n SelectDropdownClosedEvents.forEach(event => this.selectElement.on(event, this.onDropdownClosed, true));\n\n this.removeDropdownCloseListeners = () => {\n DocumentDropdownClosedEvents.forEach(event => document.removeEventListener(event, this.onDropdownClosed, true));\n SelectDropdownClosedEvents.forEach(event => this.selectElement.off(event, this.onDropdownClosed, true));\n };\n }\n\n private addDropdownOpenedListeners() {\n const removeListenerFunctions: (() => void)[] = [];\n\n this.removeDropdownOpenedListeners();\n\n for (const [event, filter] of DropdownOpenedEvents) {\n const listener = (event: Event) => {\n if (filter(event)) {\n this.onDropdownOpened();\n }\n };\n\n removeListenerFunctions.push(() => this.selectElement.off(event, listener, true));\n this.selectElement.on(event, listener, true);\n }\n\n this.removeDropdownOpenedListeners = () => {\n for (const remove of removeListenerFunctions) {\n remove();\n }\n };\n }\n\n release() {\n super.release();\n\n this.removeDropdownCloseListeners();\n this.removeDropdownOpenedListeners();\n clearTimeout(this.dropdownCloseListenerTimeoutId);\n }\n}\n","import { Container, ContainerConfig } from './container';\nimport { SelectBox } from './selectbox';\nimport { UIInstanceManager } from '../uimanager';\nimport { Timeout } from '../timeout';\nimport { Event, EventDispatcher, NoArgs } from '../eventdispatcher';\nimport { SettingsPanelPage } from './settingspanelpage';\nimport { SettingsPanelItem } from './settingspanelitem';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { Component, ComponentConfig } from './component';\n\n/**\n * Configuration interface for a {@link SettingsPanel}.\n *\n * @category Configs\n */\nexport interface SettingsPanelConfig extends ContainerConfig {\n /**\n * The delay in milliseconds after which the settings panel will be hidden when there is no user interaction.\n * Set to -1 to disable automatic hiding.\n * Default: 3 seconds (3000)\n */\n hideDelay?: number;\n\n /**\n * Flag to specify if there should be an animation when switching SettingsPanelPages.\n * Default: true\n */\n pageTransitionAnimation?: boolean;\n}\n\nenum NavigationDirection {\n Forwards,\n Backwards,\n}\n\n/**\n * A panel containing a list of {@link SettingsPanelPage items}.\n *\n * To configure pages just pass them in the components array.\n *\n * Example:\n * let settingsPanel = new SettingsPanel({\n * hidden: true,\n * });\n *\n * let settingsPanelPage = new SettingsPanelPage({\n * components: […]\n * });\n *\n * let secondSettingsPanelPage = new SettingsPanelPage({\n * components: […]\n * });\n *\n * settingsPanel.addComponent(settingsPanelPage);\n * settingsPanel.addComponent(secondSettingsPanelPage);\n *\n * For an example how to navigate between pages @see SettingsPanelPageNavigatorButton\n *\n * @category Components\n */\nexport class SettingsPanel extends Container<SettingsPanelConfig> {\n\n private static readonly CLASS_ACTIVE_PAGE = 'active';\n\n // navigation handling\n private activePage: SettingsPanelPage;\n private navigationStack: SettingsPanelPage[] = [];\n\n private settingsPanelEvents = {\n onSettingsStateChanged: new EventDispatcher<SettingsPanel, NoArgs>(),\n };\n\n private hideTimeout: Timeout;\n\n constructor(config: SettingsPanelConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settings-panel',\n hideDelay: 3000,\n pageTransitionAnimation: true,\n } as SettingsPanelConfig, this.config);\n\n this.activePage = this.getRootPage();\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n\n uimanager.onControlsHide.subscribe(() => this.hideHoveredSelectBoxes());\n uimanager.onComponentViewModeChanged.subscribe((_, { mode }) => this.trackComponentViewMode(mode));\n\n if (config.hideDelay > -1) {\n this.hideTimeout = new Timeout(config.hideDelay, () => {\n this.hide();\n this.hideHoveredSelectBoxes();\n });\n this.getDomElement().on('mouseenter', () => {\n // On mouse enter clear the timeout\n this.hideTimeout.clear();\n });\n this.getDomElement().on('mouseleave', () => {\n // On mouse leave activate the timeout\n this.hideTimeout.reset();\n });\n this.getDomElement().on('focusin', () => {\n this.hideTimeout.clear();\n });\n this.getDomElement().on('focusout', () => {\n this.hideTimeout.reset();\n });\n }\n\n this.onHide.subscribe(() => {\n if (config.hideDelay > -1) {\n // Clear timeout when hidden from outside\n this.hideTimeout.clear();\n }\n\n // Since we don't reset the actual navigation here we need to simulate a onInactive event in case some panel\n // needs to do something when they become invisible / inactive.\n this.activePage.onInactiveEvent();\n });\n\n this.onShow.subscribe(() => {\n // Reset navigation when te panel gets visible to avoid a weird animation when hiding\n this.resetNavigation(true);\n // Since we don't need to navigate to the root page again we need to fire the onActive event when the settings\n // panel gets visible.\n this.activePage.onActiveEvent();\n\n if (config.hideDelay > -1) {\n // Activate timeout when shown\n this.hideTimeout.start();\n }\n });\n\n // pass event from root page through\n this.getRootPage().onSettingsStateChanged.subscribe(() => {\n this.onSettingsStateChangedEvent();\n });\n\n this.updateActivePageClass();\n }\n\n /**\n * Returns the current active / visible page\n * @return {SettingsPanelPage}\n */\n getActivePage(): SettingsPanelPage {\n return this.activePage;\n }\n\n /**\n * Sets the\n * @deprecated Use {@link setActivePage} instead\n * @param index\n */\n setActivePageIndex(index: number): void {\n this.setActivePage(this.getPages()[index]);\n }\n\n /**\n * Adds the passed page to the navigation stack and makes it visible.\n * Use {@link popSettingsPanelPage} to navigate backwards.\n *\n * Results in no-op if the target page is the current page.\n * @param targetPage\n */\n setActivePage(targetPage: SettingsPanelPage): void {\n if (targetPage === this.getActivePage()) {\n console.warn('Page is already the current one ... skipping navigation');\n return;\n }\n\n this.navigateToPage(\n targetPage,\n this.getActivePage(),\n NavigationDirection.Forwards,\n !(this.config as SettingsPanelConfig).pageTransitionAnimation,\n );\n }\n\n /**\n * Resets the navigation stack by navigating back to the root page and displaying it.\n */\n popToRootSettingsPanelPage(): void {\n this.resetNavigation((this.config as SettingsPanelConfig).pageTransitionAnimation);\n }\n\n /**\n * Removes the current page from the navigation stack and makes the previous one visible.\n * Results in a no-op if we are already on the root page.\n */\n popSettingsPanelPage() {\n if (this.navigationStack.length === 0) {\n console.warn('Already on the root page ... skipping navigation');\n return;\n }\n\n let targetPage = this.navigationStack[this.navigationStack.length - 2];\n // The root part isn't part of the navigation stack so handle it explicitly here\n if (!targetPage) {\n targetPage = this.getRootPage();\n }\n\n this.navigateToPage(\n targetPage,\n this.activePage,\n NavigationDirection.Backwards,\n !(this.config as SettingsPanelConfig).pageTransitionAnimation,\n );\n }\n\n /**\n * Checks if there are active settings within the root page of the settings panel.\n * An active setting is a setting that is visible and enabled, which the user can interact with.\n * @returns {boolean} true if there are active settings, false if the panel is functionally empty to a user\n */\n rootPageHasActiveSettings(): boolean {\n return this.getRootPage().hasActiveSettings();\n }\n\n /**\n * Return all configured pages\n * @returns {SettingsPanelPage[]}\n */\n getPages(): SettingsPanelPage[] {\n return <SettingsPanelPage[]>this.config.components.filter(component => component instanceof SettingsPanelPage);\n }\n\n get onSettingsStateChanged(): Event<SettingsPanel, NoArgs> {\n return this.settingsPanelEvents.onSettingsStateChanged.getEvent();\n }\n\n release(): void {\n super.release();\n if (this.hideTimeout) {\n this.hideTimeout.clear();\n }\n }\n\n // Support adding settingsPanelPages after initialization\n addComponent(component: Component<ComponentConfig>) {\n if (this.getPages().length === 0 && component instanceof SettingsPanelPage) {\n this.activePage = component;\n }\n super.addComponent(component);\n }\n\n protected suspendHideTimeout() {\n this.hideTimeout.suspend();\n }\n\n protected resumeHideTimeout() {\n this.hideTimeout.resume(true);\n }\n\n private updateActivePageClass(): void {\n this.getPages().forEach((page: SettingsPanelPage) => {\n if (page === this.activePage) {\n page.getDomElement().addClass(this.prefixCss(SettingsPanel.CLASS_ACTIVE_PAGE));\n } else {\n page.getDomElement().removeClass(this.prefixCss(SettingsPanel.CLASS_ACTIVE_PAGE));\n }\n });\n }\n\n private resetNavigation(resetNavigationOnShow: boolean): void {\n const sourcePage = this.getActivePage();\n const rootPage = this.getRootPage();\n if (sourcePage) {\n // Since the onInactiveEvent was already fired in the onHide we need to suppress it here\n if (!resetNavigationOnShow) {\n sourcePage.onInactiveEvent();\n }\n }\n this.navigationStack = [];\n this.animateNavigation(rootPage, sourcePage, resetNavigationOnShow);\n this.activePage = rootPage;\n this.updateActivePageClass();\n }\n\n private navigateToPage(\n targetPage: SettingsPanelPage,\n sourcePage: SettingsPanelPage,\n direction: NavigationDirection,\n skipAnimation: boolean,\n ): void {\n this.activePage = targetPage;\n\n if (direction === NavigationDirection.Forwards) {\n this.navigationStack.push(targetPage);\n } else {\n this.navigationStack.pop();\n }\n\n this.animateNavigation(targetPage, sourcePage, skipAnimation);\n\n this.updateActivePageClass();\n targetPage.onActiveEvent();\n sourcePage.onInactiveEvent();\n }\n\n /**\n * @param targetPage\n * @param sourcePage\n * @param skipAnimation This is just an internal flag if we want to have an animation. It is set true when we reset\n * the navigation within the onShow callback of the settingsPanel. In this case we don't want an actual animation but\n * the recalculation of the dimension of the settingsPanel.\n * This is independent of the pageTransitionAnimation flag.\n */\n private animateNavigation(targetPage: SettingsPanelPage, sourcePage: SettingsPanelPage, skipAnimation: boolean) {\n if (!(this.config as SettingsPanelConfig).pageTransitionAnimation) {\n return;\n }\n\n const settingsPanelDomElement = this.getDomElement();\n const settingsPanelHTMLElement = this.getDomElement().get(0);\n\n // get current dimension\n const settingsPanelWidth = settingsPanelHTMLElement.scrollWidth;\n const settingsPanelHeight = settingsPanelHTMLElement.scrollHeight;\n\n // calculate target size of the settings panel\n sourcePage.getDomElement().css('display', 'none');\n this.getDomElement().css({ width: '', height: '' }); // let css auto settings kick in again\n\n const targetPageHtmlElement = targetPage.getDomElement().get(0);\n // clone the targetPage DOM element so that we can calculate the width / height how they will be after\n // switching the page. We are using a clone to prevent (mostly styling) side-effects on the real DOM element\n const clone = targetPageHtmlElement.cloneNode(true) as HTMLElement;\n // append to parent so we get the 'real' size\n const containerWrapper = targetPageHtmlElement.parentNode;\n containerWrapper.appendChild(clone);\n // set clone visible\n clone.style.display = 'block';\n\n // collect target dimension\n const targetSettingsPanelWidth = settingsPanelHTMLElement.scrollWidth;\n const targetSettingsPanelHeight = settingsPanelHTMLElement.scrollHeight;\n\n // remove clone from the DOM\n clone.parentElement.removeChild(clone); // .remove() is not working in IE\n sourcePage.getDomElement().css('display', '');\n\n // set the values back to the current ones that the browser animates it (browsers don't animate 'auto' values)\n settingsPanelDomElement.css({\n width: settingsPanelWidth + 'px',\n height: settingsPanelHeight + 'px',\n });\n\n if (!skipAnimation) {\n // We need to force the browser to reflow between setting the width and height that we actually get a animation\n this.forceBrowserReflow();\n }\n\n // set the values to the target dimension\n settingsPanelDomElement.css({\n width: targetSettingsPanelWidth + 'px',\n height: targetSettingsPanelHeight + 'px',\n });\n }\n\n private forceBrowserReflow(): void {\n // Force the browser to reflow the layout\n // https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n this.getDomElement().get(0).offsetLeft;\n }\n\n /**\n * Workaround for IE, Firefox and Safari\n * when the settings panel fades out while an item of a select box is still hovered, the select box will not fade out\n * while the settings panel does. This would leave a floating select box, which is just weird\n */\n private hideHoveredSelectBoxes(): void {\n this.getComputedItems()\n .map(item => item['setting'])\n .filter(component => component instanceof SelectBox)\n .forEach((selectBox: SelectBox) => selectBox.closeDropdown());\n }\n\n // collect all items from all pages (see hideHoveredSelectBoxes)\n private getComputedItems(): SettingsPanelItem[] {\n const allItems: SettingsPanelItem[] = [];\n for (let page of this.getPages()) {\n allItems.push(...page.getItems());\n }\n return allItems;\n }\n\n private getRootPage(): SettingsPanelPage {\n return this.getPages()[0];\n }\n\n protected onSettingsStateChangedEvent() {\n this.settingsPanelEvents.onSettingsStateChanged.dispatch(this);\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {Component, ComponentConfig} from './component';\nimport {Event, EventDispatcher, NoArgs} from '../eventdispatcher';\nimport { Label, LabelConfig } from './label';\nimport {UIInstanceManager} from '../uimanager';\nimport {SelectBox} from './selectbox';\nimport {ListBox} from './listbox';\nimport {VideoQualitySelectBox} from './videoqualityselectbox';\nimport {AudioQualitySelectBox} from './audioqualityselectbox';\nimport {PlaybackSpeedSelectBox} from './playbackspeedselectbox';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { LocalizableText } from '../localization/i18n';\n\n/**\n * An item for a {@link SettingsPanelPage},\n * Containing an optional {@link Label} and a component that configures a setting.\n * If the components is a {@link SelectBox} it will handle the logic of displaying it or not\n *\n * @category Components\n */\nexport class SettingsPanelItem extends Container<ContainerConfig> {\n\n private label: Component<ComponentConfig>;\n private setting: Component<ComponentConfig>;\n\n private settingsPanelItemEvents = {\n onActiveChanged: new EventDispatcher<SettingsPanelItem, NoArgs>(),\n };\n\n constructor(label: LocalizableText | Component<ComponentConfig>, setting: Component<ComponentConfig>, config: ContainerConfig = {}) {\n super(config);\n\n this.setting = setting;\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settings-panel-item',\n role: 'menuitem',\n }, this.config);\n\n if (label !== null) {\n if (label instanceof Component) {\n this.label = label;\n } else {\n this.label = new Label({ text: label, for: this.setting.getConfig().id } as LabelConfig);\n }\n this.addComponent(this.label);\n }\n\n this.addComponent(this.setting);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n if (this.setting instanceof SelectBox || this.setting instanceof ListBox) {\n let handleConfigItemChanged = () => {\n if (!(this.setting instanceof SelectBox) && !(this.setting instanceof ListBox)) {\n return;\n }\n // The minimum number of items that must be available for the setting to be displayed\n // By default, at least two items must be available, else a selection is not possible\n let minItemsToDisplay = 2;\n // Audio/video quality select boxes contain an additional 'auto' mode, which in combination with a single\n // available quality also does not make sense\n if ((this.setting instanceof VideoQualitySelectBox && this.setting.hasAutoItem())\n || this.setting instanceof AudioQualitySelectBox) {\n minItemsToDisplay = 3;\n }\n\n if (this.setting.itemCount() < minItemsToDisplay) {\n // Hide the setting if no meaningful choice is available\n this.hide();\n } else if (this.setting instanceof PlaybackSpeedSelectBox\n && !uimanager.getConfig().playbackSpeedSelectionEnabled) {\n // Hide the PlaybackSpeedSelectBox if disabled in config\n this.hide();\n } else {\n this.show();\n }\n\n // Visibility might have changed and therefore the active state might have changed so we fire the event\n // TODO fire only when state has really changed (e.g. check if visibility has really changed)\n this.onActiveChangedEvent();\n\n this.getDomElement().attr('aria-haspopup', 'true');\n };\n\n this.setting.onItemAdded.subscribe(handleConfigItemChanged);\n this.setting.onItemRemoved.subscribe(handleConfigItemChanged);\n\n // Initialize hidden state\n handleConfigItemChanged();\n }\n }\n\n /**\n * Checks if this settings panel item is active, i.e. visible and enabled and a user can interact with it.\n * @returns {boolean} true if the panel is active, else false\n */\n isActive(): boolean {\n return this.isShown();\n }\n\n protected onActiveChangedEvent() {\n this.settingsPanelItemEvents.onActiveChanged.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the 'active' state of this item changes.\n * @see #isActive\n * @returns {Event<SettingsPanelItem, NoArgs>}\n */\n get onActiveChanged(): Event<SettingsPanelItem, NoArgs> {\n return this.settingsPanelItemEvents.onActiveChanged.getEvent();\n }\n}\n","import {Container, ContainerConfig} from './container';\nimport {SettingsPanelItem} from './settingspanelitem';\nimport {UIInstanceManager} from '../uimanager';\nimport {Event, EventDispatcher, NoArgs} from '../eventdispatcher';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { BrowserUtils } from '../browserutils';\n\n/**\n * A panel containing a list of {@link SettingsPanelItem items} that represent labelled settings.\n *\n * @category Components\n */\nexport class SettingsPanelPage extends Container<ContainerConfig> {\n\n private static readonly CLASS_LAST = 'last';\n\n private settingsPanelPageEvents = {\n onSettingsStateChanged: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n onActive: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n onInactive: new EventDispatcher<SettingsPanelPage, NoArgs>(),\n };\n\n constructor(config: ContainerConfig) {\n super(config);\n\n this.config = this.mergeConfig<ContainerConfig>(config, {\n cssClass: 'ui-settings-panel-page',\n role: 'menu',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n // Fire event when the state of a settings-item has changed\n let settingsStateChangedHandler = () => {\n this.onSettingsStateChangedEvent();\n\n // Attach marker class to last visible item\n let lastShownItem = null;\n for (let component of this.getItems()) {\n component.getDomElement().removeClass(this.prefixCss(SettingsPanelPage.CLASS_LAST));\n if (component.isShown()) {\n lastShownItem = component;\n }\n }\n if (lastShownItem) {\n lastShownItem.getDomElement().addClass(this.prefixCss(SettingsPanelPage.CLASS_LAST));\n }\n };\n for (let component of this.getItems()) {\n component.onActiveChanged.subscribe(settingsStateChangedHandler);\n }\n }\n\n hasActiveSettings(): boolean {\n for (let component of this.getItems()) {\n if (component.isActive()) {\n return true;\n }\n }\n\n return false;\n }\n\n getItems(): SettingsPanelItem[] {\n return <SettingsPanelItem[]>this.config.components.filter(component => component instanceof SettingsPanelItem);\n }\n\n onSettingsStateChangedEvent() {\n this.settingsPanelPageEvents.onSettingsStateChanged.dispatch(this);\n }\n\n get onSettingsStateChanged(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onSettingsStateChanged.getEvent();\n }\n\n onActiveEvent() {\n const activeItems = this.getItems().filter((item) => item.isActive());\n\n this.settingsPanelPageEvents.onActive.dispatch(this);\n // Disable focus for iOS and iPadOS 13. They open select boxes automatically on focus and we want to avoid that.\n if (activeItems.length > 0 && !BrowserUtils.isIOS && !(BrowserUtils.isMacIntel && BrowserUtils.isTouchSupported)) {\n activeItems[0].getDomElement().focusToFirstInput();\n }\n }\n\n get onActive(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onActive.getEvent();\n }\n\n onInactiveEvent() {\n this.settingsPanelPageEvents.onInactive.dispatch(this);\n }\n\n get onInactive(): Event<SettingsPanelPage, NoArgs> {\n return this.settingsPanelPageEvents.onInactive.getEvent();\n }\n}\n","import {UIInstanceManager} from '../uimanager';\nimport {SettingsPanelPageNavigatorButton, SettingsPanelPageNavigatorConfig} from './settingspanelpagenavigatorbutton';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * @category Buttons\n */\nexport class SettingsPanelPageBackButton extends SettingsPanelPageNavigatorButton {\n\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingspanelpagebackbutton',\n text: 'back',\n } as SettingsPanelPageNavigatorConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onClick.subscribe(() => {\n this.popPage();\n });\n }\n}\n","import {Button, ButtonConfig} from './button';\nimport {SettingsPanel} from './settingspanel';\nimport {SettingsPanelPage} from './settingspanelpage';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\n\n/**\n * Configuration interface for a {@link SettingsPanelPageNavigatorButton}\n *\n * @category Configs\n */\nexport interface SettingsPanelPageNavigatorConfig extends ButtonConfig {\n /**\n * Container `SettingsPanel` where the navigation takes place\n */\n container: SettingsPanel;\n /**\n * Page where the button should navigate to\n * If empty it will navigate to the root page (not intended to use as navigate back behavior)\n */\n targetPage?: SettingsPanelPage;\n\n /**\n * WCAG20 standard: Establishes relationships between objects and their label(s)\n */\n ariaLabelledBy?: string;\n}\n\n/**\n * Can be used to navigate between SettingsPanelPages\n *\n * Example:\n * let settingPanelNavigationButton = new SettingsPanelPageNavigatorButton({\n * container: settingsPanel,\n * targetPage: settingsPanelPage,\n * });\n *\n * settingsPanelPage.addComponent(settingPanelNavigationButton);\n *\n * Don't forget to add the settingPanelNavigationButton to the settingsPanelPage.\n *\n * @category Buttons\n */\nexport class SettingsPanelPageNavigatorButton extends Button<SettingsPanelPageNavigatorConfig> {\n private readonly container: SettingsPanel;\n private readonly targetPage?: SettingsPanelPage;\n\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n this.config = this.mergeConfig(config, {} as SettingsPanelPageNavigatorConfig, this.config);\n\n this.container = (this.config as SettingsPanelPageNavigatorConfig).container;\n this.targetPage = (this.config as SettingsPanelPageNavigatorConfig).targetPage;\n }\n\n /**\n * navigate one level back\n */\n popPage() {\n this.container.popSettingsPanelPage();\n }\n\n /**\n * navigate to the target page\n */\n pushTargetPage() {\n this.container.setActivePage(this.targetPage);\n }\n}\n","import {UIInstanceManager} from '../uimanager';\nimport {SettingsPanelPageNavigatorButton, SettingsPanelPageNavigatorConfig} from './settingspanelpagenavigatorbutton';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * @category Buttons\n */\nexport class SettingsPanelPageOpenButton extends SettingsPanelPageNavigatorButton {\n constructor(config: SettingsPanelPageNavigatorConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingspanelpageopenbutton',\n text: i18n.getLocalizer('open'),\n role: 'menuitem',\n } as SettingsPanelPageNavigatorConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.getDomElement().attr('aria-haspopup', 'true');\n this.getDomElement().attr('aria-owns', this.config.targetPage.getConfig().id);\n\n this.onClick.subscribe(() => {\n this.pushTargetPage();\n });\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {SettingsPanel} from './settingspanel';\nimport {UIInstanceManager} from '../uimanager';\nimport {Component, ComponentConfig} from './component';\nimport {ArrayUtils} from '../arrayutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link SettingsToggleButton}.\n *\n * @category Configs\n */\nexport interface SettingsToggleButtonConfig extends ToggleButtonConfig {\n /**\n * The settings panel whose visibility the button should toggle.\n */\n settingsPanel: SettingsPanel;\n\n /**\n * Decides if the button should be automatically hidden when the settings panel does not contain any active settings.\n * Default: true\n */\n autoHideWhenNoActiveSettings?: boolean;\n}\n\n/**\n * A button that toggles visibility of a settings panel.\n *\n * @category Buttons\n */\nexport class SettingsToggleButton extends ToggleButton<SettingsToggleButtonConfig> {\n\n private visibleSettingsPanels: SettingsPanel[] = [];\n\n constructor(config: SettingsToggleButtonConfig) {\n super(config);\n\n if (!config.settingsPanel) {\n throw new Error('Required SettingsPanel is missing');\n }\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-settingstogglebutton',\n text: i18n.getLocalizer('settings'),\n settingsPanel: null,\n autoHideWhenNoActiveSettings: true,\n role: 'pop-up button',\n }, <SettingsToggleButtonConfig>this.config);\n\n /**\n * WCAG20 standard defines which popup menu (element id) is owned by the button\n */\n this.getDomElement().attr('aria-owns', config.settingsPanel.getActivePage().getConfig().id);\n\n /**\n * WCAG20 standard defines that a button has a popup menu bound to it\n */\n this.getDomElement().attr('aria-haspopup', 'true');\n\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let settingsPanel = config.settingsPanel;\n\n this.onClick.subscribe(() => {\n // only hide other `SettingsPanel`s if a new one will be opened\n if (!settingsPanel.isShown()) {\n // Hide all open SettingsPanels before opening this button's panel\n // (We need to iterate a copy because hiding them will automatically remove themselves from the array\n // due to the subscribeOnce above)\n this.visibleSettingsPanels.slice().forEach(settingsPanel => settingsPanel.hide());\n }\n settingsPanel.toggleHidden();\n });\n settingsPanel.onShow.subscribe(() => {\n // Set toggle status to on when the settings panel shows\n this.on();\n });\n settingsPanel.onHide.subscribe(() => {\n // Set toggle status to off when the settings panel hides\n this.off();\n });\n\n // Ensure that only one `SettingPanel` is visible at once\n // Keep track of shown SettingsPanels\n uimanager.onComponentShow.subscribe((sender: Component<ComponentConfig>) => {\n if (sender instanceof SettingsPanel) {\n this.visibleSettingsPanels.push(sender);\n sender.onHide.subscribeOnce(() => ArrayUtils.remove(this.visibleSettingsPanels, sender));\n }\n });\n\n // Handle automatic hiding of the button if there are no settings for the user to interact with\n if (config.autoHideWhenNoActiveSettings) {\n // Setup handler to show/hide button when the settings change\n let settingsPanelItemsChangedHandler = () => {\n if (settingsPanel.rootPageHasActiveSettings()) {\n if (this.isHidden()) {\n this.show();\n }\n } else {\n if (this.isShown()) {\n this.hide();\n }\n }\n };\n // Wire the handler to the event\n settingsPanel.onSettingsStateChanged.subscribe(settingsPanelItemsChangedHandler);\n // Call handler for first init at startup\n settingsPanelItemsChangedHandler();\n }\n }\n}\n","import {Component, ComponentConfig} from './component';\n\n/**\n * A dummy component that just reserves some space and does nothing else.\n *\n * @category Components\n */\nexport class Spacer extends Component<ComponentConfig> {\n\n constructor(config: ComponentConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-spacer',\n }, this.config);\n }\n\n\n protected onShowEvent(): void {\n // disable event firing by overwriting and not calling super\n }\n\n protected onHideEvent(): void {\n // disable event firing by overwriting and not calling super\n }\n\n protected onHoverChangedEvent(hovered: boolean): void {\n // disable event firing by overwriting and not calling super\n }\n}","import {ListBox} from './listbox';\nimport {UIInstanceManager} from '../uimanager';\nimport {SubtitleSwitchHandler} from '../subtitleutils';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * A element that is similar to a select box where the user can select a subtitle\n *\n * @category Components\n */\nexport class SubtitleListBox extends ListBox {\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new SubtitleSwitchHandler(player, this, uimanager);\n }\n}\n","import { Container, ContainerConfig } from './container';\nimport { UIInstanceManager } from '../uimanager';\nimport { Label, LabelConfig } from './label';\nimport { ComponentConfig, Component } from './component';\nimport { ControlBar } from './controlbar';\nimport { EventDispatcher } from '../eventdispatcher';\nimport { DOM, Size } from '../dom';\nimport { PlayerAPI, SubtitleCueEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { VttUtils } from '../vttutils';\nimport { VTTProperties } from 'bitmovin-player/types/subtitles/vtt/API';\n\ninterface SubtitleCropDetectionResult {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n}\n\n/**\n * Overlays the player to display subtitles.\n *\n * @category Components\n */\nexport class SubtitleOverlay extends Container<ContainerConfig> {\n\n private subtitleManager: ActiveSubtitleManager;\n private previewSubtitleActive: boolean;\n private previewSubtitle: SubtitleLabel;\n\n private preprocessLabelEventCallback = new EventDispatcher<SubtitleCueEvent, SubtitleLabel>();\n private subtitleContainerManager: SubtitleRegionContainerManager;\n\n private static readonly CLASS_CONTROLBAR_VISIBLE = 'controlbar-visible';\n private static readonly CLASS_CEA_608 = 'cea608';\n\n // The number of rows in a cea608 grid\n private static readonly CEA608_NUM_ROWS = 15;\n // The number of columns in a cea608 grid\n private static readonly CEA608_NUM_COLUMNS = 32;\n // The offset in percent for one row (which is also the height of a row)\n private static readonly CEA608_ROW_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_ROWS;\n // The offset in percent for one column (which is also the width of a column)\n private static readonly CEA608_COLUMN_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_COLUMNS;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.previewSubtitleActive = false;\n this.previewSubtitle = new SubtitleLabel({ text: i18n.getLocalizer('subtitle.example') });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitle-overlay',\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let subtitleManager = new ActiveSubtitleManager();\n this.subtitleManager = subtitleManager;\n\n this.subtitleContainerManager = new SubtitleRegionContainerManager(this);\n\n player.on(player.exports.PlayerEvent.CueEnter, (event: SubtitleCueEvent) => {\n const label = this.generateLabel(event);\n subtitleManager.cueEnter(event, label);\n\n this.preprocessLabelEventCallback.dispatch(event, label);\n\n if (this.previewSubtitleActive) {\n this.subtitleContainerManager.removeLabel(this.previewSubtitle);\n }\n\n this.show();\n\n this.subtitleContainerManager.addLabel(label, this.getDomElement().size());\n this.updateComponents();\n\n if (uimanager.getConfig().forceSubtitlesIntoViewContainer) {\n this.handleSubtitleCropping(label);\n }\n });\n\n player.on(player.exports.PlayerEvent.CueUpdate, (event: SubtitleCueEvent) => {\n const label = this.generateLabel(event);\n const labelToReplace = subtitleManager.cueUpdate(event, label);\n\n this.preprocessLabelEventCallback.dispatch(event, label);\n\n if (labelToReplace) {\n this.subtitleContainerManager.replaceLabel(labelToReplace, label);\n }\n\n if (uimanager.getConfig().forceSubtitlesIntoViewContainer) {\n this.handleSubtitleCropping(label);\n }\n });\n\n player.on(player.exports.PlayerEvent.CueExit, (event: SubtitleCueEvent) => {\n let labelToRemove = subtitleManager.cueExit(event);\n\n if (labelToRemove) {\n this.subtitleContainerManager.removeLabel(labelToRemove);\n this.updateComponents();\n }\n\n if (!subtitleManager.hasCues) {\n if (!this.previewSubtitleActive) {\n this.hide();\n } else {\n this.subtitleContainerManager.addLabel(this.previewSubtitle);\n this.updateComponents();\n }\n }\n });\n\n let subtitleClearHandler = () => {\n this.hide();\n this.subtitleContainerManager.clear();\n subtitleManager.clear();\n this.removeComponents();\n this.updateComponents();\n };\n\n const clearInactiveCues = () => {\n const removedActiveCues = subtitleManager.clearInactiveCues(player.getCurrentTime());\n removedActiveCues.forEach(toRemove => {\n this.subtitleContainerManager.removeLabel(toRemove.label);\n });\n };\n\n player.on(player.exports.PlayerEvent.AudioChanged, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.SubtitleDisabled, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.Seeked, clearInactiveCues);\n player.on(player.exports.PlayerEvent.TimeShifted, clearInactiveCues);\n player.on(player.exports.PlayerEvent.PlaybackFinished, subtitleClearHandler);\n player.on(player.exports.PlayerEvent.SourceUnloaded, subtitleClearHandler);\n\n uimanager.onComponentShow.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof ControlBar) {\n this.getDomElement().addClass(this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE));\n }\n });\n uimanager.onComponentHide.subscribe((component: Component<ComponentConfig>) => {\n if (component instanceof ControlBar) {\n this.getDomElement().removeClass(this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE));\n }\n });\n\n this.configureCea608Captions(player, uimanager);\n // Init\n subtitleClearHandler();\n }\n\n detectCroppedSubtitleLabel(\n labelElement: HTMLElement,\n ): SubtitleCropDetectionResult {\n const parent = this.getDomElement().get(0);\n\n const childRect = labelElement.getBoundingClientRect();\n const parentRect = parent.getBoundingClientRect();\n\n return {\n top: childRect.top < parentRect.top,\n right: childRect.right > parentRect.right,\n bottom: childRect.bottom > parentRect.bottom,\n left: childRect.left < parentRect.left,\n };\n }\n\n handleSubtitleCropping(label: SubtitleLabel) {\n const labelDomElement = label.getDomElement();\n const cropDetection = this.detectCroppedSubtitleLabel(\n labelDomElement.get(0),\n );\n\n if (cropDetection.top) {\n labelDomElement.css('top', '0');\n labelDomElement.removeCss('bottom');\n }\n\n if (cropDetection.right) {\n labelDomElement.css('right', '0');\n labelDomElement.removeCss('left');\n }\n\n if (cropDetection.bottom) {\n labelDomElement.css('bottom', '0');\n labelDomElement.removeCss('top');\n }\n\n if (cropDetection.left) {\n labelDomElement.css('left', '0');\n labelDomElement.removeCss('right');\n }\n }\n\n generateLabel(event: SubtitleCueEvent): SubtitleLabel {\n // Sanitize cue data (must be done before the cue ID is generated in subtitleManager.cueEnter / update)\n if (event.position) {\n // Sometimes the positions are undefined, we assume them to be zero\n event.position.row = event.position.row || 0;\n event.position.column = event.position.column || 0;\n }\n\n const label = new SubtitleLabel({\n // Prefer the HTML subtitle text if set, else try generating a image tag as string from the image attribute,\n // else use the plain text\n text: event.html || ActiveSubtitleManager.generateImageTagText(event.image) || event.text,\n vtt: event.vtt,\n region: event.region,\n regionStyle: event.regionStyle,\n });\n\n return label;\n }\n\n configureCea608Captions(player: PlayerAPI, uimanager: UIInstanceManager): void {\n // The calculated font size\n let fontSize = 0;\n // The required letter spacing spread the text characters evenly across the grid\n let fontLetterSpacing = 0;\n // Flag telling if a font size calculation is required of if the current values are valid\n let fontSizeCalculationRequired = true;\n // Flag telling if the CEA-608 mode is enabled\n let enabled = false;\n\n const updateCEA608FontSize = () => {\n const dummyLabel = new SubtitleLabel({ text: 'X' });\n dummyLabel.getDomElement().css({\n // By using a large font size we do not need to use multiple letters and can get still an\n // accurate measurement even though the returned size is an integer value\n 'font-size': '200px',\n 'line-height': '200px',\n 'visibility': 'hidden',\n });\n this.addComponent(dummyLabel);\n this.updateComponents();\n this.show();\n\n const dummyLabelCharWidth = dummyLabel.getDomElement().width();\n const dummyLabelCharHeight = dummyLabel.getDomElement().height();\n const fontSizeRatio = dummyLabelCharWidth / dummyLabelCharHeight;\n\n this.removeComponent(dummyLabel);\n this.updateComponents();\n if (!this.subtitleManager.hasCues) {\n this.hide();\n }\n\n // We subtract 1px here to avoid line breaks at the right border of the subtitle overlay that can happen\n // when texts contain whitespaces. It's probably some kind of pixel rounding issue in the browser's\n // layouting, but the actual reason could not be determined. Aiming for a target width - 1px would work in\n // most browsers, but Safari has a \"quantized\" font size rendering with huge steps in between so we need\n // to subtract some more pixels to avoid line breaks there as well.\n const subtitleOverlayWidth = this.getDomElement().width() - 10;\n const subtitleOverlayHeight = this.getDomElement().height();\n\n // The size ratio of the letter grid\n const fontGridSizeRatio = (dummyLabelCharWidth * SubtitleOverlay.CEA608_NUM_COLUMNS) /\n (dummyLabelCharHeight * SubtitleOverlay.CEA608_NUM_ROWS);\n // The size ratio of the available space for the grid\n const subtitleOverlaySizeRatio = subtitleOverlayWidth / subtitleOverlayHeight;\n\n if (subtitleOverlaySizeRatio > fontGridSizeRatio) {\n // When the available space is wider than the text grid, the font size is simply\n // determined by the height of the available space.\n fontSize = subtitleOverlayHeight / SubtitleOverlay.CEA608_NUM_ROWS;\n\n // Calculate the additional letter spacing required to evenly spread the text across the grid's width\n const gridSlotWidth = subtitleOverlayWidth / SubtitleOverlay.CEA608_NUM_COLUMNS;\n const fontCharWidth = fontSize * fontSizeRatio;\n fontLetterSpacing = gridSlotWidth - fontCharWidth;\n } else {\n // When the available space is not wide enough, texts would vertically overlap if we take\n // the height as a base for the font size, so we need to limit the height. We do that\n // by determining the font size by the width of the available space.\n fontSize = subtitleOverlayWidth / SubtitleOverlay.CEA608_NUM_COLUMNS / fontSizeRatio;\n fontLetterSpacing = 0;\n }\n\n // Update font-size of all active subtitle labels\n for (let label of this.getComponents()) {\n if (label instanceof SubtitleLabel) {\n label.getDomElement().css({\n 'font-size': `${fontSize}px`,\n 'letter-spacing': `${fontLetterSpacing}px`,\n });\n }\n }\n };\n\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n if (enabled) {\n updateCEA608FontSize();\n } else {\n fontSizeCalculationRequired = true;\n }\n });\n\n this.preprocessLabelEventCallback.subscribe((event: SubtitleCueEvent, label: SubtitleLabel) => {\n const isCEA608 = event.position != null;\n if (!isCEA608) {\n // Skip all non-CEA608 cues\n return;\n }\n\n if (!enabled) {\n enabled = true;\n this.getDomElement().addClass(this.prefixCss(SubtitleOverlay.CLASS_CEA_608));\n\n // We conditionally update the font size by this flag here to avoid updating every time a subtitle\n // is added into an empty overlay. Because we reset the overlay when all subtitles are gone, this\n // would trigger an unnecessary update every time, but it's only required under certain conditions,\n // e.g. after the player size has changed.\n if (fontSizeCalculationRequired) {\n updateCEA608FontSize();\n fontSizeCalculationRequired = false;\n }\n }\n\n label.getDomElement().css({\n 'left': `${event.position.column * SubtitleOverlay.CEA608_COLUMN_OFFSET}%`,\n 'top': `${event.position.row * SubtitleOverlay.CEA608_ROW_OFFSET}%`,\n 'font-size': `${fontSize}px`,\n 'letter-spacing': `${fontLetterSpacing}px`,\n });\n });\n\n const reset = () => {\n this.getDomElement().removeClass(this.prefixCss(SubtitleOverlay.CLASS_CEA_608));\n enabled = false;\n };\n\n player.on(player.exports.PlayerEvent.CueExit, () => {\n if (!this.subtitleManager.hasCues) {\n // Disable CEA-608 mode when all subtitles are gone (to allow correct formatting and\n // display of other types of subtitles, e.g. the formatting preview subtitle)\n reset();\n }\n });\n\n player.on(player.exports.PlayerEvent.SourceUnloaded, reset);\n player.on(player.exports.PlayerEvent.SubtitleEnabled, reset);\n player.on(player.exports.PlayerEvent.SubtitleDisabled, reset);\n }\n\n enablePreviewSubtitleLabel(): void {\n if (!this.subtitleManager.hasCues) {\n this.previewSubtitleActive = true;\n this.subtitleContainerManager.addLabel(this.previewSubtitle);\n this.updateComponents();\n this.show();\n }\n }\n\n removePreviewSubtitleLabel(): void {\n if (this.previewSubtitleActive) {\n this.previewSubtitleActive = false;\n this.subtitleContainerManager.removeLabel(this.previewSubtitle);\n this.updateComponents();\n }\n }\n}\n\ninterface ActiveSubtitleCue {\n event: SubtitleCueEvent;\n label: SubtitleLabel;\n}\n\ninterface ActiveSubtitleCueMap {\n [id: string]: ActiveSubtitleCue[];\n}\n\ninterface SubtitleLabelConfig extends LabelConfig {\n vtt?: VTTProperties;\n region?: string;\n regionStyle?: string;\n}\n\nexport class SubtitleLabel extends Label<SubtitleLabelConfig> {\n\n constructor(config: SubtitleLabelConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitle-label',\n }, this.config);\n }\n\n get vtt(): VTTProperties {\n return this.config.vtt;\n }\n\n get region(): string {\n return this.config.region;\n }\n\n get regionStyle(): string {\n return this.config.regionStyle;\n }\n}\n\nclass ActiveSubtitleManager {\n\n private activeSubtitleCueMap: ActiveSubtitleCueMap;\n private activeSubtitleCueCount: number;\n\n constructor() {\n this.activeSubtitleCueMap = {};\n this.activeSubtitleCueCount = 0;\n }\n\n /**\n * Calculates a unique ID for a subtitle cue, which is needed to associate an CueEnter with its CueExit\n * event so we can remove the correct subtitle in CueExit when multiple subtitles are active at the same time.\n * The start time plus the text should make a unique identifier, and in the only case where a collision\n * can happen, two similar texts will be displayed at a similar time and a similar position (or without position).\n * The start time should always be known, because it is required to schedule the CueEnter event. The end time\n * must not necessarily be known and therefore cannot be used for the ID.\n * @param event\n * @return {string}\n */\n private static calculateId(event: SubtitleCueEvent): string {\n let id = event.start + '-' + event.text;\n\n if (event.position) {\n id += '-' + event.position.row + '-' + event.position.column;\n }\n\n return id;\n }\n\n cueEnter(event: SubtitleCueEvent, label: SubtitleLabel): void {\n this.addCueToMap(event, label);\n }\n\n cueUpdate(event: SubtitleCueEvent, label: SubtitleLabel): SubtitleLabel | undefined {\n const labelToReplace = this.popCueFromMap(event);\n\n if (labelToReplace) {\n this.addCueToMap(event, label);\n return labelToReplace;\n }\n\n return undefined;\n }\n\n private addCueToMap(event: SubtitleCueEvent, label: SubtitleLabel): void {\n let id = ActiveSubtitleManager.calculateId(event);\n\n // Create array for id if it does not exist\n this.activeSubtitleCueMap[id] = this.activeSubtitleCueMap[id] || [];\n\n // Add cue\n this.activeSubtitleCueMap[id].push({ event, label });\n this.activeSubtitleCueCount++;\n }\n\n private popCueFromMap(event: SubtitleCueEvent): SubtitleLabel | undefined {\n let id = ActiveSubtitleManager.calculateId(event);\n let activeSubtitleCues = this.activeSubtitleCueMap[id];\n\n if (activeSubtitleCues && activeSubtitleCues.length > 0) {\n // Remove cue\n /* We apply the FIFO approach here and remove the oldest cue from the associated id. When there are multiple cues\n * with the same id, there is no way to know which one of the cues is to be deleted, so we just hope that FIFO\n * works fine. Theoretically it can happen that two cues with colliding ids are removed at different times, in\n * the wrong order. This rare case has yet to be observed. If it ever gets an issue, we can take the unstable\n * cue end time (which can change between CueEnter and CueExit IN CueUpdate) and use it as an\n * additional hint to try and remove the correct one of the colliding cues.\n */\n let activeSubtitleCue = activeSubtitleCues.shift();\n this.activeSubtitleCueCount--;\n\n return activeSubtitleCue.label;\n }\n }\n\n /**\n * Removes all active cues which don't enclose the given time\n * @param time the time for which subtitles should remain\n */\n public clearInactiveCues(time: number): ActiveSubtitleCue[] {\n const removedCues: ActiveSubtitleCue[] = [];\n Object.keys(this.activeSubtitleCueMap).forEach(key => {\n const activeCues = this.activeSubtitleCueMap[key];\n activeCues.forEach(cue => {\n if (time < cue.event.start || time > cue.event.end) {\n this.popCueFromMap(cue.event);\n removedCues.push(cue);\n }\n });\n });\n return removedCues;\n }\n\n static generateImageTagText(imageData: string): string | undefined {\n if (!imageData) {\n return;\n }\n\n const imgTag = new DOM('img', {\n src: imageData,\n });\n imgTag.css('width', '100%');\n return imgTag.get(0).outerHTML; // return the html as string\n }\n\n /**\n * Returns the label associated with an already added cue.\n * @param event\n * @return {SubtitleLabel}\n */\n getCues(event: SubtitleCueEvent): SubtitleLabel[] | undefined {\n let id = ActiveSubtitleManager.calculateId(event);\n let activeSubtitleCues = this.activeSubtitleCueMap[id];\n if (activeSubtitleCues && activeSubtitleCues.length > 0) {\n return activeSubtitleCues.map((cue) => cue.label);\n }\n }\n\n /**\n * Removes the subtitle cue from the manager and returns the label that should be removed from the subtitle overlay,\n * or null if there is no associated label existing (e.g. because all labels have been {@link #clear cleared}.\n * @param event\n * @return {SubtitleLabel|null}\n */\n cueExit(event: SubtitleCueEvent): SubtitleLabel {\n return this.popCueFromMap(event);\n }\n\n /**\n * Returns the number of active subtitle cues.\n * @return {number}\n */\n get cueCount(): number {\n // We explicitly count the cues to save an Array.reduce on every cueCount call (which can happen frequently)\n return this.activeSubtitleCueCount;\n }\n\n /**\n * Returns true if there are active subtitle cues, else false.\n * @return {boolean}\n */\n get hasCues(): boolean {\n return this.cueCount > 0;\n }\n\n /**\n * Removes all subtitle cues from the manager.\n */\n clear(): void {\n this.activeSubtitleCueMap = {};\n this.activeSubtitleCueCount = 0;\n }\n}\n\nexport class SubtitleRegionContainerManager {\n private subtitleRegionContainers: { [regionName: string]: SubtitleRegionContainer } = {};\n\n /**\n * @param subtitleOverlay Reference to the subtitle overlay for adding and removing the containers.\n */\n constructor(private subtitleOverlay: SubtitleOverlay) {\n this.subtitleOverlay = subtitleOverlay;\n }\n\n private getRegion(label: SubtitleLabel): { regionContainerId: string, regionName: string } {\n if (label.vtt) {\n return {\n regionContainerId: label.vtt.region && label.vtt.region.id ? label.vtt.region.id : 'vtt',\n regionName: 'vtt',\n };\n }\n\n return {\n regionContainerId: label.region || 'default',\n regionName: label.region || 'default',\n };\n }\n\n /**\n * Creates and wraps a subtitle label into a container div based on the subtitle region.\n * If the subtitle has positioning information it is added to the container.\n * @param label The subtitle label to wrap\n */\n addLabel(label: SubtitleLabel, overlaySize?: Size): void {\n const { regionContainerId, regionName } = this.getRegion(label);\n const cssClasses = [`subtitle-position-${regionName}`];\n\n if (label.vtt && label.vtt.region) {\n cssClasses.push(`vtt-region-${label.vtt.region.id}`);\n }\n\n if (!this.subtitleRegionContainers[regionContainerId]) {\n const regionContainer = new SubtitleRegionContainer({\n cssClasses,\n });\n\n this.subtitleRegionContainers[regionContainerId] = regionContainer;\n\n if (label.regionStyle) {\n regionContainer.getDomElement().attr('style', label.regionStyle);\n } else if (label.vtt && !label.vtt.region) {\n /**\n * If there is no region present to wrap the Cue Box, the Cue box becomes the\n * region itself. Therefore the positioning values have to come from the box.\n */\n regionContainer.getDomElement().css('position', 'static');\n } else {\n // getDomElement needs to be called at least once to ensure the component exists\n regionContainer.getDomElement();\n }\n\n for (const regionContainerId in this.subtitleRegionContainers) {\n this.subtitleOverlay.addComponent(this.subtitleRegionContainers[regionContainerId]);\n }\n }\n\n this.subtitleRegionContainers[regionContainerId].addLabel(label, overlaySize);\n }\n\n replaceLabel(previousLabel: SubtitleLabel, newLabel: SubtitleLabel): void {\n const { regionContainerId } = this.getRegion(previousLabel);\n\n this.subtitleRegionContainers[regionContainerId].removeLabel(previousLabel);\n this.subtitleRegionContainers[regionContainerId].addLabel(newLabel);\n }\n\n /**\n * Removes a subtitle label from a container.\n */\n removeLabel(label: SubtitleLabel): void {\n let regionContainerId;\n\n if (label.vtt) {\n regionContainerId = label.vtt.region && label.vtt.region.id ? label.vtt.region.id : 'vtt';\n } else {\n regionContainerId = label.region || 'default';\n }\n\n this.subtitleRegionContainers[regionContainerId].removeLabel(label);\n\n // Remove container if no more labels are displayed\n if (this.subtitleRegionContainers[regionContainerId].isEmpty()) {\n this.subtitleOverlay.removeComponent(this.subtitleRegionContainers[regionContainerId]);\n delete this.subtitleRegionContainers[regionContainerId];\n }\n }\n\n /**\n * Removes all subtitle containers.\n */\n clear(): void {\n for (const regionName in this.subtitleRegionContainers) {\n this.subtitleOverlay.removeComponent(this.subtitleRegionContainers[regionName]);\n }\n\n this.subtitleRegionContainers = {};\n }\n}\n\nexport class SubtitleRegionContainer extends Container<ContainerConfig> {\n private labelCount = 0;\n\n constructor(config: ContainerConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'subtitle-region-container',\n }, this.config);\n }\n\n addLabel(labelToAdd: SubtitleLabel, overlaySize?: Size) {\n this.labelCount++;\n\n if (labelToAdd.vtt) {\n if (labelToAdd.vtt.region && overlaySize) {\n VttUtils.setVttRegionStyles(this, labelToAdd.vtt.region, overlaySize);\n }\n\n VttUtils.setVttCueBoxStyles(labelToAdd, overlaySize);\n }\n\n this.addComponent(labelToAdd);\n this.updateComponents();\n }\n\n removeLabel(labelToRemove: SubtitleLabel): void {\n this.labelCount--;\n this.removeComponent(labelToRemove);\n this.updateComponents();\n }\n\n public isEmpty(): boolean {\n return this.labelCount === 0;\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport {SubtitleSwitchHandler} from '../subtitleutils';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between available subtitle and caption tracks.\n *\n * @category Components\n */\nexport class SubtitleSelectBox extends SelectBox {\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitleselectbox'],\n ariaLabel: i18n.getLocalizer('subtitle.select'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n new SubtitleSwitchHandler(player, this, uimanager);\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background colors.\n *\n * @category Components\n */\nexport class BackgroundColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsbackgroundcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.backgroundColor.isSet() && this.settingsManager.backgroundOpacity.isSet()) {\n this.toggleOverlayClass(\n 'bgcolor-' + this.settingsManager.backgroundColor.value + this.settingsManager.backgroundOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.backgroundColor.value = key;\n });\n\n this.settingsManager.backgroundColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.backgroundColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.backgroundOpacity.clear();\n } else if (!this.settingsManager.backgroundOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.backgroundOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.backgroundOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.backgroundColor.isSet()) {\n this.selectItem(this.settingsManager.backgroundColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background opacity.\n *\n * @category Components\n */\nexport class BackgroundOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsbackgroundopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n this.addItem('0', i18n.getLocalizer('percent', { value: 0 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.backgroundOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.backgroundOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.backgroundColor.clear();\n } else if (!this.settingsManager.backgroundColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.backgroundColor.value = 'black';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.backgroundOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.backgroundOpacity.isSet()) {\n this.selectItem(this.settingsManager.backgroundOpacity.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different character edge.\n *\n * @category Components\n */\nexport class CharacterEdgeSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingscharacteredgeselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('raised', i18n.getLocalizer('settings.subtitles.characterEdge.raised'));\n this.addItem('depressed', i18n.getLocalizer('settings.subtitles.characterEdge.depressed'));\n this.addItem('uniform', i18n.getLocalizer('settings.subtitles.characterEdge.uniform'));\n this.addItem('dropshadowed', i18n.getLocalizer('settings.subtitles.characterEdge.dropshadowed'));\n\n this.settingsManager.characterEdge.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('characteredge-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.characterEdge.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.characterEdge.isSet()) {\n this.selectItem(this.settingsManager.characterEdge.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.fontColor.isSet() && this.settingsManager.fontOpacity.isSet()) {\n this.toggleOverlayClass(\n 'fontcolor-' + this.settingsManager.fontColor.value + this.settingsManager.fontOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontColor.value = key;\n });\n\n this.settingsManager.fontColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.fontColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.fontOpacity.clear();\n } else if (!this.settingsManager.fontOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.fontOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.fontOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.fontColor.isSet()) {\n this.selectItem(this.settingsManager.fontColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font family.\n *\n * @category Components\n */\nexport class FontFamilySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontfamilyselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('monospacedserif', i18n.getLocalizer('settings.subtitles.font.family.monospacedserif'));\n this.addItem('proportionalserif', i18n.getLocalizer('settings.subtitles.font.family.proportionalserif'));\n this.addItem('monospacedsansserif', i18n.getLocalizer('settings.subtitles.font.family.monospacedsansserif'));\n this.addItem('proportionalsansserif', i18n.getLocalizer('settings.subtitles.font.family.proportionalsansserif'));\n this.addItem('casual', i18n.getLocalizer('settings.subtitles.font.family.casual'));\n this.addItem('cursive', i18n.getLocalizer('settings.subtitles.font.family.cursive'));\n this.addItem('smallcapital', i18n.getLocalizer('settings.subtitles.font.family.smallcapital'));\n\n this.settingsManager.fontFamily.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('fontfamily-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontFamily.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.fontFamily.isSet()) {\n this.selectItem(this.settingsManager.fontFamily.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.fontOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.fontColor.clear();\n } else if (!this.settingsManager.fontColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.fontColor.value = 'white';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.fontOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.fontOpacity.isSet()) {\n this.selectItem(this.settingsManager.fontOpacity.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different font colors.\n *\n * @category Components\n */\nexport class FontSizeSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingsfontsizeselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('150', i18n.getLocalizer('percent', { value: 150 }));\n this.addItem('200', i18n.getLocalizer('percent', { value: 200 }));\n this.addItem('300', i18n.getLocalizer('percent', { value: 300 }));\n this.addItem('400', i18n.getLocalizer('percent', { value: 400 }));\n\n this.settingsManager.fontSize.onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n this.toggleOverlayClass('fontsize-' + property.value);\n } else {\n this.toggleOverlayClass(null);\n }\n\n // Select the item in case the property was set from outside\n this.selectItem(property.value);\n });\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.fontSize.value = key;\n });\n\n // Load initial value\n if (this.settingsManager.fontSize.isSet()) {\n this.selectItem(this.settingsManager.fontSize.value);\n }\n }\n}\n","import {SubtitleOverlay} from '../subtitleoverlay';\nimport {ListSelectorConfig} from '../listselector';\nimport {SelectBox} from '../selectbox';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../../uimanager';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingSelectBoxConfig extends ListSelectorConfig {\n overlay: SubtitleOverlay;\n}\n\n/**\n * Base class for all subtitles settings select box\n *\n * @category Components\n **/\nexport class SubtitleSettingSelectBox extends SelectBox {\n\n protected settingsManager?: SubtitleSettingsManager;\n protected overlay: SubtitleOverlay;\n private currentCssClass: string;\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.overlay = config.overlay;\n }\n\n /**\n * Removes a previously set class and adds the passed in class.\n * @param cssClass The new class to replace the previous class with or null to just remove the previous class\n */\n protected toggleOverlayClass(cssClass: string): void {\n // Remove previous class if existing\n if (this.currentCssClass) {\n this.overlay.getDomElement().removeClass(this.currentCssClass);\n this.currentCssClass = null;\n }\n\n // Add new class if specified. If the new class is null, we don't add anything.\n if (cssClass) {\n this.currentCssClass = this.prefixCss(cssClass);\n this.overlay.getDomElement().addClass(this.currentCssClass);\n }\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n this.settingsManager = uimanager.getSubtitleSettingsManager();\n }\n}\n","import {LabelConfig} from '../label';\nimport {Container, ContainerConfig} from '../container';\nimport {DOM} from '../../dom';\nimport {SettingsPanelPageOpenButton} from '../settingspanelpageopenbutton';\nimport { LocalizableText, i18n } from '../../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingsLabelConfig extends LabelConfig {\n opener: SettingsPanelPageOpenButton;\n}\n\n/**\n * @category Components\n */\nexport class SubtitleSettingsLabel extends Container<ContainerConfig> {\n\n private opener: SettingsPanelPageOpenButton;\n\n private text: LocalizableText;\n\n private for: string;\n\n constructor(config: SubtitleSettingsLabelConfig) {\n super(config);\n\n this.opener = config.opener;\n this.text = config.text;\n this.for = config.for;\n\n this.config = this.mergeConfig(<ContainerConfig>config, {\n cssClass: 'ui-label',\n components: [\n this.opener,\n ],\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n let labelElement = new DOM('label', {\n 'id': this.config.id,\n 'class': this.getCssClasses(),\n 'for': this.for,\n }, this).append(\n new DOM('span', {}).html(i18n.performLocalization(this.text)),\n this.opener.getDomElement(),\n );\n\n return labelElement;\n }\n}\n","import { StorageUtils } from '../../storageutils';\nimport { Component, ComponentConfig } from '../component';\nimport { EventDispatcher, Event } from '../../eventdispatcher';\n\ninterface SubtitleSettings {\n fontColor?: string;\n fontOpacity?: string;\n fontFamily?: string;\n fontSize?: string;\n characterEdge?: string;\n backgroundColor?: string;\n backgroundOpacity?: string;\n windowColor?: string;\n windowOpacity?: string;\n}\n\ninterface Properties {\n [name: string]: SubtitleSettingsProperty<string>;\n}\n\n/**\n * @category Utils\n */\nexport class SubtitleSettingsManager {\n private userSettings: SubtitleSettings;\n private localStorageKey: string;\n\n private _properties: Properties = {\n fontColor: new SubtitleSettingsProperty<string>(this),\n fontOpacity: new SubtitleSettingsProperty<string>(this),\n fontFamily: new SubtitleSettingsProperty<string>(this),\n fontSize: new SubtitleSettingsProperty<string>(this),\n characterEdge: new SubtitleSettingsProperty<string>(this),\n backgroundColor: new SubtitleSettingsProperty<string>(this),\n backgroundOpacity: new SubtitleSettingsProperty<string>(this),\n windowColor: new SubtitleSettingsProperty<string>(this),\n windowOpacity: new SubtitleSettingsProperty<string>(this),\n };\n\n constructor() {\n this.userSettings = {};\n this.localStorageKey =\n DummyComponent.instance().prefixCss('subtitlesettings');\n }\n\n public reset(): void {\n for (let propertyName in this._properties) {\n this._properties[propertyName].clear();\n }\n }\n\n public get fontColor(): SubtitleSettingsProperty<string> {\n return this._properties.fontColor;\n }\n\n public get fontOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.fontOpacity;\n }\n\n public get fontFamily(): SubtitleSettingsProperty<string> {\n return this._properties.fontFamily;\n }\n\n public get fontSize(): SubtitleSettingsProperty<string> {\n return this._properties.fontSize;\n }\n\n public get characterEdge(): SubtitleSettingsProperty<string> {\n return this._properties.characterEdge;\n }\n\n public get backgroundColor(): SubtitleSettingsProperty<string> {\n return this._properties.backgroundColor;\n }\n\n public get backgroundOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.backgroundOpacity;\n }\n\n public get windowColor(): SubtitleSettingsProperty<string> {\n return this._properties.windowColor;\n }\n\n public get windowOpacity(): SubtitleSettingsProperty<string> {\n return this._properties.windowOpacity;\n }\n\n public initialize() {\n for (let propertyName in this._properties) {\n this._properties[propertyName].onChanged.subscribe((sender, property) => {\n if (property.isSet()) {\n (<any>this.userSettings)[propertyName] = property.value;\n } else {\n // Delete the property from the settings object if unset to avoid serialization of null values\n delete (<any>this.userSettings)[propertyName];\n }\n\n // Save the settings object when a property has changed\n this.save();\n });\n }\n\n this.load();\n }\n\n /**\n * Saves the settings to local storage.\n */\n public save(): void {\n StorageUtils.setObject(this.localStorageKey, this.userSettings);\n }\n\n /**\n * Loads the settings from local storage\n */\n public load(): void {\n this.userSettings =\n StorageUtils.getObject<SubtitleSettings>(this.localStorageKey) || {};\n\n // Apply the loaded settings\n for (let property in this.userSettings) {\n this._properties[property].value = (<any>this.userSettings)[property];\n }\n }\n}\n\n/**\n * A dummy component whose sole purpose is to expose the {@link #prefixCss} method to the\n * {@link SubtitleSettingsManager}.\n */\nclass DummyComponent extends Component<ComponentConfig> {\n private static _instance: DummyComponent;\n\n public static instance(): DummyComponent {\n if (!DummyComponent._instance) {\n DummyComponent._instance = new DummyComponent();\n }\n\n return DummyComponent._instance;\n }\n\n public prefixCss(cssClassOrId: string): string {\n return super.prefixCss(cssClassOrId);\n }\n}\n\nexport class SubtitleSettingsProperty<T> {\n private _manager: SubtitleSettingsManager;\n private _onChanged: EventDispatcher<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n >;\n private _value: T;\n\n constructor(manager: SubtitleSettingsManager) {\n this._manager = manager;\n this._onChanged = new EventDispatcher<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n >();\n }\n\n public isSet(): boolean {\n return this._value != null;\n }\n\n public clear(): void {\n this._value = null;\n this.onChangedEvent(null);\n }\n\n public get value(): T {\n return this._value;\n }\n\n public set value(value: T) {\n if (typeof value === 'string' && value === 'null') {\n value = null;\n }\n\n this._value = value;\n this.onChangedEvent(value);\n }\n\n protected onChangedEvent(value: T) {\n this._onChanged.dispatch(this._manager, this);\n }\n\n public get onChanged(): Event<\n SubtitleSettingsManager,\n SubtitleSettingsProperty<T>\n > {\n return this._onChanged.getEvent();\n }\n}\n","import {SettingsPanelPage} from '../settingspanelpage';\nimport {SettingsPanel} from '../settingspanel';\nimport {SubtitleOverlay} from '../subtitleoverlay';\nimport {ContainerConfig} from '../container';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport {Component, ComponentConfig} from '../component';\nimport {FontSizeSelectBox} from './fontsizeselectbox';\nimport {FontFamilySelectBox} from './fontfamilyselectbox';\nimport {FontColorSelectBox} from './fontcolorselectbox';\nimport {FontOpacitySelectBox} from './fontopacityselectbox';\nimport {CharacterEdgeSelectBox} from './characteredgeselectbox';\nimport {BackgroundColorSelectBox} from './backgroundcolorselectbox';\nimport {BackgroundOpacitySelectBox} from './backgroundopacityselectbox';\nimport {WindowColorSelectBox} from './windowcolorselectbox';\nimport {WindowOpacitySelectBox} from './windowopacityselectbox';\nimport {SubtitleSettingsResetButton} from './subtitlesettingsresetbutton';\nimport {UIInstanceManager} from '../../uimanager';\nimport {SettingsPanelPageBackButton} from '../settingspanelpagebackbutton';\nimport {SettingsPanelItem} from '../settingspanelitem';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * @category Configs\n */\nexport interface SubtitleSettingsPanelPageConfig extends ContainerConfig {\n settingsPanel: SettingsPanel;\n overlay: SubtitleOverlay;\n}\n\n/**\n * @category Components\n */\nexport class SubtitleSettingsPanelPage extends SettingsPanelPage {\n\n private readonly overlay: SubtitleOverlay;\n private readonly settingsPanel: SettingsPanel;\n\n constructor(config: SubtitleSettingsPanelPageConfig) {\n super(config);\n\n this.overlay = config.overlay;\n this.settingsPanel = config.settingsPanel;\n\n\n this.config = this.mergeConfig(config, {\n components: <Component<ComponentConfig>[]>[\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.size'), new FontSizeSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.family'), new FontFamilySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.color'), new FontColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.font.opacity'), new FontOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.characterEdge'), new CharacterEdgeSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.background.color'), new BackgroundColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.background.opacity'), new BackgroundOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.window.color'), new WindowColorSelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(i18n.getLocalizer('settings.subtitles.window.opacity'), new WindowOpacitySelectBox({\n overlay: this.overlay,\n })),\n new SettingsPanelItem(new SettingsPanelPageBackButton({\n container: this.settingsPanel,\n text: i18n.getLocalizer('back'),\n }), new SubtitleSettingsResetButton({}), {\n role: 'menubar',\n }),\n ],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.onActive.subscribe(() => {\n this.overlay.enablePreviewSubtitleLabel();\n });\n\n this.onInactive.subscribe(() => {\n this.overlay.removePreviewSubtitleLabel();\n });\n }\n}","import {UIInstanceManager} from '../../uimanager';\nimport {SubtitleSettingsManager} from './subtitlesettingsmanager';\nimport {Button, ButtonConfig} from '../button';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A button that resets all subtitle settings to their defaults.\n *\n * @category Buttons\n */\nexport class SubtitleSettingsResetButton extends Button<ButtonConfig> {\n\n private settingsManager: SubtitleSettingsManager;\n\n constructor(config: ButtonConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-subtitlesettingsresetbutton',\n text: i18n.getLocalizer('reset'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n this.settingsManager = uimanager.getSubtitleSettingsManager();\n\n this.onClick.subscribe(() => {\n this.settingsManager.reset();\n });\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background colors.\n *\n * @category Components\n */\nexport class WindowColorSelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingswindowcolorselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('white', i18n.getLocalizer('colors.white'));\n this.addItem('black', i18n.getLocalizer('colors.black'));\n this.addItem('red', i18n.getLocalizer('colors.red'));\n this.addItem('green', i18n.getLocalizer('colors.green'));\n this.addItem('blue', i18n.getLocalizer('colors.blue'));\n this.addItem('cyan', i18n.getLocalizer('colors.cyan'));\n this.addItem('yellow', i18n.getLocalizer('colors.yellow'));\n this.addItem('magenta', i18n.getLocalizer('colors.magenta'));\n\n\n\n let setColorAndOpacity = () => {\n if (this.settingsManager.windowColor.isSet() && this.settingsManager.windowOpacity.isSet()) {\n this.toggleOverlayClass(\n 'windowcolor-' + this.settingsManager.windowColor.value + this.settingsManager.windowOpacity.value);\n } else {\n this.toggleOverlayClass(null);\n }\n };\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.windowColor.value = key;\n });\n\n this.settingsManager.windowColor.onChanged.subscribe((sender, property) => {\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.windowColor.isSet()) {\n // ... clear the opacity when the color is not set\n this.settingsManager.windowOpacity.clear();\n } else if (!this.settingsManager.windowOpacity.isSet()) {\n // ... set an opacity when the color is set\n this.settingsManager.windowOpacity.value = '100';\n }\n this.selectItem(property.value);\n setColorAndOpacity();\n });\n\n this.settingsManager.windowOpacity.onChanged.subscribe(() => {\n setColorAndOpacity();\n });\n\n // Load initial value\n if (this.settingsManager.windowColor.isSet()) {\n this.selectItem(this.settingsManager.windowColor.value);\n }\n }\n}\n","import { SubtitleSettingSelectBox, SubtitleSettingSelectBoxConfig } from './subtitlesettingselectbox';\nimport {UIInstanceManager} from '../../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../../localization/i18n';\n\n/**\n * A select box providing a selection of different background opacity.\n *\n * @category Components\n */\nexport class WindowOpacitySelectBox extends SubtitleSettingSelectBox {\n\n constructor(config: SubtitleSettingSelectBoxConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-subtitlesettingswindowopacityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n this.addItem(null, i18n.getLocalizer('default'));\n this.addItem('100', i18n.getLocalizer('percent', { value: 100 }));\n this.addItem('75', i18n.getLocalizer('percent', { value: 75 }));\n this.addItem('50', i18n.getLocalizer('percent', { value: 50 }));\n this.addItem('25', i18n.getLocalizer('percent', { value: 25 }));\n this.addItem('0', i18n.getLocalizer('percent', { value: 0 }));\n\n this.onItemSelected.subscribe((sender, key: string) => {\n this.settingsManager.windowOpacity.value = key;\n\n // Color and opacity go together, so we need to...\n if (!this.settingsManager.windowOpacity.isSet()) {\n // ... clear the color when the opacity is not set\n this.settingsManager.windowColor.clear();\n } else if (!this.settingsManager.windowColor.isSet()) {\n // ... set a color when the opacity is set\n this.settingsManager.windowColor.value = 'black';\n }\n });\n\n // Update selected item when value is set from somewhere else\n this.settingsManager.windowOpacity.onChanged.subscribe((sender, property) => {\n this.selectItem(property.value);\n });\n\n // Load initial value\n if (this.settingsManager.windowOpacity.isSet()) {\n this.selectItem(this.settingsManager.windowOpacity.value);\n }\n }\n}\n","import { PlayerAPI } from 'bitmovin-player';\nimport { UIInstanceManager } from '../uimanager';\nimport { DOM } from '../dom';\nimport { ComponentConfig } from './component';\nimport { TimelineMarker } from '../uiconfig';\nimport { SeekBarMarker } from './seekbar';\nimport { PlayerUtils } from '../playerutils';\nimport { Timeout } from '../timeout';\n\n/**\n * @category Configs\n */\nexport interface MarkersConfig extends ComponentConfig {\n /**\n * Used for seekBar marker snapping range percentage\n */\n snappingRange?: number;\n}\n\nexport class TimelineMarkersHandler {\n private markersContainer: DOM;\n private timelineMarkers: SeekBarMarker[];\n private player: PlayerAPI;\n private uimanager: UIInstanceManager;\n private pausedTimeshiftUpdater: Timeout;\n private getSeekBarWidth: () => number;\n protected config: MarkersConfig;\n\n constructor(config: MarkersConfig, getSeekBarWidth: () => number, markersContainer: DOM) {\n this.config = config;\n this.getSeekBarWidth = getSeekBarWidth;\n this.markersContainer = markersContainer;\n this.timelineMarkers = [];\n }\n\n public initialize(player: PlayerAPI, uimanager: UIInstanceManager) {\n this.player = player;\n this.uimanager = uimanager;\n this.configureMarkers();\n }\n\n private configureMarkers(): void {\n // Remove markers when unloaded\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, () => this.clearMarkers());\n this.player.on(this.player.exports.PlayerEvent.AdBreakStarted, () => this.clearMarkers());\n this.player.on(this.player.exports.PlayerEvent.AdBreakFinished, () => this.updateMarkers());\n // Update markers when the size of the seekbar changes\n this.player.on(this.player.exports.PlayerEvent.PlayerResized, () => this.updateMarkersDOM());\n\n this.player.on(this.player.exports.PlayerEvent.SourceLoaded, () => {\n if (this.player.isLive()) {\n // Update marker position as timeshift range changes\n this.player.on(this.player.exports.PlayerEvent.TimeChanged, () => this.updateMarkers());\n // Update marker postion when paused as timeshift range changes\n this.configureLivePausedTimeshiftUpdater(() => this.updateMarkers());\n }\n });\n this.uimanager.getConfig().events.onUpdated.subscribe(() => this.updateMarkers());\n this.uimanager.onRelease.subscribe(() => this.uimanager.getConfig().events.onUpdated.unsubscribe(() => this.updateMarkers()));\n\n // Init markers at startup\n this.updateMarkers();\n }\n\n public getMarkerAtPosition(percentage: number): SeekBarMarker | null {\n const snappingRange = this.config.snappingRange;\n\n const matchingMarker = this.timelineMarkers.find(marker => {\n const hasDuration = marker.duration > 0;\n // Handle interval markers\n const intervalMarkerMatch =\n hasDuration &&\n percentage >= marker.position - snappingRange &&\n percentage <= marker.position + marker.duration + snappingRange;\n\n // Handle position markers\n const positionMarkerMatch =\n percentage >= marker.position - snappingRange &&\n percentage <= marker.position + snappingRange;\n\n return intervalMarkerMatch || positionMarkerMatch;\n });\n\n return matchingMarker || null;\n }\n\n private clearMarkers(): void {\n this.timelineMarkers = [];\n this.markersContainer.empty();\n }\n\n private removeMarkerFromConfig(marker: TimelineMarker): void {\n this.uimanager.getConfig().metadata.markers = this.uimanager.getConfig().metadata.markers.filter(_marker => marker !== _marker);\n }\n\n private filterRemovedMarkers(): void {\n this.timelineMarkers = this.timelineMarkers.filter(seekbarMarker => {\n const matchingMarker = this.uimanager.getConfig().metadata.markers.find(_marker => seekbarMarker.marker === _marker);\n if (!matchingMarker) {\n this.removeMarkerFromDOM(seekbarMarker);\n }\n return matchingMarker;\n });\n }\n\n private removeMarkerFromDOM(marker: SeekBarMarker): void {\n if (marker.element) {\n marker.element.remove();\n }\n }\n\n private updateMarkers(): void {\n if (!shouldProcessMarkers(this.player, this.uimanager)) {\n this.clearMarkers();\n return;\n }\n\n this.filterRemovedMarkers();\n\n this.uimanager.getConfig().metadata.markers.forEach(marker => {\n const { markerPosition, markerDuration } = getMarkerPositions(this.player, marker);\n\n if (shouldRemoveMarker(markerPosition, markerDuration)) {\n this.removeMarkerFromConfig(marker);\n } else if (markerPosition <= 100) {\n const matchingMarker = this.timelineMarkers.find(seekbarMarker => seekbarMarker.marker === marker);\n\n if (matchingMarker) {\n matchingMarker.position = markerPosition;\n matchingMarker.duration = markerDuration;\n\n this.updateMarkerDOM(matchingMarker);\n } else {\n const newMarker: SeekBarMarker = { marker, position: markerPosition, duration: markerDuration };\n this.timelineMarkers.push(newMarker);\n\n this.createMarkerDOM(newMarker);\n }\n }\n });\n }\n\n private getMarkerCssProperties(marker: SeekBarMarker): { [propertyName: string]: string } {\n const seekBarWidthPx = this.getSeekBarWidth();\n\n const positionInPx = (seekBarWidthPx / 100) * (marker.position < 0 ? 0 : marker.position);\n const cssProperties: { [propertyName: string]: string } = {\n 'transform': `translateX(${positionInPx}px)`,\n };\n\n if (marker.duration > 0) {\n const markerWidthPx = Math.round(seekBarWidthPx / 100 * marker.duration);\n cssProperties['width'] = `${markerWidthPx}px`;\n }\n\n return cssProperties;\n }\n\n private updateMarkerDOM(marker: SeekBarMarker): void {\n marker.element.css(this.getMarkerCssProperties(marker));\n }\n\n private createMarkerDOM(marker: SeekBarMarker): void {\n const markerClasses = ['seekbar-marker'].concat(marker.marker.cssClasses || [])\n .map(cssClass => this.prefixCss(cssClass));\n\n const markerElement = new DOM('div', {\n 'class': markerClasses.join(' '),\n 'data-marker-time': String(marker.marker.time),\n 'data-marker-title': String(marker.marker.title),\n }).css(this.getMarkerCssProperties(marker));\n\n if (marker.marker.imageUrl) {\n const removeImage = () => {\n imageElement.remove();\n };\n\n const imageElement = new DOM('img', {\n 'class': this.prefixCss('seekbar-marker-image'),\n 'src': marker.marker.imageUrl,\n }).on('error', removeImage);\n\n markerElement.append(imageElement);\n }\n\n marker.element = markerElement;\n this.markersContainer.append(markerElement);\n }\n\n private updateMarkersDOM(): void {\n this.timelineMarkers.forEach(marker => {\n if (marker.element) {\n this.updateMarkerDOM(marker);\n } else {\n this.createMarkerDOM(marker);\n }\n });\n }\n\n private configureLivePausedTimeshiftUpdater(\n handler: () => void,\n ): void {\n // Regularly update the marker position while the timeout is active\n this.pausedTimeshiftUpdater = new Timeout(1000, handler, true);\n\n this.player.on(this.player.exports.PlayerEvent.Paused, () => {\n if (this.player.isLive() && this.player.getMaxTimeShift() < 0) {\n this.pausedTimeshiftUpdater.start();\n }\n });\n\n // Stop updater when playback continues (no matter if the updater was started before)\n this.player.on(this.player.exports.PlayerEvent.Play, () => this.pausedTimeshiftUpdater.clear());\n this.player.on(this.player.exports.PlayerEvent.Destroy, () => this.pausedTimeshiftUpdater.clear());\n }\n\n protected prefixCss(cssClassOrId: string): string {\n return this.config.cssPrefix + '-' + cssClassOrId;\n }\n}\n\nfunction getMarkerPositions(player: PlayerAPI, marker: TimelineMarker) {\n const duration = getDuration(player);\n\n const markerPosition = 100 / duration * getMarkerTime(marker, player, duration); // convert absolute time to percentage\n let markerDuration = 100 / duration * marker.duration;\n\n if (markerPosition < 0 && !isNaN(markerDuration)) {\n // Shrink marker duration for on live streams as they reach end\n markerDuration = markerDuration + markerPosition;\n }\n\n if (100 - markerPosition < markerDuration) {\n // Shrink marker if it overflows timeline\n markerDuration = 100 - markerPosition;\n }\n\n return { markerDuration, markerPosition };\n}\n\nfunction getMarkerTime(marker: TimelineMarker, player: PlayerAPI, duration: number): number {\n if (!player.isLive()) {\n return marker.time;\n }\n\n return duration - (PlayerUtils.getSeekableRangeRespectingLive(player).end - marker.time);\n}\n\nfunction getDuration(player: PlayerAPI): number {\n if (!player.isLive()) {\n return player.getDuration();\n }\n const { start, end } = PlayerUtils.getSeekableRangeRespectingLive(player);\n\n return end - start;\n}\n\nfunction shouldRemoveMarker(markerPosition: number, markerDuration: number): boolean {\n return (markerDuration < 0 || isNaN(markerDuration)) && markerPosition < 0;\n}\n\nfunction shouldProcessMarkers(player: PlayerAPI, uimanager: UIInstanceManager): boolean {\n // Don't generate timeline markers if we don't yet have a duration\n // The duration check is for buggy platforms where the duration is not available instantly (Chrome on Android 4.3)\n const validToProcess = player.getDuration() !== Infinity || player.isLive();\n const hasMarkers = uimanager.getConfig().metadata.markers.length > 0;\n\n return validToProcess && hasMarkers;\n}\n","import {Container, ContainerConfig} from './container';\nimport {UIInstanceManager} from '../uimanager';\nimport {MetadataLabel, MetadataLabelContent} from './metadatalabel';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for a {@link TitleBar}.\n *\n * @category Configs\n */\nexport interface TitleBarConfig extends ContainerConfig {\n /**\n * Specifies if the title bar should stay hidden when no metadata label contains any text. Does not make a lot\n * of sense if the title bar contains other components than just MetadataLabels (like in the default configuration).\n * Default: false\n */\n keepHiddenWithoutMetadata?: boolean;\n}\n\n/**\n * Displays a title bar containing a label with the title of the video.\n *\n * @category Components\n */\nexport class TitleBar extends Container<TitleBarConfig> {\n\n constructor(config: TitleBarConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-titlebar',\n hidden: true,\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n new MetadataLabel({ content: MetadataLabelContent.Description }),\n ],\n keepHiddenWithoutMetadata: false,\n }, <TitleBarConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let config = this.getConfig();\n let shouldBeShown = !this.isHidden();\n let hasMetadataText = true; // Flag to track if any metadata label contains text\n\n let checkMetadataTextAndUpdateVisibility = () => {\n hasMetadataText = false;\n\n // Iterate through metadata labels and check if at least one of them contains text\n for (let component of this.getComponents()) {\n if (component instanceof MetadataLabel) {\n if (!component.isEmpty()) {\n hasMetadataText = true;\n break;\n }\n }\n }\n\n if (this.isShown()) {\n // Hide a visible titlebar if it does not contain any text and the hidden flag is set\n if (config.keepHiddenWithoutMetadata && !hasMetadataText) {\n this.hide();\n }\n } else if (shouldBeShown) {\n // Show a hidden titlebar if it should actually be shown\n this.show();\n }\n };\n\n // Listen to text change events to update the hasMetadataText flag when the metadata dynamically changes\n for (let component of this.getComponents()) {\n if (component instanceof MetadataLabel) {\n component.onTextChanged.subscribe(checkMetadataTextAndUpdateVisibility);\n }\n }\n\n uimanager.onControlsShow.subscribe(() => {\n shouldBeShown = true;\n if (!(config.keepHiddenWithoutMetadata && !hasMetadataText)) {\n this.show();\n }\n });\n uimanager.onControlsHide.subscribe(() => {\n shouldBeShown = false;\n this.hide();\n });\n\n // init\n checkMetadataTextAndUpdateVisibility();\n }\n}","import {Button, ButtonConfig} from './button';\nimport {NoArgs, EventDispatcher, Event} from '../eventdispatcher';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { LocalizableText } from '../localization/i18n';\n\n/**\n * Configuration interface for a toggle button component.\n *\n * @category Configs\n */\nexport interface ToggleButtonConfig extends ButtonConfig {\n /**\n * The CSS class that marks the on-state of the button.\n */\n onClass?: string;\n /**\n * The CSS class that marks the off-state of the button.\n */\n offClass?: string;\n /**\n * WCAG20 standard for defining info about the component (usually the name)\n *\n * It is recommended to use `onAriaLabel` and `offAriaLabel` for toggle buttons\n * as the component can then update them as the button is used.\n *\n * If both `ariaLabel` and `onAriaLabel` are set, `onAriaLabel` is used.\n */\n ariaLabel?: LocalizableText;\n /**\n * The aria label that marks the on-state of the button.\n */\n onAriaLabel?: LocalizableText;\n /**\n * The aria label that marks the off-state of the button.\n */\n offAriaLabel?: LocalizableText;\n /**\n * The text as string or as localize callback on the button.\n */\n text?: LocalizableText;\n}\n\n/**\n * A button that can be toggled between 'on' and 'off' states.\n *\n * @category Components\n */\nexport class ToggleButton<Config extends ToggleButtonConfig> extends Button<Config> {\n\n private onState: boolean;\n\n private toggleButtonEvents = {\n onToggle: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n onToggleOn: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n onToggleOff: new EventDispatcher<ToggleButton<Config>, NoArgs>(),\n };\n\n constructor(config: Config) {\n super(config);\n\n const defaultConfig: ToggleButtonConfig = {\n cssClass: 'ui-togglebutton',\n onClass: 'on',\n offClass: 'off',\n };\n\n if (config.onAriaLabel) {\n config.ariaLabel = config.onAriaLabel;\n }\n\n this.config = this.mergeConfig(config, defaultConfig as Config, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n const config = this.getConfig();\n this.getDomElement().addClass(this.prefixCss(config.offClass));\n }\n\n /**\n * Toggles the button to the 'on' state.\n */\n on() {\n if (this.isOff()) {\n const config = this.getConfig();\n\n this.onState = true;\n this.getDomElement().removeClass(this.prefixCss(config.offClass));\n this.getDomElement().addClass(this.prefixCss(config.onClass));\n\n this.onToggleEvent();\n this.onToggleOnEvent();\n\n this.setAriaAttr('pressed', 'true');\n\n if (this.config.onAriaLabel) {\n this.setAriaLabel(this.config.onAriaLabel);\n }\n }\n }\n\n /**\n * Toggles the button to the 'off' state.\n */\n off() {\n if (this.isOn()) {\n const config = this.getConfig();\n\n this.onState = false;\n this.getDomElement().removeClass(this.prefixCss(config.onClass));\n this.getDomElement().addClass(this.prefixCss(config.offClass));\n\n this.onToggleEvent();\n this.onToggleOffEvent();\n\n this.setAriaAttr('pressed', 'false');\n\n if (this.config.offAriaLabel) {\n this.setAriaLabel(this.config.offAriaLabel);\n }\n }\n }\n\n /**\n * Toggle the button 'on' if it is 'off', or 'off' if it is 'on'.\n */\n toggle() {\n if (this.isOn()) {\n this.off();\n } else {\n this.on();\n }\n }\n\n /**\n * Checks if the toggle button is in the 'on' state.\n * @returns {boolean} true if button is 'on', false if 'off'\n */\n isOn(): boolean {\n return this.onState;\n }\n\n /**\n * Checks if the toggle button is in the 'off' state.\n * @returns {boolean} true if button is 'off', false if 'on'\n */\n isOff(): boolean {\n return !this.isOn();\n }\n\n protected onClickEvent() {\n super.onClickEvent();\n\n // Fire the toggle event together with the click event\n // (they are technically the same, only the semantics are different)\n this.onToggleEvent();\n }\n\n protected onToggleEvent() {\n this.toggleButtonEvents.onToggle.dispatch(this);\n }\n\n protected onToggleOnEvent() {\n this.toggleButtonEvents.onToggleOn.dispatch(this);\n }\n\n protected onToggleOffEvent() {\n this.toggleButtonEvents.onToggleOff.dispatch(this);\n }\n\n /**\n * Gets the event that is fired when the button is toggled.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggle(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggle.getEvent();\n }\n\n /**\n * Gets the event that is fired when the button is toggled 'on'.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggleOn(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggleOn.getEvent();\n }\n\n /**\n * Gets the event that is fired when the button is toggled 'off'.\n * @returns {Event<ToggleButton<Config>, NoArgs>}\n */\n get onToggleOff(): Event<ToggleButton<Config>, NoArgs> {\n return this.toggleButtonEvents.onToggleOff.getEvent();\n }\n}","import {Component, ComponentConfig} from './component';\nimport {DOM} from '../dom';\n\n/**\n * Animated analog TV static noise.\n *\n * @category Components\n */\nexport class TvNoiseCanvas extends Component<ComponentConfig> {\n\n private canvas: DOM;\n\n private canvasElement: HTMLCanvasElement;\n private canvasContext: CanvasRenderingContext2D;\n private canvasWidth = 160;\n private canvasHeight = 90;\n private interferenceHeight = 50;\n private lastFrameUpdate: number = 0;\n private frameInterval: number = 60;\n private useAnimationFrame: boolean = !!window.requestAnimationFrame;\n private noiseAnimationWindowPos: number;\n private frameUpdateHandlerId: number;\n\n constructor(config: ComponentConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-tvnoisecanvas',\n }, this.config);\n }\n\n protected toDomElement(): DOM {\n return this.canvas = new DOM('canvas', { 'class': this.getCssClasses() }, this);\n }\n\n start(): void {\n this.canvasElement = <HTMLCanvasElement>this.canvas.get(0);\n this.canvasContext = this.canvasElement.getContext('2d');\n this.noiseAnimationWindowPos = -this.canvasHeight;\n this.lastFrameUpdate = 0;\n\n this.canvasElement.width = this.canvasWidth;\n this.canvasElement.height = this.canvasHeight;\n\n this.renderFrame();\n }\n\n stop(): void {\n if (this.useAnimationFrame) {\n cancelAnimationFrame(this.frameUpdateHandlerId);\n } else {\n clearTimeout(this.frameUpdateHandlerId);\n }\n }\n\n private renderFrame(): void {\n // This code has been copied from the player controls.js and simplified\n\n if (this.lastFrameUpdate + this.frameInterval > new Date().getTime()) {\n // It's too early to render the next frame\n this.scheduleNextRender();\n return;\n }\n\n let currentPixelOffset;\n let canvasWidth = this.canvasWidth;\n let canvasHeight = this.canvasHeight;\n\n // Create texture\n let noiseImage = this.canvasContext.createImageData(canvasWidth, canvasHeight);\n\n // Fill texture with noise\n for (let y = 0; y < canvasHeight; y++) {\n for (let x = 0; x < canvasWidth; x++) {\n currentPixelOffset = (canvasWidth * y * 4) + x * 4;\n noiseImage.data[currentPixelOffset] = Math.random() * 255;\n if (y < this.noiseAnimationWindowPos || y > this.noiseAnimationWindowPos + this.interferenceHeight) {\n noiseImage.data[currentPixelOffset] *= 0.85;\n }\n noiseImage.data[currentPixelOffset + 1] = noiseImage.data[currentPixelOffset];\n noiseImage.data[currentPixelOffset + 2] = noiseImage.data[currentPixelOffset];\n noiseImage.data[currentPixelOffset + 3] = 50;\n }\n }\n\n // Put texture onto canvas\n this.canvasContext.putImageData(noiseImage, 0, 0);\n\n this.lastFrameUpdate = new Date().getTime();\n this.noiseAnimationWindowPos += 7;\n if (this.noiseAnimationWindowPos > canvasHeight) {\n this.noiseAnimationWindowPos = -canvasHeight;\n }\n\n this.scheduleNextRender();\n }\n\n private scheduleNextRender(): void {\n if (this.useAnimationFrame) {\n this.frameUpdateHandlerId = window.requestAnimationFrame(this.renderFrame.bind(this));\n } else {\n this.frameUpdateHandlerId = window.setTimeout(this.renderFrame.bind(this), this.frameInterval);\n }\n }\n}","import { Container, ContainerConfig } from './container';\nimport { UIInstanceManager } from '../uimanager';\nimport { DOM, HTMLElementWithComponent } from '../dom';\nimport { Timeout } from '../timeout';\nimport { PlayerUtils } from '../playerutils';\nimport { CancelEventArgs, Event as UiEvent, EventDispatcher } from '../eventdispatcher';\nimport { PlayerAPI, PlayerResizedEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\nimport { Button, ButtonConfig } from './button';\n\n/**\n * Configuration interface for a {@link UIContainer}.\n *\n * @category Configs\n */\nexport interface UIContainerConfig extends ContainerConfig {\n /**\n * The delay in milliseconds after which the control bar will be hidden when there is no user interaction.\n * Set to -1 for the UI to be always shown.\n * Default: 5 seconds (5000)\n */\n hideDelay?: number;\n /**\n * An array of player states in which the UI will not be hidden, no matter what the {@link hideDelay} is.\n */\n hidePlayerStateExceptions?: PlayerUtils.PlayerState[];\n /**\n * The HTML element on which user interaction events (e.g. mouse and touch events) will be tracked to detect\n * interaction with the UI. These basically trigger showing and hiding of the UI.\n * Default: the UI container itself\n */\n userInteractionEventSource?: HTMLElement;\n\n /**\n * Specify whether the UI should be hidden immediatly if the mouse leaves the userInteractionEventSource.\n * If false or not set it will wait for the hideDelay.\n * Default: false\n */\n hideImmediatelyOnMouseLeave?: boolean;\n}\n\n/**\n * The base container that contains all of the UI. The UIContainer is passed to the {@link UIManager} to build and\n * setup the UI.\n *\n * @category Containers\n */\nexport class UIContainer extends Container<UIContainerConfig> {\n\n private static readonly STATE_PREFIX = 'player-state-';\n\n private static readonly FULLSCREEN = 'fullscreen';\n private static readonly BUFFERING = 'buffering';\n private static readonly REMOTE_CONTROL = 'remote-control';\n private static readonly CONTROLS_SHOWN = 'controls-shown';\n private static readonly CONTROLS_HIDDEN = 'controls-hidden';\n\n private uiHideTimeout: Timeout;\n private playerStateChange: EventDispatcher<UIContainer, PlayerUtils.PlayerState>;\n\n private userInteractionEventSource: DOM;\n private userInteractionEvents: { name: string, handler: EventListenerOrEventListenerObject }[];\n private hidingPrevented: () => boolean;\n\n public hideUi: () => void = () => {};\n public showUi: () => void = () => {};\n\n constructor(config: UIContainerConfig) {\n super(config);\n\n this.config = this.mergeConfig(config, <UIContainerConfig>{\n cssClass: 'ui-uicontainer',\n role: 'region',\n ariaLabel: i18n.getLocalizer('player'),\n hideDelay: 5000,\n hideImmediatelyOnMouseLeave: false,\n }, this.config);\n\n this.playerStateChange = new EventDispatcher<UIContainer, PlayerUtils.PlayerState>();\n this.hidingPrevented = () => false;\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n const config = this.getConfig();\n\n if (config.userInteractionEventSource) {\n this.userInteractionEventSource = new DOM(config.userInteractionEventSource);\n } else {\n this.userInteractionEventSource = this.getDomElement();\n }\n\n super.configure(player, uimanager);\n\n this.configureUIShowHide(player, uimanager);\n this.configurePlayerStates(player, uimanager);\n }\n\n private configureUIShowHide(player: PlayerAPI, uimanager: UIInstanceManager): void {\n let config = this.getConfig();\n\n if (config.hideDelay === -1) {\n uimanager.onConfigured.subscribe(() => uimanager.onControlsShow.dispatch(this));\n return;\n }\n\n let isUiShown = false;\n let isSeeking = false;\n let isFirstTouch = true;\n let playerState: PlayerUtils.PlayerState;\n\n this.hidingPrevented = (): boolean => {\n return config.hidePlayerStateExceptions && config.hidePlayerStateExceptions.indexOf(playerState) > -1;\n };\n\n this.showUi = () => {\n if (!isUiShown) {\n // Let subscribers know that they should reveal themselves\n uimanager.onControlsShow.dispatch(this);\n isUiShown = true;\n }\n // Don't trigger timeout while seeking (it will be triggered once the seek is finished) or casting\n if (!isSeeking && !player.isCasting() && !this.hidingPrevented()) {\n this.uiHideTimeout.start();\n }\n };\n\n this.hideUi = () => {\n // Hide the UI only if it is shown, and if not casting\n if (isUiShown && !player.isCasting()) {\n // Issue a preview event to check if we are good to hide the controls\n let previewHideEventArgs = <CancelEventArgs>{};\n uimanager.onPreviewControlsHide.dispatch(this, previewHideEventArgs);\n\n if (!previewHideEventArgs.cancel) {\n // If the preview wasn't canceled, let subscribers know that they should now hide themselves\n uimanager.onControlsHide.dispatch(this);\n isUiShown = false;\n } else {\n // If the hide preview was canceled, continue to show UI\n this.showUi();\n }\n }\n };\n\n // Timeout to defer UI hiding by the configured delay time\n this.uiHideTimeout = new Timeout(config.hideDelay, this.hideUi);\n\n this.userInteractionEvents = [{\n // On touch displays, the first touch reveals the UI\n name: 'touchend',\n handler: (e) => {\n const shouldPreventDefault = ((e: Event): Boolean => {\n const findButtonComponent = ((element: HTMLElementWithComponent): Button<ButtonConfig> | null => {\n if (\n !element\n || element === this.userInteractionEventSource.get(0)\n || element.component instanceof UIContainer\n ) {\n return null;\n }\n\n if (element.component && element.component instanceof Button) {\n return element.component;\n } else {\n return findButtonComponent(element.parentElement);\n }\n });\n\n const buttonComponent = findButtonComponent(e.target as HTMLElementWithComponent);\n return !(buttonComponent && buttonComponent.getConfig().acceptsTouchWithUiHidden);\n });\n\n if (!isUiShown) {\n // Only if the UI is hidden, we prevent other actions (except for the first touch) and reveal the UI\n // instead. The first touch is not prevented to let other listeners receive the event and trigger an\n // initial action, e.g. the huge playback button can directly start playback instead of requiring a double\n // tap which 1. reveals the UI and 2. starts playback.\n if (isFirstTouch && !player.isPlaying()) {\n isFirstTouch = false;\n } else {\n // On touch input devices, the first touch is expected to display the UI controls and not be propagated to\n // other components.\n // When buttons are always visible this causes UX problems, as the first touch is not recognized.\n // This is the case for the {@link AdSkipButton} and {@link AdClickOverlay}.\n // To prevent UX issues where the buttons need to be touched twice, we do not prevent the first touch event.\n if (shouldPreventDefault(e)) {\n e.preventDefault();\n }\n }\n this.showUi();\n }\n },\n }, {\n // When the mouse enters, we show the UI\n name: 'mouseenter',\n handler: () => {\n this.showUi();\n },\n }, {\n // When the mouse moves within, we show the UI\n name: 'mousemove',\n handler: () => {\n this.showUi();\n },\n }, {\n name: 'focusin',\n handler: () => {\n this.showUi();\n },\n }, {\n name: 'keydown',\n handler: () => {\n this.showUi();\n },\n }, {\n // When the mouse leaves, we can prepare to hide the UI, except a seek is going on\n name: 'mouseleave',\n handler: () => {\n // When a seek is going on, the seek scrub pointer may exit the UI area while still seeking, and we do not\n // hide the UI in such cases\n if (!isSeeking && !this.hidingPrevented()) {\n if (this.config.hideImmediatelyOnMouseLeave) {\n this.hideUi();\n } else {\n this.uiHideTimeout.start();\n }\n }\n },\n }];\n\n this.userInteractionEvents.forEach((event) => this.userInteractionEventSource.on(event.name, event.handler));\n\n uimanager.onSeek.subscribe(() => {\n this.uiHideTimeout.clear(); // Don't hide UI while a seek is in progress\n isSeeking = true;\n });\n uimanager.onSeeked.subscribe(() => {\n isSeeking = false;\n if (!this.hidingPrevented()) {\n this.uiHideTimeout.start(); // Re-enable UI hide timeout after a seek\n }\n });\n uimanager.onComponentViewModeChanged.subscribe((_, { mode }) => this.trackComponentViewMode(mode));\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n this.showUi(); // Show UI when a Cast session has started (UI will then stay permanently on during the session)\n });\n this.playerStateChange.subscribe((_, state) => {\n playerState = state;\n if (this.hidingPrevented()) {\n // Entering a player state that prevents hiding and forces the controls to be shown\n this.uiHideTimeout.clear();\n this.showUi();\n } else {\n // Entering a player state that allows hiding\n this.uiHideTimeout.start();\n }\n });\n }\n\n private configurePlayerStates(player: PlayerAPI, uimanager: UIInstanceManager): void {\n let container = this.getDomElement();\n\n // Convert player states into CSS class names\n let stateClassNames = <any>[];\n for (let state in PlayerUtils.PlayerState) {\n if (isNaN(Number(state))) {\n let enumName = PlayerUtils.PlayerState[<any>PlayerUtils.PlayerState[state]];\n stateClassNames[PlayerUtils.PlayerState[state]] =\n this.prefixCss(UIContainer.STATE_PREFIX + enumName.toLowerCase());\n }\n }\n\n let removeStates = () => {\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Idle]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Prepared]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Playing]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Paused]);\n container.removeClass(stateClassNames[PlayerUtils.PlayerState.Finished]);\n };\n\n const updateState = (state: PlayerUtils.PlayerState) => {\n removeStates();\n container.addClass(stateClassNames[state]);\n this.playerStateChange.dispatch(this, state);\n };\n\n player.on(player.exports.PlayerEvent.SourceLoaded, () => {\n updateState(PlayerUtils.PlayerState.Prepared);\n });\n player.on(player.exports.PlayerEvent.Play, () => {\n updateState(PlayerUtils.PlayerState.Playing);\n });\n player.on(player.exports.PlayerEvent.Playing, () => {\n updateState(PlayerUtils.PlayerState.Playing);\n });\n player.on(player.exports.PlayerEvent.Paused, () => {\n updateState(PlayerUtils.PlayerState.Paused);\n });\n player.on(player.exports.PlayerEvent.PlaybackFinished, () => {\n updateState(PlayerUtils.PlayerState.Finished);\n });\n player.on(player.exports.PlayerEvent.SourceUnloaded, () => {\n updateState(PlayerUtils.PlayerState.Idle);\n });\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n updateState(PlayerUtils.getState(player));\n });\n\n // Fullscreen marker class\n player.on(player.exports.PlayerEvent.ViewModeChanged, () => {\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n container.addClass(this.prefixCss(UIContainer.FULLSCREEN));\n } else {\n container.removeClass(this.prefixCss(UIContainer.FULLSCREEN));\n }\n });\n // Init fullscreen state\n if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {\n container.addClass(this.prefixCss(UIContainer.FULLSCREEN));\n }\n\n // Buffering marker class\n player.on(player.exports.PlayerEvent.StallStarted, () => {\n container.addClass(this.prefixCss(UIContainer.BUFFERING));\n });\n player.on(player.exports.PlayerEvent.StallEnded, () => {\n container.removeClass(this.prefixCss(UIContainer.BUFFERING));\n });\n // Init buffering state\n if (player.isStalled()) {\n container.addClass(this.prefixCss(UIContainer.BUFFERING));\n }\n\n // RemoteControl marker class\n player.on(player.exports.PlayerEvent.CastStarted, () => {\n container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n });\n player.on(player.exports.PlayerEvent.CastStopped, () => {\n container.removeClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n });\n // Init RemoteControl state\n if (player.isCasting()) {\n container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL));\n }\n\n // Controls visibility marker class\n uimanager.onControlsShow.subscribe(() => {\n container.removeClass(this.prefixCss(UIContainer.CONTROLS_HIDDEN));\n container.addClass(this.prefixCss(UIContainer.CONTROLS_SHOWN));\n });\n uimanager.onControlsHide.subscribe(() => {\n container.removeClass(this.prefixCss(UIContainer.CONTROLS_SHOWN));\n container.addClass(this.prefixCss(UIContainer.CONTROLS_HIDDEN));\n });\n\n // Layout size classes\n let updateLayoutSizeClasses = (width: number, height: number) => {\n container.removeClass(this.prefixCss('layout-max-width-400'));\n container.removeClass(this.prefixCss('layout-max-width-600'));\n container.removeClass(this.prefixCss('layout-max-width-800'));\n container.removeClass(this.prefixCss('layout-max-width-1200'));\n\n if (width <= 400) {\n container.addClass(this.prefixCss('layout-max-width-400'));\n } else if (width <= 600) {\n container.addClass(this.prefixCss('layout-max-width-600'));\n } else if (width <= 800) {\n container.addClass(this.prefixCss('layout-max-width-800'));\n } else if (width <= 1200) {\n container.addClass(this.prefixCss('layout-max-width-1200'));\n }\n };\n player.on(player.exports.PlayerEvent.PlayerResized, (e: PlayerResizedEvent) => {\n // Convert strings (with \"px\" suffix) to ints\n let width = Math.round(Number(e.width.substring(0, e.width.length - 2)));\n let height = Math.round(Number(e.height.substring(0, e.height.length - 2)));\n\n updateLayoutSizeClasses(width, height);\n });\n // Init layout state\n updateLayoutSizeClasses(new DOM(player.getContainer()).width(), new DOM(player.getContainer()).height());\n }\n\n release(): void {\n // Explicitly unsubscribe user interaction event handlers because they could be attached to an external element\n // that isn't owned by the UI and therefore not removed on release.\n if (this.userInteractionEvents) {\n this.userInteractionEvents.forEach((event) => this.userInteractionEventSource.off(event.name, event.handler));\n }\n\n super.release();\n\n if (this.uiHideTimeout) {\n this.uiHideTimeout.clear();\n }\n }\n\n onPlayerStateChange(): UiEvent<UIContainer, PlayerUtils.PlayerState> {\n return this.playerStateChange.getEvent();\n }\n\n protected suspendHideTimeout() {\n this.uiHideTimeout.suspend();\n }\n\n protected resumeHideTimeout() {\n this.uiHideTimeout.resume(!this.hidingPrevented());\n }\n\n protected toDomElement(): DOM {\n let container = super.toDomElement();\n\n // Detect flexbox support (not supported in IE9)\n if (document && typeof document.createElement('p').style.flex !== 'undefined') {\n container.addClass(this.prefixCss('flexbox'));\n } else {\n container.addClass(this.prefixCss('no-flexbox'));\n }\n\n return container;\n }\n}\n","import {SelectBox} from './selectbox';\nimport {ListSelectorConfig} from './listselector';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A select box providing a selection between 'auto' and the available video qualities.\n *\n * @category Components\n */\nexport class VideoQualitySelectBox extends SelectBox {\n\n private hasAuto: boolean;\n\n constructor(config: ListSelectorConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClasses: ['ui-videoqualityselectbox'],\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let selectCurrentVideoQuality = () => {\n this.selectItem(player.getVideoQuality().id);\n };\n\n let updateVideoQualities = () => {\n let videoQualities = player.getAvailableVideoQualities();\n\n this.clearItems();\n\n // Progressive streams do not support automatic quality selection\n this.hasAuto = player.getStreamType() !== 'progressive';\n\n if (this.hasAuto) {\n // Add entry for automatic quality switching (default setting)\n this.addItem('auto', i18n.getLocalizer('auto'));\n }\n\n // Add video qualities\n for (let videoQuality of videoQualities) {\n this.addItem(videoQuality.id, videoQuality.label);\n }\n\n // Select initial quality\n selectCurrentVideoQuality();\n };\n\n this.onItemSelected.subscribe((sender: VideoQualitySelectBox, value: string) => {\n player.setVideoQuality(value);\n });\n\n // Update qualities when source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, updateVideoQualities);\n // Update qualities when the period within a source changes\n player.on(player.exports.PlayerEvent.PeriodSwitched, updateVideoQualities);\n // Update quality selection when quality is changed (from outside)\n player.on(player.exports.PlayerEvent.VideoQualityChanged, selectCurrentVideoQuality);\n\n if ((player.exports.PlayerEvent as any).VideoQualityAdded) {\n // Update qualities when their availability changed\n // TODO: remove any cast after next player release\n player.on((player.exports.PlayerEvent as any).VideoQualityAdded, updateVideoQualities);\n player.on((player.exports.PlayerEvent as any).VideoQualityRemoved, updateVideoQualities);\n }\n\n uimanager.getConfig().events.onUpdated.subscribe(updateVideoQualities);\n }\n\n /**\n * Returns true if the select box contains an 'auto' item for automatic quality selection mode.\n * @return {boolean}\n */\n hasAutoItem(): boolean {\n return this.hasAuto;\n }\n}","import {Container, ContainerConfig} from './container';\nimport {VolumeSlider} from './volumeslider';\nimport {VolumeToggleButton} from './volumetogglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport {Timeout} from '../timeout';\nimport { PlayerAPI } from 'bitmovin-player';\n\n/**\n * Configuration interface for a {@link VolumeControlButton}.\n *\n * @category Configs\n */\nexport interface VolumeControlButtonConfig extends ContainerConfig {\n /**\n * The delay after which the volume slider will be hidden when there is no user interaction.\n * Care must be taken that the delay is long enough so users can reach the slider from the toggle button, e.g. by\n * mouse movement. If the delay is too short, the sliders disappears before the mouse pointer has reached it and\n * the user is not able to use it.\n * Default: 500ms\n */\n hideDelay?: number;\n /**\n * Specifies if the volume slider should be vertically or horizontally aligned.\n * Default: true\n */\n vertical?: boolean;\n}\n\n/**\n * A composite volume control that consists of and internally manages a volume control button that can be used\n * for muting, and a (depending on the CSS style, e.g. slide-out) volume control bar.\n *\n * @category Buttons\n */\nexport class VolumeControlButton extends Container<VolumeControlButtonConfig> {\n\n private volumeToggleButton: VolumeToggleButton;\n private volumeSlider: VolumeSlider;\n\n private volumeSliderHideTimeout: Timeout;\n\n constructor(config: VolumeControlButtonConfig = {}) {\n super(config);\n\n this.volumeToggleButton = new VolumeToggleButton();\n this.volumeSlider = new VolumeSlider({\n vertical: config.vertical != null ? config.vertical : true,\n hidden: true,\n });\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-volumecontrolbutton',\n components: [this.volumeToggleButton, this.volumeSlider],\n hideDelay: 500,\n }, <VolumeControlButtonConfig>this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let volumeToggleButton = this.getVolumeToggleButton();\n let volumeSlider = this.getVolumeSlider();\n\n this.volumeSliderHideTimeout = new Timeout(this.getConfig().hideDelay, () => {\n volumeSlider.hide();\n });\n\n /*\n * Volume Slider visibility handling\n *\n * The volume slider shall be visible while the user hovers the mute toggle button, while the user hovers the\n * volume slider, and while the user slides the volume slider. If none of these situations are true, the slider\n * shall disappear.\n */\n let volumeSliderHovered = false;\n volumeToggleButton.getDomElement().on('mouseenter', () => {\n // Show volume slider when mouse enters the button area\n if (volumeSlider.isHidden()) {\n volumeSlider.show();\n }\n // Avoid hiding of the slider when button is hovered\n this.volumeSliderHideTimeout.clear();\n });\n volumeToggleButton.getDomElement().on('mouseleave', () => {\n // Hide slider delayed when button is left\n this.volumeSliderHideTimeout.reset();\n });\n volumeSlider.getDomElement().on('mouseenter', () => {\n // When the slider is entered, cancel the hide timeout activated by leaving the button\n this.volumeSliderHideTimeout.clear();\n volumeSliderHovered = true;\n });\n volumeSlider.getDomElement().on('mouseleave', () => {\n // When mouse leaves the slider, only hide it if there is no slide operation in progress\n if (volumeSlider.isSeeking()) {\n this.volumeSliderHideTimeout.clear();\n } else {\n this.volumeSliderHideTimeout.reset();\n }\n volumeSliderHovered = false;\n });\n volumeSlider.onSeeked.subscribe(() => {\n // When a slide operation is done and the slider not hovered (mouse outside slider), hide slider delayed\n if (!volumeSliderHovered) {\n this.volumeSliderHideTimeout.reset();\n }\n });\n }\n\n release(): void {\n super.release();\n this.volumeSliderHideTimeout.clear();\n }\n\n /**\n * Provides access to the internally managed volume toggle button.\n * @returns {VolumeToggleButton}\n */\n getVolumeToggleButton(): VolumeToggleButton {\n return this.volumeToggleButton;\n }\n\n /**\n * Provides access to the internally managed volume silder.\n * @returns {VolumeSlider}\n */\n getVolumeSlider(): VolumeSlider {\n return this.volumeSlider;\n }\n}","import { SeekBar, SeekBarConfig, SeekPreviewEventArgs } from './seekbar';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { VolumeTransition } from '../volumecontroller';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for the {@link VolumeSlider} component.\n *\n * @category Configs\n */\nexport interface VolumeSliderConfig extends SeekBarConfig {\n /**\n * Specifies if the volume slider should be automatically hidden when volume control is prohibited by the\n * browser or platform. This currently only applies to iOS.\n * Default: true\n */\n hideIfVolumeControlProhibited?: boolean;\n}\n\n/**\n * A simple volume slider component to adjust the player's volume setting.\n *\n * @category Components\n */\nexport class VolumeSlider extends SeekBar {\n private volumeTransition: VolumeTransition;\n\n constructor(config: VolumeSliderConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, <VolumeSliderConfig>{\n cssClass: 'ui-volumeslider',\n hideIfVolumeControlProhibited: true,\n ariaLabel: i18n.getLocalizer('settings.audio.volume'),\n tabIndex: 0,\n }, this.config);\n }\n\n private setVolumeAriaSliderValues(value: number) {\n this.getDomElement().attr('aria-valuenow', Math.ceil(value).toString());\n this.getDomElement().attr('aria-valuetext', `${i18n.performLocalization(i18n.getLocalizer('seekBar.value'))}: ${Math.ceil(value)}`);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager, false);\n\n this.setAriaSliderMinMax('0', '100');\n\n let config = <VolumeSliderConfig>this.getConfig();\n\n const volumeController = uimanager.getConfig().volumeController;\n\n if (config.hideIfVolumeControlProhibited && !this.detectVolumeControlAvailability()) {\n this.hide();\n\n // We can just return from here, because the user will never interact with the control and any configured\n // functionality would only eat resources for no reason.\n return;\n }\n\n volumeController.onChanged.subscribe((_, args) => {\n if (args.muted) {\n this.setVolumeAriaSliderValues(0);\n this.setPlaybackPosition(0);\n } else {\n this.setPlaybackPosition(args.volume);\n this.setVolumeAriaSliderValues(args.volume);\n }\n });\n\n this.onSeek.subscribe(() => {\n this.volumeTransition = volumeController.startTransition();\n });\n\n this.onSeekPreview.subscribeRateLimited(this.updateVolumeWhileScrubbing, 50);\n this.onSeeked.subscribe((sender, percentage) => {\n if (this.volumeTransition) {\n this.volumeTransition.finish(percentage);\n }\n });\n\n // Update the volume slider marker when the player resized, a source is loaded,\n // or the UI is configured. Check the seekbar for a detailed description.\n player.on(player.exports.PlayerEvent.PlayerResized, () => {\n this.refreshPlaybackPosition();\n });\n uimanager.onConfigured.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n uimanager.getConfig().events.onUpdated.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n uimanager.onComponentShow.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n uimanager.onComponentHide.subscribe(() => {\n this.refreshPlaybackPosition();\n });\n\n // Init volume bar\n volumeController.onChangedEvent();\n }\n\n private updateVolumeWhileScrubbing = (sender: VolumeSlider, args: SeekPreviewEventArgs) => {\n if (args.scrubbing && this.volumeTransition) {\n this.volumeTransition.update(args.position);\n }\n };\n\n private detectVolumeControlAvailability(): boolean {\n /*\n * \"On iOS devices, the audio level is always under the user’s physical control. The volume property is not\n * settable in JavaScript. Reading the volume property always returns 1.\"\n * https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html\n */\n // as muted autoplay gets paused as soon as we unmute it, we may not touch the volume of the actual player so we\n // probe a dummy audio element\n const dummyVideoElement = document.createElement('video');\n // try setting the volume to 0.7 and if it's still 1 we are on a volume control restricted device\n dummyVideoElement.volume = 0.7;\n return dummyVideoElement.volume !== 1;\n }\n\n release(): void {\n super.release();\n\n this.onSeekPreview.unsubscribe(this.updateVolumeWhileScrubbing);\n }\n}\n","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport { UIInstanceManager } from '../uimanager';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles audio muting.\n *\n * @category Buttons\n */\nexport class VolumeToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n const defaultConfig: ToggleButtonConfig = {\n cssClass: 'ui-volumetogglebutton',\n text: i18n.getLocalizer('settings.audio.mute'),\n onClass: 'muted',\n offClass: 'unmuted',\n ariaLabel: i18n.getLocalizer('settings.audio.mute'),\n };\n\n this.config = this.mergeConfig(config, defaultConfig, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n const volumeController = uimanager.getConfig().volumeController;\n\n volumeController.onChanged.subscribe((_, args) => {\n if (args.muted) {\n this.on();\n } else {\n this.off();\n }\n\n const volumeLevelTens = Math.ceil(args.volume / 10);\n this.getDomElement().data(this.prefixCss('volume-level-tens'), String(volumeLevelTens));\n });\n\n this.onClick.subscribe(() => {\n volumeController.toggleMuted();\n });\n\n // Startup init\n volumeController.onChangedEvent();\n }\n}","import {ToggleButton, ToggleButtonConfig} from './togglebutton';\nimport {UIInstanceManager} from '../uimanager';\nimport { PlayerAPI, PlayerEventBase, WarningEvent } from 'bitmovin-player';\nimport { i18n } from '../localization/i18n';\n\n/**\n * A button that toggles the video view between normal/mono and VR/stereo.\n *\n * @category Buttons\n */\nexport class VRToggleButton extends ToggleButton<ToggleButtonConfig> {\n\n constructor(config: ToggleButtonConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-vrtogglebutton',\n text: i18n.getLocalizer('vr'),\n }, this.config);\n }\n\n configure(player: PlayerAPI, uimanager: UIInstanceManager): void {\n super.configure(player, uimanager);\n\n let isVRConfigured = () => {\n // VR availability cannot be checked through getVRStatus() because it is asynchronously populated and not\n // available at UI initialization. As an alternative, we check the VR settings in the config.\n // TODO use getVRStatus() through isVRStereoAvailable() once the player has been rewritten and the status is\n // available in Ready\n const source = player.getSource();\n return source && Boolean(source.vr);\n };\n\n let isVRStereoAvailable = () => {\n const source = player.getSource();\n return player.vr && Boolean(source.vr);\n };\n\n let vrStateHandler = (ev: PlayerEventBase) => {\n if (ev.type === player.exports.PlayerEvent.Warning\n && (ev as WarningEvent).code !== player.exports.WarningCode.VR_RENDERING_ERROR) {\n return;\n }\n\n if (isVRConfigured() && isVRStereoAvailable()) {\n this.show(); // show button in case it is hidden\n\n if (player.vr && player.vr.getStereo()) {\n this.on();\n } else {\n this.off();\n }\n } else {\n this.hide(); // hide button if no stereo mode available\n }\n };\n\n let vrButtonVisibilityHandler = () => {\n if (isVRConfigured()) {\n this.show();\n } else {\n this.hide();\n }\n };\n\n player.on(player.exports.PlayerEvent.VRStereoChanged, vrStateHandler);\n player.on(player.exports.PlayerEvent.Warning, vrStateHandler);\n // Hide button when VR source goes away\n player.on(player.exports.PlayerEvent.SourceUnloaded, vrButtonVisibilityHandler);\n uimanager.getConfig().events.onUpdated.subscribe(vrButtonVisibilityHandler);\n\n this.onClick.subscribe(() => {\n if (!isVRStereoAvailable()) {\n if (console) {\n console.log('No VR content');\n }\n } else {\n if (player.vr && player.vr.getStereo()) {\n player.vr.setStereo(false);\n } else {\n player.vr.setStereo(true);\n }\n }\n });\n\n // Set startup visibility\n vrButtonVisibilityHandler();\n }\n}","import {ClickOverlay, ClickOverlayConfig} from './clickoverlay';\nimport { i18n } from '../localization/i18n';\n\n/**\n * Configuration interface for a {@link ClickOverlay}.\n *\n * @category Configs\n */\nexport interface WatermarkConfig extends ClickOverlayConfig {\n // nothing yet\n}\n\n/**\n * A watermark overlay with a clickable logo.\n *\n * @category Components\n */\nexport class Watermark extends ClickOverlay {\n\n constructor(config: WatermarkConfig = {}) {\n super(config);\n\n this.config = this.mergeConfig(config, {\n cssClass: 'ui-watermark',\n url: 'http://bitmovin.com',\n role: 'link',\n text: 'logo',\n ariaLabel: i18n.getLocalizer('watermarkLink'),\n }, <WatermarkConfig>this.config);\n }\n}","import {VRToggleButton} from './components/vrtogglebutton';\nimport {SettingsToggleButton} from './components/settingstogglebutton';\nimport {VolumeSlider} from './components/volumeslider';\nimport {PlaybackTimeLabel, PlaybackTimeLabelMode} from './components/playbacktimelabel';\nimport {AirPlayToggleButton} from './components/airplaytogglebutton';\nimport {ErrorMessageOverlay} from './components/errormessageoverlay';\nimport {ControlBar} from './components/controlbar';\nimport {CastToggleButton} from './components/casttogglebutton';\nimport {FullscreenToggleButton} from './components/fullscreentogglebutton';\nimport {RecommendationOverlay} from './components/recommendationoverlay';\nimport {PlaybackSpeedSelectBox} from './components/playbackspeedselectbox';\nimport {AudioQualitySelectBox} from './components/audioqualityselectbox';\nimport {CastStatusOverlay} from './components/caststatusoverlay';\nimport {UIContainer} from './components/uicontainer';\nimport {Watermark} from './components/watermark';\nimport {SubtitleOverlay} from './components/subtitleoverlay';\nimport {SettingsPanel} from './components/settingspanel';\nimport {SeekBarLabel} from './components/seekbarlabel';\nimport {PlaybackToggleOverlay} from './components/playbacktoggleoverlay';\nimport {PictureInPictureToggleButton} from './components/pictureinpicturetogglebutton';\nimport {Spacer} from './components/spacer';\nimport {Container} from './components/container';\nimport {VolumeToggleButton} from './components/volumetogglebutton';\nimport {PlaybackToggleButton} from './components/playbacktogglebutton';\nimport {SeekBar} from './components/seekbar';\nimport {VideoQualitySelectBox} from './components/videoqualityselectbox';\nimport {UIConditionContext, UIManager} from './uimanager';\nimport {TitleBar} from './components/titlebar';\nimport {BufferingOverlay} from './components/bufferingoverlay';\nimport {SubtitleListBox} from './components/subtitlelistbox';\nimport {AudioTrackListBox} from './components/audiotracklistbox';\nimport {SettingsPanelItem} from './components/settingspanelitem';\nimport {SettingsPanelPage} from './components/settingspanelpage';\nimport { UIFactory } from './uifactory';\nimport { UIConfig } from './uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { QuickSeekButton } from './main';\n\nexport namespace DemoFactory {\n\n export function buildDemoWithSeparateAudioSubtitlesButtons(player: PlayerAPI, config: UIConfig = {}): UIManager {\n // show smallScreen UI only on mobile/handheld devices\n let smallScreenSwitchWidth = 600;\n\n return new UIManager(player, [{\n ui: UIFactory.modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isMobile && context.documentWidth < smallScreenSwitchWidth\n && context.isAd && context.adRequiresUi;\n },\n }, {\n ui: UIFactory.modernAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n }, {\n ui: UIFactory.modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return context.isMobile && context.documentWidth < smallScreenSwitchWidth;\n },\n }, {\n ui: modernUIWithSeparateAudioSubtitlesButtons(),\n }], config);\n }\n\n function modernUIWithSeparateAudioSubtitlesButtons() {\n let subtitleOverlay = new SubtitleOverlay();\n\n let settingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem('Video Quality', new VideoQualitySelectBox()),\n new SettingsPanelItem('Speed', new PlaybackSpeedSelectBox()),\n new SettingsPanelItem('Audio Quality', new AudioQualitySelectBox()),\n ],\n }),\n ],\n hidden: true,\n });\n\n let subtitleListBox = new SubtitleListBox();\n let subtitleSettingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem(null, subtitleListBox),\n ],\n }),\n ],\n hidden: true,\n });\n\n let audioTrackListBox = new AudioTrackListBox();\n let audioTrackSettingsPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [\n new SettingsPanelItem(null, audioTrackListBox),\n ],\n }),\n ],\n hidden: true,\n });\n\n let controlBar = new ControlBar({\n components: [\n audioTrackSettingsPanel,\n subtitleSettingsPanel,\n settingsPanel,\n new Container({\n components: [\n new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.CurrentTime, hideInLivePlayback: true }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.TotalTime, cssClasses: ['text-right'] }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n new Container({\n components: [\n new PlaybackToggleButton(),\n new QuickSeekButton({ seekSeconds: -10 }),\n new QuickSeekButton({ seekSeconds: 10 }),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new CastToggleButton(),\n new VRToggleButton(),\n new SettingsToggleButton({\n settingsPanel: audioTrackSettingsPanel,\n cssClass: 'ui-audiotracksettingstogglebutton',\n }),\n new SettingsToggleButton({\n settingsPanel: subtitleSettingsPanel,\n cssClass: 'ui-subtitlesettingstogglebutton',\n }),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new CastStatusOverlay(),\n controlBar,\n new TitleBar(),\n new RecommendationOverlay(),\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n });\n }\n}","import { Component, ComponentConfig } from './components/component';\n\nexport interface Offset {\n left: number;\n top: number;\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface CssProperties {\n [propertyName: string]: string;\n}\n\n/**\n * Extends the {@link HTMLElement} interface with a component attribute to store the associated component.\n */\nexport interface HTMLElementWithComponent extends HTMLElement {\n component?: Component<ComponentConfig>;\n}\n\n/**\n * Simple DOM manipulation and DOM element event handling modeled after jQuery (as replacement for jQuery).\n *\n * Like jQuery, DOM operates on single elements and lists of elements. For example: creating an element returns a DOM\n * instance with a single element, selecting elements returns a DOM instance with zero, one, or many elements. Similar\n * to jQuery, setters usually affect all elements, while getters operate on only the first element.\n * Also similar to jQuery, most methods (except getters) return the DOM instance facilitating easy chaining of method\n * calls.\n *\n * Built with the help of: http://youmightnotneedjquery.com/\n */\nexport class DOM {\n\n private document: Document;\n\n /**\n * The list of elements that the instance wraps. Take care that not all methods can operate on the whole list,\n * getters usually just work on the first element.\n */\n private elements: HTMLElementWithComponent[];\n\n /**\n * Creates a DOM element.\n * @param tagName the tag name of the DOM element\n * @param attributes a list of attributes of the element\n * @param component the {@link Component} the DOM element is associated with\n */\n constructor(tagName: string, attributes: {[name: string]: string}, component?: Component<ComponentConfig>);\n /**\n * Selects all elements from the DOM that match the specified selector.\n * @param selector the selector to match DOM elements with\n */\n constructor(selector: string);\n /**\n * Wraps a plain HTMLElement with a DOM instance.\n * @param element the HTMLElement to wrap with DOM\n */\n constructor(element: HTMLElement);\n /**\n * Wraps a list of plain HTMLElements with a DOM instance.\n * @param elements the HTMLElements to wrap with DOM\n */\n constructor(elements: HTMLElement[]);\n /**\n * Wraps the document with a DOM instance. Useful to attach event listeners to the document.\n * @param document the document to wrap\n */\n constructor(document: Document);\n constructor(\n something: string | HTMLElement | HTMLElement[] | Document,\n attributes?: {[name: string]: string},\n component?: Component<ComponentConfig>,\n ) {\n this.document = document; // Set the global document to the local document field\n\n if (something instanceof Array) {\n if (something.length > 0 && something[0] instanceof HTMLElement) {\n let elements = something as HTMLElementWithComponent[];\n this.elements = elements;\n }\n }\n else if (something instanceof HTMLElement) {\n let element = something as HTMLElementWithComponent;\n this.elements = [element];\n }\n else if (something instanceof Document) {\n // When a document is passed in, we do not do anything with it, but by setting this.elements to null\n // we give the event handling method a means to detect if the events should be registered on the document\n // instead of elements.\n this.elements = null;\n }\n else if (attributes) {\n let tagName = something;\n let element = document.createElement(tagName) as HTMLElementWithComponent;\n\n for (let attributeName in attributes) {\n let attributeValue = attributes[attributeName];\n if (attributeValue != null) {\n element.setAttribute(attributeName, attributeValue);\n }\n }\n\n if (component) {\n element.component = component;\n }\n\n this.elements = [element];\n }\n else {\n let selector = something;\n this.elements = this.findChildElements(selector) as HTMLElementWithComponent[];\n }\n }\n\n /**\n * Gets the number of elements that this DOM instance currently holds.\n * @returns {number} the number of elements\n */\n get length(): number {\n return this.elements ? this.elements.length : 0;\n }\n\n /**\n * Gets the HTML elements that this DOM instance currently holds.\n * @returns {HTMLElement[]} the raw HTML elements\n */\n get(): HTMLElementWithComponent[];\n /**\n * Gets an HTML element from the list elements that this DOM instance currently holds.\n * @param index The zero-based index into the element list. Can be negative to return an element from the end,\n * e.g. -1 returns the last element.\n */\n get(index: number): HTMLElementWithComponent;\n get(index?: number): HTMLElementWithComponent | HTMLElementWithComponent[] {\n if (index === undefined) {\n return this.elements;\n } else if (!this.elements || index >= this.elements.length || index < -this.elements.length) {\n return undefined;\n } else if (index < 0) {\n return this.elements[this.elements.length - index];\n } else {\n return this.elements[index];\n }\n }\n\n /**\n * A shortcut method for iterating all elements. Shorts this.elements.forEach(...) to this.forEach(...).\n * @param handler the handler to execute an operation on an element\n */\n private forEach(handler: (element: HTMLElement) => void): void {\n if (!this.elements) {\n return;\n }\n this.elements.forEach((element) => {\n handler(element);\n });\n }\n\n private findChildElementsOfElement(element: HTMLElement | Document, selector: string): HTMLElement[] {\n let childElements = element.querySelectorAll(selector);\n\n // Convert NodeList to Array\n // https://toddmotto.com/a-comprehensive-dive-into-nodelists-arrays-converting-nodelists-and-understanding-the-dom/\n return [].slice.call(childElements);\n }\n\n private findChildElements(selector: string): HTMLElement[] {\n let allChildElements = <HTMLElement[]>[];\n\n if (this.elements) {\n this.forEach((element) => {\n allChildElements = allChildElements.concat(this.findChildElementsOfElement(element, selector));\n });\n }\n else {\n return this.findChildElementsOfElement(document, selector);\n }\n\n return allChildElements;\n }\n\n /**\n * Finds all child elements of all elements matching the supplied selector.\n * @param selector the selector to match with child elements\n * @returns {DOM} a new DOM instance representing all matched children\n */\n find(selector: string): DOM {\n let allChildElements = this.findChildElements(selector) as HTMLElementWithComponent[];\n return new DOM(allChildElements);\n }\n\n /**\n * Focuses to the first input element\n */\n focusToFirstInput() {\n const inputElements = this.findChildElements('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n if (inputElements.length > 0) {\n inputElements[0].focus();\n }\n }\n\n /**\n * Focuses to the first input element\n */\n scrollTo(x: number, y: number) {\n this.elements[0].scrollTo(x, y);\n }\n\n /**\n * Returns a string of the inner HTML content of the first element.\n */\n html(): string;\n /**\n * Sets the inner HTML content of all elements.\n * @param content a string of plain text or HTML markup\n */\n html(content: string): DOM;\n html(content?: string): string | DOM {\n if (arguments.length > 0) {\n return this.setHtml(content);\n }\n else {\n return this.getHtml();\n }\n }\n\n private getHtml(): string | null {\n return this.elements[0].innerHTML;\n }\n\n private setHtml(content: string): DOM {\n if (content === undefined || content == null) {\n // Set to empty string to avoid innerHTML getting set to 'undefined' (all browsers) or 'null' (IE9)\n content = '';\n }\n\n this.forEach((element) => {\n element.innerHTML = content;\n });\n\n return this;\n }\n\n /**\n * Clears the inner HTML of all elements (deletes all children).\n * @returns {DOM}\n */\n empty(): DOM {\n this.forEach((element) => {\n element.innerHTML = '';\n });\n return this;\n }\n\n /**\n * Returns the current value of the first form element, e.g. the selected value of a select box or the text if an\n * input field.\n * @returns {string} the value of a form element\n */\n val(): string {\n let element = this.elements[0];\n\n if (element instanceof HTMLSelectElement || element instanceof HTMLInputElement) {\n return element.value;\n }\n else {\n // TODO add support for missing form elements\n throw new Error(`val() not supported for ${typeof element}`);\n }\n }\n\n /**\n * Returns the value of an attribute on the first element.\n * @param attribute\n */\n attr(attribute: string): string | null;\n /**\n * Sets an attribute on all elements.\n * @param attribute the name of the attribute\n * @param value the value of the attribute\n */\n attr(attribute: string, value: string): DOM;\n attr(attribute: string, value?: string): string | null | DOM {\n if (arguments.length > 1) {\n return this.setAttr(attribute, value);\n }\n else {\n return this.getAttr(attribute);\n }\n }\n\n /**\n * Removes the attribute of the element.\n * @param attribute\n */\n removeAttr(attribute: string) {\n this.forEach((element) => {\n element.removeAttribute(attribute);\n });\n }\n\n private getAttr(attribute: string): string | null {\n return this.elements[0].getAttribute(attribute);\n }\n\n private setAttr(attribute: string, value: string): DOM {\n this.forEach((element) => {\n element.setAttribute(attribute, value);\n });\n return this;\n }\n\n /**\n * Returns the value of a data element on the first element.\n * @param dataAttribute the name of the data attribute without the 'data-' prefix\n */\n data(dataAttribute: string): string | null;\n /**\n * Sets a data attribute on all elements.\n * @param dataAttribute the name of the data attribute without the 'data-' prefix\n * @param value the value of the data attribute\n */\n data(dataAttribute: string, value: string): DOM;\n data(dataAttribute: string, value?: string): string | null | DOM {\n if (arguments.length > 1) {\n return this.setData(dataAttribute, value);\n }\n else {\n return this.getData(dataAttribute);\n }\n }\n\n private getData(dataAttribute: string): string | null {\n return this.elements[0].getAttribute('data-' + dataAttribute);\n }\n\n private setData(dataAttribute: string, value: string): DOM {\n this.forEach((element) => {\n element.setAttribute('data-' + dataAttribute, value);\n });\n return this;\n }\n\n /**\n * Appends one or more DOM elements as children to all elements.\n * @param childElements the chrild elements to append\n * @returns {DOM}\n */\n append(...childElements: DOM[]): DOM {\n this.forEach((element) => {\n childElements.forEach((childElement) => {\n childElement.elements.forEach((_, index) => {\n element.appendChild(childElement.elements[index]);\n });\n });\n });\n return this;\n }\n\n /**\n * Removes all elements from the DOM.\n */\n remove(): void {\n this.forEach((element) => {\n let parent = element.parentNode;\n if (parent) {\n parent.removeChild(element);\n }\n });\n }\n\n /**\n * Returns the offset of the first element from the document's top left corner.\n * @returns {Offset}\n */\n offset(): Offset {\n let element = this.elements[0];\n let elementRect = element.getBoundingClientRect();\n let htmlRect = document.body.parentElement.getBoundingClientRect();\n\n // Virtual viewport scroll handling (e.g. pinch zoomed viewports in mobile browsers or desktop Chrome/Edge)\n // 'normal' zooms and virtual viewport zooms (aka layout viewport) result in different\n // element.getBoundingClientRect() results:\n // - with normal scrolls, the clientRect decreases with an increase in scroll(Top|Left)/page(X|Y)Offset\n // - with pinch zoom scrolls, the clientRect stays the same while scroll/pageOffset changes\n // This means, that the combination of clientRect + scroll/pageOffset does not work to calculate the offset\n // from the document's upper left origin when pinch zoom is used.\n // To work around this issue, we do not use scroll/pageOffset but get the clientRect of the html element and\n // subtract it from the element's rect, which always results in the offset from the document origin.\n // NOTE: the current way of offset calculation was implemented specifically to track event positions on the\n // seek bar, and it might break compatibility with jQuery's offset() method. If this ever turns out to be a\n // problem, this method should be reverted to the old version and the offset calculation moved to the seek bar.\n\n return {\n top: elementRect.top - htmlRect.top,\n left: elementRect.left - htmlRect.left,\n };\n }\n\n /**\n * Returns the width of the first element.\n * @returns {number} the width of the first element\n */\n width(): number {\n // TODO check if this is the same as jQuery's width() (probably not)\n return this.elements[0].offsetWidth;\n }\n\n /**\n * Returns the height of the first element.\n * @returns {number} the height of the first element\n */\n height(): number {\n // TODO check if this is the same as jQuery's height() (probably not)\n return this.elements[0].offsetHeight;\n }\n\n /**\n * Returns the size of the first element.\n * @return {Size} the size of the first element\n */\n size(): Size {\n return { width: this.width(), height: this.height() };\n }\n\n /**\n * Attaches an event handler to one or more events on all elements.\n * @param eventName the event name (or multiple names separated by space) to listen to\n * @param eventHandler the event handler to call when the event fires\n * @param options the options for this event handler\n * @returns {DOM}\n */\n on(eventName: string, eventHandler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): DOM {\n let events = eventName.split(' ');\n\n events.forEach((event) => {\n if (this.elements == null) {\n this.document.addEventListener(event, eventHandler, options);\n }\n else {\n this.forEach((element) => {\n element.addEventListener(event, eventHandler, options);\n });\n }\n });\n\n return this;\n }\n\n /**\n * Removes an event handler from one or more events on all elements.\n * @param eventName the event name (or multiple names separated by space) to remove the handler from\n * @param eventHandler the event handler to remove\n * @param options the options for this event handler\n * @returns {DOM}\n */\n off(eventName: string, eventHandler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): DOM {\n let events = eventName.split(' ');\n\n events.forEach((event) => {\n if (this.elements == null) {\n this.document.removeEventListener(event, eventHandler, options);\n }\n else {\n this.forEach((element) => {\n element.removeEventListener(event, eventHandler, options);\n });\n }\n });\n\n return this;\n }\n\n /**\n * Adds the specified class(es) to all elements.\n * @param className the class(es) to add, multiple classes separated by space\n * @returns {DOM}\n */\n addClass(className: string): DOM {\n this.forEach((element) => {\n if (element.classList) {\n const classNames = className.split(' ')\n .filter(className => className.length > 0);\n\n if (classNames.length > 0) {\n element.classList.add(...classNames);\n }\n }\n else {\n element.className += ' ' + className;\n }\n });\n\n return this;\n }\n\n /**\n * Removed the specified class(es) from all elements.\n * @param className the class(es) to remove, multiple classes separated by space\n * @returns {DOM}\n */\n removeClass(className: string): DOM {\n this.forEach((element) => {\n if (element.classList) {\n const classNames = className.split(' ')\n .filter(className => className.length > 0);\n\n if (classNames.length > 0) {\n element.classList.remove(...classNames);\n }\n }\n else {\n element.className = element.className.replace(\n new RegExp('(^|\\\\b)' + className.split(' ').join('|') + '(\\\\b|$)', 'gi'), ' ');\n }\n });\n\n return this;\n }\n\n /**\n * Checks if any of the elements has the specified class.\n * @param className the class name to check\n * @returns {boolean} true if one of the elements has the class attached, else if no element has it attached\n */\n hasClass(className: string): boolean {\n let hasClass = false;\n\n this.forEach((element) => {\n if (element.classList) {\n if (element.classList.contains(className)) {\n // Since we are inside a handler, we can't just 'return true'. Instead, we save it to a variable\n // and return it at the end of the function body.\n hasClass = true;\n }\n }\n else {\n if (new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className)) {\n // See comment above\n hasClass = true;\n }\n }\n });\n\n return hasClass;\n }\n\n /**\n * Returns the value of a CSS property of the first element.\n * @param propertyName the name of the CSS property to retrieve the value of\n */\n css(propertyName: string): string | null;\n /**\n * Sets the value of a CSS property on all elements.\n * @param propertyName the name of the CSS property to set the value for\n * @param value the value to set for the given CSS property\n */\n css(propertyName: string, value: string): DOM;\n /**\n * Sets a collection of CSS properties and their values on all elements.\n * @param propertyValueCollection an object containing pairs of property names and their values\n */\n css(propertyValueCollection: CssProperties): DOM;\n css(propertyNameOrCollection: string | CssProperties, value?: string): string | null | DOM {\n if (typeof propertyNameOrCollection === 'string') {\n let propertyName = propertyNameOrCollection;\n\n if (arguments.length === 2) {\n return this.setCss(propertyName, value);\n }\n else {\n return this.getCss(propertyName);\n }\n }\n else {\n let propertyValueCollection = propertyNameOrCollection;\n return this.setCssCollection(propertyValueCollection);\n }\n }\n\n /**\n * Removes an inline CSS property if it exists\n * @param propertyName name of the property to remove\n * @param elementIndex index of the element whose CSS property should get removed\n */\n removeCss(propertyName: string, elementIndex = 0): string {\n return this.elements[elementIndex].style.removeProperty(propertyName);\n }\n\n private getCss(propertyName: string): string | null {\n return getComputedStyle(this.elements[0])[<any>propertyName];\n }\n\n private setCss(propertyName: string, value: string): DOM {\n this.forEach((element) => {\n // <any> cast to resolve TS7015: http://stackoverflow.com/a/36627114/370252\n element.style[<any>propertyName] = value;\n });\n return this;\n }\n\n private setCssCollection(ruleValueCollection: {[ruleName: string]: string}): DOM {\n this.forEach((element) => {\n // http://stackoverflow.com/a/34490573/370252\n Object.assign(element.style, ruleValueCollection);\n });\n\n return this;\n }\n}\n","import {ErrorMessageMap, ErrorMessageTranslator} from './components/errormessageoverlay';\nimport { ErrorEvent } from 'bitmovin-player';\nimport { MobileV3PlayerErrorEvent, MobileV3SourceErrorEvent } from './mobilev3playerapi';\n\n/**\n * @category Utils\n */\nexport namespace ErrorUtils {\n\n export const defaultErrorMessages: ErrorMessageMap = {\n 1000: 'Error is unknown',\n 1001: 'The player API is not available after a call to PlayerAPI.destroy.',\n 1100: 'General setup error',\n 1101: 'There was an error when inserting the HTML video element',\n 1102: 'No configuration was provided',\n 1103: 'The license is not valid',\n 1104: 'The the domain-locked player is not authorized to playback on this domain',\n 1105: 'The domain is not allowlisted',\n 1106: 'The license server URL is invalid',\n 1107: 'The impression server URL is invalid',\n 1108: 'Could not initialize a rendering engine',\n 1109: 'The used flash version does not support playback',\n 1110: 'Native Flash is not authorized by a valid Adobe token',\n 1111: 'Flash doesn\\'t have sufficient resources',\n 1112: 'Flash container API not available',\n 1113: 'Protocol not supported. This site has been loaded using \"file\" protocol, but unfortunately this is not supported. Please load the page using a web server (using http or https)',\n 1200: 'General source error',\n 1201: 'No valid source was provided',\n 1202: 'The downloaded manifest is invalid',\n 1203: 'There was no technology detected to playback the provided source',\n 1204: 'The stream type is not supported',\n 1205: 'The forced technology is not supported',\n 1206: 'No stream found for supported technologies.',\n 1207: 'The downloaded segment is empty',\n 1208: 'The manifest could not be loaded',\n 1209: 'Progressive stream type not supported or the stream has an error',\n 1210: 'HLS stream has an error',\n 1211: 'The encryption method is not supported',\n 1300: 'General playback error',\n 1301: 'Video decoder or demuxer had an error with the content',\n 1302: 'General error if Flash renderer has an error',\n 1303: 'Flash doesn\\'t have sufficient resources',\n 1304: 'The transmuxer could not be initialized',\n 1400: 'Network error while downloading',\n 1401: 'The manifest download timed out',\n 1402: 'The segment download timed out',\n 1403: 'The progressive stream download timed out',\n 1404: 'The Certificate could not be loaded',\n 2000: 'General DRM error',\n 2001: 'Required DRM configuration is missing',\n 2002: 'The licensing server URL is missing',\n 2003: 'License request failed',\n 2004: 'Key or KeyId is missing',\n 2005: 'Key size is not supported',\n 2006: 'Unable to instantiate a key system supporting the required combinations',\n 2007: 'Unable to create or initialize key session',\n 2008: 'The MediaKey object could not be created/initialized',\n 2009: 'Key error',\n 2010: 'The key system is not supported',\n 2011: 'The certificate is not valid',\n 2012: 'Invalid header key/value pair for PlayReady license request',\n 2013: 'Content cannot be played back because the output is restricted on this machine',\n 2014: 'DRM error for the Flash renderer',\n 2100: 'General VR error',\n 2101: 'Player technology not compatible with VR playback',\n 3000: 'General module error',\n 3001: 'The definition of the module is invalid (e.g. incomplete).',\n 3002: 'The module definition specifies dependencies but the module is not provided via a function for deferred loading.',\n 3003: 'A module cannot be loaded because it has not been added to the player core.',\n 3004: 'A module cannot be loaded because one or more dependencies are missing.',\n 3100: 'An Advertising module error has occurred. Refer to the attached AdvertisingError.',\n };\n\n export const defaultMobileV3ErrorMessageTranslator = (error: MobileV3PlayerErrorEvent | MobileV3SourceErrorEvent) => {\n return error.message;\n };\n\n export const defaultWebErrorMessageTranslator: ErrorMessageTranslator = (error: ErrorEvent) => {\n const errorMessage = ErrorUtils.defaultErrorMessages[error.code];\n\n if (errorMessage) {\n // Use the error message text if there is one\n return `${errorMessage as string}\\n(${error.name})`; // default error message style\n } else {\n // Fallback to error code/name if no message is defined\n return `${error.code} ${error.name}`;\n }\n };\n}\n","import {ArrayUtils} from './arrayutils';\nimport { Timeout } from './timeout';\n/**\n * Function interface for event listeners on the {@link EventDispatcher}.\n */\nexport interface EventListener<Sender, Args> {\n (sender: Sender, args: Args): void;\n}\n\n/**\n * Empty type for creating {@link EventDispatcher event dispatchers} that do not carry any arguments.\n */\nexport interface NoArgs {\n}\n\n/**\n * Event args for an event that can be canceled.\n */\nexport interface CancelEventArgs extends NoArgs {\n /**\n * Gets or sets a flag whether the event should be canceled.\n */\n cancel?: boolean;\n}\n\n/**\n * Public interface that represents an event. Can be used to subscribe to and unsubscribe from events.\n */\nexport interface Event<Sender, Args> {\n /**\n * Subscribes an event listener to this event dispatcher.\n * @param listener the listener to add\n */\n subscribe(listener: EventListener<Sender, Args>): void;\n\n /**\n * Subscribes an event listener to this event dispatcher that is only called once.\n * @param listener the listener to add\n */\n subscribeOnce(listener: EventListener<Sender, Args>): void;\n\n /**\n * Subscribes an event listener to this event dispatcher that will be called at a limited rate with a minimum\n * interval of the specified milliseconds.\n * @param listener the listener to add\n * @param rateMs the rate in milliseconds to which calling of the listeners should be limited\n */\n subscribeRateLimited(listener: EventListener<Sender, Args>, rateMs: number): void;\n\n /**\n * Unsubscribes a subscribed event listener from this dispatcher.\n * @param listener the listener to remove\n * @returns {boolean} true if the listener was successfully unsubscribed, false if it isn't subscribed on this\n * dispatcher\n */\n unsubscribe(listener: EventListener<Sender, Args>): boolean;\n}\n\n/**\n * Event dispatcher to subscribe and trigger events. Each event should have its own dispatcher.\n */\nexport class EventDispatcher<Sender, Args> implements Event<Sender, Args> {\n\n private listeners: EventListenerWrapper<Sender, Args>[] = [];\n\n constructor() {\n }\n\n /**\n * {@inheritDoc}\n */\n subscribe(listener: EventListener<Sender, Args>) {\n this.listeners.push(new EventListenerWrapper(listener));\n }\n\n /**\n * {@inheritDoc}\n */\n subscribeOnce(listener: EventListener<Sender, Args>) {\n this.listeners.push(new EventListenerWrapper(listener, true));\n }\n\n /**\n * {@inheritDoc}\n */\n subscribeRateLimited(listener: EventListener<Sender, Args>, rateMs: number) {\n this.listeners.push(new RateLimitedEventListenerWrapper(listener, rateMs));\n }\n\n /**\n * {@inheritDoc}\n */\n unsubscribe(listener: EventListener<Sender, Args>): boolean {\n // Iterate through listeners, compare with parameter, and remove if found\n // NOTE: In case we ever remove all matching listeners instead of just the first, we need to reverse-iterate here\n for (let i = 0; i < this.listeners.length; i++) {\n let subscribedListener = this.listeners[i];\n if (subscribedListener.listener === listener) {\n subscribedListener.clear();\n ArrayUtils.remove(this.listeners, subscribedListener);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Removes all listeners from this dispatcher.\n */\n unsubscribeAll(): void {\n // In case of RateLimitedEventListenerWrapper we need to make sure that the timeout callback won't be called\n for (let listener of this.listeners) {\n listener.clear();\n }\n\n this.listeners = [];\n }\n\n /**\n * Dispatches an event to all subscribed listeners.\n * @param sender the source of the event\n * @param args the arguments for the event\n */\n dispatch(sender: Sender, args: Args = null) {\n let listenersToRemove = [];\n\n // Call every listener\n // We iterate over a copy of the array of listeners to avoid the case where events are not fired on listeners when\n // listeners are unsubscribed from within the event handlers during a dispatch (because the indices change and\n // listeners are shifted within the array).\n // This means that listener x+1 will still be called if unsubscribed from within the handler of listener x, as well\n // as listener y+1 will not be called when subscribed from within the handler of listener y.\n // Array.slice(0) is the fastest array copy method according to: https://stackoverflow.com/a/21514254/370252\n const listeners = this.listeners.slice(0);\n for (let listener of listeners) {\n listener.fire(sender, args);\n\n if (listener.isOnce()) {\n listenersToRemove.push(listener);\n }\n }\n\n // Remove one-time listener\n for (let listenerToRemove of listenersToRemove) {\n ArrayUtils.remove(this.listeners, listenerToRemove);\n }\n }\n\n /**\n * Returns the event that this dispatcher manages and on which listeners can subscribe and unsubscribe event handlers.\n * @returns {Event}\n */\n getEvent(): Event<Sender, Args> {\n // For now, just cast the event dispatcher to the event interface. At some point in the future when the\n // codebase grows, it might make sense to split the dispatcher into separate dispatcher and event classes.\n return <Event<Sender, Args>>this;\n }\n}\n\n/**\n * A basic event listener wrapper to manage listeners within the {@link EventDispatcher}. This is a 'private' class\n * for internal dispatcher use and it is therefore not exported.\n */\nclass EventListenerWrapper<Sender, Args> {\n\n private eventListener: EventListener<Sender, Args>;\n private once: boolean;\n\n constructor(listener: EventListener<Sender, Args>, once: boolean = false) {\n this.eventListener = listener;\n this.once = once;\n }\n\n /**\n * Returns the wrapped event listener.\n * @returns {EventListener<Sender, Args>}\n */\n get listener(): EventListener<Sender, Args> {\n return this.eventListener;\n }\n\n /**\n * Fires the wrapped event listener with the given arguments.\n * @param sender\n * @param args\n */\n fire(sender: Sender, args: Args) {\n this.eventListener(sender, args);\n }\n\n /**\n * Checks if this listener is scheduled to be called only once.\n * @returns {boolean} once if true\n */\n isOnce(): boolean {\n return this.once;\n }\n\n clear(): void {\n }\n}\n\ninterface EventAttributes<Sender, Args> {\n sender: Sender;\n args: Args;\n}\n\n/**\n * Extends the basic {@link EventListenerWrapper} with rate-limiting functionality.\n */\nclass RateLimitedEventListenerWrapper<Sender, Args> extends EventListenerWrapper<Sender, Args> {\n\n private readonly rateMs: number;\n private readonly rateLimitingEventListener: EventListener<Sender, Args>;\n\n // save last seen event attributes\n private lastSeenEvent: EventAttributes<Sender, Args>;\n\n private rateLimitTimout: Timeout;\n\n constructor(listener: EventListener<Sender, Args>, rateMs: number) {\n super(listener); // sets the event listener sink\n\n this.rateMs = rateMs;\n\n // starting limiting the events to the given value\n const startRateLimiting = () => {\n this.rateLimitTimout.start();\n };\n\n // timout for limiting the events\n this.rateLimitTimout = new Timeout(this.rateMs, () => {\n if (this.lastSeenEvent) {\n this.fireSuper(this.lastSeenEvent.sender, this.lastSeenEvent.args);\n startRateLimiting(); // start rateLimiting again to keep rate limit active even after firing the last seen event\n this.lastSeenEvent = null;\n }\n });\n\n // In case the events stopping during the rateLimiting we need to track the last seen one and delegate after the\n // rate limiting is finished. This prevents missing the last update due to the rate limit.\n this.rateLimitingEventListener = (sender: Sender, args: Args) => {\n // only fire events if the rateLimiting is not running\n if (this.shouldFireEvent()) {\n this.fireSuper(sender, args);\n startRateLimiting();\n return;\n }\n\n this.lastSeenEvent = {\n sender: sender,\n args: args,\n };\n };\n }\n\n private shouldFireEvent(): boolean {\n return !this.rateLimitTimout.isActive();\n }\n\n private fireSuper(sender: Sender, args: Args) {\n // Fire the actual external event listener\n super.fire(sender, args);\n }\n\n fire(sender: Sender, args: Args) {\n // Fire the internal rate-limiting listener instead of the external event listener\n this.rateLimitingEventListener(sender, args);\n }\n\n clear(): void {\n super.clear();\n this.rateLimitTimout.clear();\n }\n}\n","const FocusVisibleCssClassName = '{{PREFIX}}-focus-visible';\n\nexport class FocusVisibilityTracker {\n private readonly eventHandlerMap: { [eventName: string]: EventListenerOrEventListenerObject };\n private lastInteractionWasKeyboard: boolean = true;\n\n constructor(private bitmovinUiPrefix: string) {\n this.eventHandlerMap = {\n mousedown: this.onMouseOrPointerOrTouch,\n pointerdown: this.onMouseOrPointerOrTouch,\n touchstart: this.onMouseOrPointerOrTouch,\n keydown: this.onKeyDown,\n focus: this.onFocus,\n blur: this.onBlur,\n };\n this.registerEventListeners();\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n this.lastInteractionWasKeyboard = true;\n };\n\n private onMouseOrPointerOrTouch = () => (this.lastInteractionWasKeyboard = false);\n\n private onFocus = ({ target: element }: FocusEvent) => {\n if (\n this.lastInteractionWasKeyboard &&\n isHtmlElement(element) &&\n isBitmovinUi(element, this.bitmovinUiPrefix) &&\n !element.classList.contains(FocusVisibleCssClassName)\n ) {\n element.classList.add(FocusVisibleCssClassName);\n }\n };\n\n private onBlur = ({ target: element }: FocusEvent) => {\n if (isHtmlElement(element)) {\n element.classList.remove(FocusVisibleCssClassName);\n }\n };\n\n private registerEventListeners(): void {\n for (const event in this.eventHandlerMap) {\n document.addEventListener(event, this.eventHandlerMap[event], true);\n }\n }\n\n private unregisterEventListeners(): void {\n for (const event in this.eventHandlerMap) {\n document.removeEventListener(event, this.eventHandlerMap[event], true);\n }\n }\n\n public release(): void {\n this.unregisterEventListeners();\n }\n}\n\nfunction isBitmovinUi(element: Element, bitmovinUiPrefix: string): boolean {\n return element.id.indexOf(bitmovinUiPrefix) === 0;\n}\n\nfunction isHtmlElement(element: unknown): element is HTMLElement & { classList: DOMTokenList } {\n return (\n element instanceof HTMLElement && element.classList instanceof DOMTokenList\n );\n}\n","import { PlayerAPI } from 'bitmovin-player';\n/**\n * The Group Playback API offers control over synchronized playback of a group of clients, e.g. for Apple SharePlay\n * sessions.\n\n * Note: The API currently only covers the immediate needs of the iOS SDK in combination with our UI which is regarding\n * temporarily suspending synchronization of the player from the group. But it is open to be extended as needed in the\n * future.\n */\n\n/**\n * Reason for suspending the synchronization with the group.\n */\nexport enum GroupPlaybackSuspensionReason {\n UserIsScrubbing = 'userIsScrubbing',\n}\n\n/**\n * A representation of a temporary break in participation.\n */\nexport interface GroupPlaybackSuspension {\n /**\n * The reason for the suspension.\n */\n reason: GroupPlaybackSuspensionReason;\n\n /**\n * A unique identifier.\n */\n id: string;\n}\n\n/**\n * Options to be considered upon ending a suspension.\n */\ninterface EndGroupPlaybackSuspensionOptions {\n /**\n * A proposed time for the group to seek to.\n */\n proposedPlaybackTime?: number;\n}\n\n/**\n * Group Playback API offering control over the player's participation in synchronized playback of a group of clients.\n * For example, an Apple SharePlay session.\n */\ninterface GroupPlaybackAPI {\n /**\n * Begins a new suspension.\n *\n * Temporarily suspends the local player's synchronization with the group. While suspended, any local playback control\n * action (e.g. play, pause, seek) will not be forwarded to the group and any action originating from another group\n * participant will not be performed on the local player.\n *\n * @remarks\n * It is possible for multiple suspensions to exist exist simultaneously with different suspension reasons. The player\n * will re-synchronize with the group once all existing suspensions have ended.\n *\n * @param reason - The reason for the suspension.\n * @returns A suspension object.\n */\n beginSuspension(reason: GroupPlaybackSuspensionReason): GroupPlaybackSuspension;\n\n /**\n * Ends the given suspension.\n *\n * @param suspension - The suspension to be ended.\n * @param options - Optional. Options to be considered when ending the suspension, e.g. a proposed seek time for the group.\n */\n endSuspension(suspension: GroupPlaybackSuspension, options?: EndGroupPlaybackSuspensionOptions): void;\n\n /**\n * Whether the player is currently participating in a group playback session.\n */\n hasJoined(): boolean;\n\n /**\n * Whether the player is currently suspending synchronization with the group.\n * Can only return true if `hasJoined()` also is true.\n */\n isSuspended(): boolean;\n}\n\n\nexport interface ExtendedPlayerAPI extends PlayerAPI {\n /**\n * Group Playback API\n *\n * @remarks\n * This API is optional as not every platform supports group playback.\n */\n groupPlayback?: GroupPlaybackAPI;\n}\n","export namespace Guid {\n\n let guid = 1;\n\n export function next() {\n return guid++;\n }\n}\n","import {DOM} from './dom';\n\nexport interface ImageLoadedCallback {\n (url: string, width: number, height: number): void;\n}\n\ninterface ImageLoaderState {\n url: string;\n image: DOM;\n loadedCallback: ImageLoadedCallback;\n loaded: boolean;\n width: number;\n height: number;\n}\n\n/**\n * Tracks the loading state of images.\n */\nexport class ImageLoader {\n\n private state: { [url: string]: ImageLoaderState; } = {};\n\n /**\n * Loads an image and call the callback once the image is loaded. If the image is already loaded, the callback\n * is called immediately, else it is called once loading has finished. Calling this method multiple times for the\n * same image while it is loading calls only let callback passed into the last call.\n * @param url The url to the image to load\n * @param loadedCallback The callback that is called when the image is loaded\n */\n load(url: string, loadedCallback: ImageLoadedCallback): void {\n if (!this.state[url]) {\n // When the image was never attempted to be loaded before, we create a state and store it in the state map\n // for later use when the same image is requested to be loaded again.\n let state: ImageLoaderState = {\n url: url,\n image: new DOM('img', {}),\n loadedCallback: loadedCallback,\n loaded: false,\n width: 0,\n height: 0,\n };\n this.state[url] = state;\n\n // Listen to the load event, update the state and call the callback once the image is loaded\n state.image.on('load', (e) => {\n state.loaded = true;\n state.width = (<HTMLImageElement>state.image.get(0)).width;\n state.height = (<HTMLImageElement>state.image.get(0)).height;\n\n this.callLoadedCallback(state);\n });\n\n // Set the image URL to start the loading\n state.image.attr('src', state.url);\n } else {\n // We have a state for the requested image, so it is either already loaded or currently loading\n let state = this.state[url];\n\n // We overwrite the callback to make sure that only the callback of the latest call gets executed.\n // Earlier callbacks become invalid once a new load call arrives, and they are not called as long as the image\n // is not loaded.\n state.loadedCallback = loadedCallback;\n\n // When the image is already loaded, we directly execute the callback instead of waiting for the load event\n if (state.loaded) {\n this.callLoadedCallback(state);\n }\n }\n }\n\n private callLoadedCallback(state: ImageLoaderState): void {\n state.loadedCallback(state.url, state.width, state.height);\n }\n}\n","import vocabularyDe from './languages/de.json';\nimport vocabularyEn from './languages/en.json';\nimport vocabularyEs from './languages/es.json';\nimport vocabularyNl from './languages/nl.json';\n\nimport { LocalizationConfig } from '../uimanager.js';\n\nexport const defaultVocabularies: Vocabularies = {\n 'en': vocabularyEn,\n 'de': vocabularyDe,\n 'es': vocabularyEs,\n 'nl': vocabularyNl,\n};\n\nconst defaultLocalizationConfig: LocalizationConfig = {\n language: 'en',\n vocabularies: defaultVocabularies,\n};\n\n/**\n * @category Localization\n */\nexport type Localizer = () => string;\n/**\n * @category Localization\n */\nexport type LocalizableText = string | Localizer;\n\n/**\n * @category Localization\n */\nexport interface Vocabulary {\n 'settings.video.quality': string;\n 'settings.audio.quality': string;\n 'settings.audio.track': string;\n 'settings.audio.mute': string;\n 'settings.audio.volume': string;\n 'settings.subtitles': string;\n 'settings.subtitles.font.color': string;\n 'settings.subtitles.font.opacity': string;\n 'settings.subtitles.background.color': string;\n 'settings.subtitles.background.opacity': string;\n 'settings.subtitles.font.size': string;\n 'settings.subtitles.characterEdge': string;\n 'settings.subtitles.characterEdge.raised': string;\n 'settings.subtitles.characterEdge.depressed': string;\n 'settings.subtitles.characterEdge.uniform': string;\n 'settings.subtitles.characterEdge.dropshadowed': string;\n 'settings.subtitles.font.family': string;\n 'settings.subtitles.font.family.monospacedserif': string;\n 'settings.subtitles.font.family.proportionalserif': string;\n 'settings.subtitles.font.family.monospacedsansserif': string;\n 'settings.subtitles.font.family.proportionalsansserif': string;\n 'settings.subtitles.font.family.casual': string;\n 'settings.subtitles.font.family.cursive': string;\n 'settings.subtitles.font.family.smallcapital': string;\n 'settings.subtitles.window.color': string;\n 'settings.subtitles.window.opacity': string;\n 'play': string;\n 'settings.time.hours': string;\n 'settings.time.minutes': string;\n 'settings.time.seconds': string;\n 'colors.white': string;\n 'colors.black': string;\n 'colors.red': string;\n 'colors.green': string;\n 'colors.blue': string;\n 'colors.cyan': string;\n 'colors.yellow': string;\n 'colors.magenta': string;\n 'percent': string;\n 'settings': string;\n 'ads.remainingTime': string;\n 'pictureInPicture': string;\n 'appleAirplay': string;\n 'googleCast': string;\n 'vr': string;\n 'off': string;\n 'auto': string;\n 'back': string;\n 'reset': string;\n 'replay': string;\n 'normal': string;\n 'default': string;\n 'open': string;\n 'close': string;\n 'fullscreen': string;\n 'speed': string;\n 'playPause': string;\n 'live': string;\n 'subtitle.example': string;\n 'subtitle.select': string;\n 'playingOn': string;\n 'connectingTo': string;\n 'watermarkLink': string;\n 'controlBar': string;\n 'player': string;\n 'seekBar': string;\n 'seekBar.value': string;\n 'seekBar.timeshift': string;\n 'seekBar.durationText': string;\n 'ecoMode': string;\n 'ecoMode.title': string;\n}\n\n/**\n * @category Localization\n */\nexport type CustomVocabulary<V> = V & Partial<Vocabulary>;\n\n/**\n * @category Localization\n */\nexport interface Vocabularies {\n [key: string]: CustomVocabulary<Record<string, string>>;\n}\n\n/**\n * @category Localization\n */\nexport class I18n {\n private language: string;\n private vocabulary: CustomVocabulary<Record<string, string>>;\n\n constructor(config: LocalizationConfig) {\n this.setConfig(config);\n }\n\n public setConfig(config: LocalizationConfig) {\n const mergedConfig = { ...defaultLocalizationConfig, ...config };\n const detectBrowserLanguage = mergedConfig.language === 'auto';\n const vocabularies = this.mergeVocabulariesWithDefaultVocabularies(mergedConfig.vocabularies);\n this.initializeLanguage(mergedConfig.language, detectBrowserLanguage, vocabularies);\n this.initializeVocabulary(vocabularies);\n }\n\n private static containsLanguage(vocabularies: Vocabularies, language: string) {\n return vocabularies.hasOwnProperty(language);\n }\n\n private mergeVocabulariesWithDefaultVocabularies(vocabularies: Vocabularies = {}) {\n const rawVocabularies: Vocabularies = { ...defaultVocabularies, ...vocabularies };\n return Object.keys(rawVocabularies).reduce((mergedVocabularies, language) => {\n let vocabulary = rawVocabularies[language];\n if (I18n.containsLanguage(defaultVocabularies, language) && I18n.containsLanguage(vocabularies, language)) {\n vocabulary = { ...defaultVocabularies[language], ...vocabularies[language] };\n }\n return { ...mergedVocabularies, [language]: vocabulary };\n }, {});\n }\n\n private initializeLanguage(\n language: string,\n browserLanguageDetectionEnabled: boolean,\n vocabularies: Vocabularies,\n ) {\n if (browserLanguageDetectionEnabled) {\n const userLanguage = window.navigator.language;\n\n if (I18n.containsLanguage(vocabularies, userLanguage)) {\n this.language = userLanguage;\n return;\n }\n const shortenedUserLanguage = userLanguage.slice(0, 2);\n if (I18n.containsLanguage(vocabularies, shortenedUserLanguage)) {\n this.language = shortenedUserLanguage;\n return;\n }\n }\n\n this.language = language;\n }\n\n private initializeVocabulary(vocabularies: Vocabularies) {\n this.vocabulary = ['en', this.language]\n .reduce((vocab, lang) => ({ ...vocab, ...(vocabularies[lang] || {}) }), {});\n }\n\n private replaceVariableWithPlaceholderIfExists(text: string, config: any) {\n const matches = text.match(new RegExp('{[a-zA-Z0-9]+}', 'g'));\n if (matches.length === 0) {\n return text;\n }\n\n return matches\n .map((m: string) => ({ match: m, key: m.slice(1, -1) }))\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n .reduce((str, { key, match }) => config.hasOwnProperty(key) ? str.replace(match, config[key]) : str, text);\n }\n\n public getLocalizer<V extends CustomVocabulary<Record<string, string>> = CustomVocabulary<Record<string, string>>>(\n key: keyof V,\n config?: Record<string, string | number>,\n ): Localizer {\n return () => {\n if (key == null) { // because sometimes we call toDomElement() without configuring the component or setting text...\n return undefined;\n }\n let vocabularyString = this.vocabulary[key as string];\n\n if (vocabularyString == null) {\n vocabularyString = key as string;\n }\n\n if (config != null) {\n vocabularyString = this.replaceVariableWithPlaceholderIfExists(vocabularyString, config);\n }\n\n return vocabularyString;\n };\n }\n\n public performLocalization(text: LocalizableText) {\n return typeof text === 'function' ? text() : text;\n }\n}\n\n/**\n * @category Localization\n */\nexport const i18n = new I18n(defaultLocalizationConfig);\n","module.exports={\n \"settings.video.quality\": \"Videoqualität\",\n \"settings.audio.quality\": \"Audioqualität\",\n \"settings.audio.track\": \"Audiospur\",\n \"speed\": \"Geschwindigkeit\",\n \"play\": \"Abspielen\",\n \"pause\": \"Pause\",\n \"playPause\": \"Abspielen/Pause\",\n \"open\": \"öffnen\",\n \"close\": \"Schließen\",\n \"settings.audio.mute\": \"Stummschaltung\",\n \"settings.audio.volume\": \"Lautstärke\",\n \"pictureInPicture\": \"Bild im Bild\",\n \"appleAirplay\": \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\": \"VR\",\n \"settings\": \"Einstellungen\",\n \"fullscreen\": \"Vollbild\",\n \"off\": \"aus\",\n \"settings.subtitles\": \"Untertitel\",\n \"settings.subtitles.font.size\": \"Größe\",\n \"settings.subtitles.font.family\": \"Schriftart\",\n \"settings.subtitles.font.color\": \"Farbe\",\n \"settings.subtitles.font.opacity\": \"Deckkraft\",\n \"settings.subtitles.characterEdge\": \"Ränder\",\n \"settings.subtitles.background.color\": \"Hintergrundfarbe\",\n \"settings.subtitles.background.opacity\": \"Hintergrunddeckkraft\",\n \"settings.subtitles.window.color\": \"Hintergrundfarbe\",\n \"settings.subtitles.window.opacity\": \"Hintergrunddeckkraft\",\n \"settings.time.hours\": \"Stunden\",\n \"settings.time.minutes\": \"Minuten\",\n \"settings.time.seconds\": \"Sekunden\",\n \"back\": \"Zurück\",\n \"reset\": \"Zurücksetzen\",\n \"replay\": \"Wiederholen\",\n \"ads.remainingTime\": \"Diese Anzeige endet in {remainingTime} Sekunden\",\n \"default\": \"standard\",\n \"colors.white\": \"weiß\",\n \"colors.black\": \"schwarz\",\n \"colors.red\": \"rot\",\n \"colors.green\": \"grün\",\n \"colors.blue\": \"blau\",\n \"colors.yellow\": \"gelb\",\n \"subtitle.example\": \"Beispiel Untertitel\",\n \"subtitle.select\": \"Untertitel auswählen\",\n \"playingOn\": \"Spielt auf <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Verbindung mit <strong>{castDeviceName}</strong> wird hergestellt...\",\n \"watermarkLink\": \"Link zum Homepage\",\n \"controlBar\": \"Videoplayer Kontrollen\",\n \"player\": \"Video player\",\n \"seekBar\": \"Video-Timeline\",\n \"seekBar.value\": \"Wert\",\n \"seekBar.timeshift\": \"Timeshift\",\n \"seekBar.durationText\": \"aus\",\n \"quickseek.forward\": \"Vor\",\n \"quickseek.rewind\": \"Zurück\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\":\"Eco Mode\"\n}\n","module.exports={\n \"settings.video.quality\": \"Video Quality\",\n \"settings.audio.quality\": \"Audio Quality\",\n \"settings.audio.track\": \"Audio Track\",\n \"settings.audio.mute\" : \"Mute\",\n \"settings.audio.volume\" : \"Volume\",\n \"settings.subtitles.window.color\" : \"Window color\",\n \"settings.subtitles.window.opacity\" : \"Window opacity\",\n \"settings.subtitles\" : \"Subtitles\",\n \"settings.subtitles.font.color\" : \"Font color\",\n \"settings.subtitles.font.opacity\" : \"Font opacity\",\n \"settings.subtitles.background.color\" : \"Background color\",\n \"settings.subtitles.background.opacity\": \"Background opacity\",\n \"colors.white\": \"white\",\n \"colors.black\": \"black\",\n \"colors.red\": \"red\",\n \"colors.green\": \"green\",\n \"colors.blue\": \"blue\",\n \"colors.cyan\": \"cyan\",\n \"colors.yellow\": \"yellow\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"Font size\",\n \"settings.subtitles.characterEdge\": \"Character edge\",\n \"settings.subtitles.characterEdge.raised\": \"raised\",\n \"settings.subtitles.characterEdge.depressed\": \"depressed\",\n \"settings.subtitles.characterEdge.uniform\": \"uniform\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"drop shadowed\",\n \"settings.subtitles.font.family\": \"Font family\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospaced serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportional serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospaced sans serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportional sans serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursive\",\n \"settings.subtitles.font.family.smallcapital\": \"small capital\",\n \"settings.time.hours\": \"Hours\",\n \"settings.time.minutes\": \"Minutes\",\n \"settings.time.seconds\": \"Seconds\",\n \"ads.remainingTime\": \"This ad will end in {remainingTime} seconds.\",\n \"settings\": \"Settings\",\n \"fullscreen\" : \"Fullscreen\",\n \"speed\": \"Speed\",\n \"playPause\" : \"Play/Pause\",\n \"play\": \"Play\",\n \"pause\": \"Pause\",\n \"open\": \"open\",\n \"close\": \"Close\",\n \"pictureInPicture\": \"Picture-in-Picture\",\n \"appleAirplay\" : \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\" : \"VR\",\n \"off\": \"off\",\n \"auto\": \"auto\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\":\"Eco Mode\",\n \"back\" : \"Back\",\n \"reset\": \"Reset\",\n \"replay\": \"Replay\",\n \"normal\": \"normal\",\n \"default\": \"default\",\n \"live\": \"Live\",\n \"subtitle.example\": \"example subtitle\",\n \"subtitle.select\": \"Select subtitle\",\n \"playingOn\": \"Playing on <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Connecting to <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Link to Homepage\",\n \"controlBar\": \"Video player controls\",\n \"player\": \"Video player\",\n \"seekBar\": \"Video timeline\",\n \"seekBar.value\": \"Value\",\n \"seekBar.timeshift\": \"Timeshift\",\n \"seekBar.durationText\": \"out of\",\n \"quickseek.forward\": \"Fast Forward\",\n \"quickseek.rewind\": \"Rewind\"\n}\n","module.exports={\n \"settings.video.quality\": \"Calidad de Video\",\n \"settings.audio.quality\": \"Calidad de Audio\",\n \"settings.audio.track\": \"Pista de Audio\",\n \"settings.audio.mute\" : \"Silencio\",\n \"settings.audio.volume\" : \"Volumen\",\n \"settings.subtitles.window.color\" : \"color de Ventana\",\n \"settings.subtitles.window.opacity\" : \"opacidad de Ventana\",\n \"settings.subtitles\" : \"Subtítulos\",\n \"settings.subtitles.font.color\" : \"color de Fuente\",\n \"settings.subtitles.font.opacity\" : \"opacidad de Fuente\",\n \"settings.subtitles.background.color\" : \"color de Fondo\",\n \"settings.subtitles.background.opacity\": \"opacidad de Fondo\",\n \"colors.white\": \"blanco\",\n \"colors.black\": \"negro\",\n \"colors.red\": \"rojo\",\n \"colors.green\": \"verde\",\n \"colors.blue\": \"azul\",\n \"colors.cyan\": \"cian\",\n \"colors.yellow\": \"amarillo\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"tamaño de Fuente\",\n \"settings.subtitles.characterEdge\": \"borde del Caracter\",\n \"settings.subtitles.characterEdge.raised\": \"alzado\",\n \"settings.subtitles.characterEdge.depressed\": \"discreto\",\n \"settings.subtitles.characterEdge.uniform\": \"uniforme\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"sombreado\",\n \"settings.subtitles.font.family\": \"tipo de Fuente\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospaced serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportional serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospaced sans serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportional sans serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursiva\",\n \"settings.subtitles.font.family.smallcapital\": \"small capital\",\n \"settings.time.hours\": \"Horas\",\n \"settings.time.minutes\": \"Minutos\",\n \"settings.time.seconds\": \"Segundos\",\n \"ads.remainingTime\": \"Este anuncio acabará en {remainingTime} segundos.\",\n \"settings\": \"Configuración\",\n \"fullscreen\" : \"Pantalla Completa\",\n \"speed\": \"Velocidad\",\n \"playPause\" : \"Reproducir/Pausa\",\n \"play\": \"Reproducir\",\n \"pause\": \"Pausa\",\n \"open\": \"Abrir\",\n \"close\": \"Cerrar\",\n \"pictureInPicture\": \"Imagen en Imagen\",\n \"appleAirplay\" : \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\" : \"VR\",\n \"off\": \"off\",\n \"auto\": \"auto\",\n \"ecoMode\": \"ecoMode\",\n \"ecoMode.title\": \"Eco Mode\",\n \"back\" : \"Atrás\",\n \"reset\": \"Reiniciar\",\n \"replay\": \"Rebobinar\",\n \"normal\": \"normal\",\n \"default\": \"predeterminado\",\n \"live\": \"Directo\",\n \"subtitle.example\": \"Ejemplo de Subtítulo\",\n \"subtitle.select\": \"Seleccionar subtítulo\",\n \"playingOn\": \"Reproduciendo en <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Conectando a <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Enlace al inicio\",\n \"controlBar\": \"Controles del Reproductor\",\n \"player\": \"Reproductor de Video\",\n \"seekBar\": \"Línea de Tiempo\",\n \"seekBar.value\": \"posición\",\n \"seekBar.timeshift\": \"cambio de posición\",\n \"seekBar.durationText\": \"de\",\n \"quickseek.forward\": \"Adelantar\",\n \"quickseek.rewind\": \"Rebobinar\"\n}","module.exports={\n \"settings.video.quality\": \"Videokwaliteit\",\n \"settings.audio.quality\": \"Audiokwaliteit\",\n \"settings.audio.track\": \"Audiospoor\",\n \"settings.audio.mute\": \"Dempen\",\n \"settings.audio.volume\": \"Volume\",\n \"settings.subtitles.window.color\": \"Vensterkleur\",\n \"settings.subtitles.window.opacity\": \"Venster doorzichtigheid\",\n \"settings.subtitles\": \"Ondertiteling\",\n \"settings.subtitles.font.color\": \"Lettertype kleur\",\n \"settings.subtitles.font.opacity\": \"Lettertype doorzichtigheid\",\n \"settings.subtitles.background.color\": \"Achtergrondkleur\",\n \"settings.subtitles.background.opacity\": \"Achtergrond doorzichtigheid\",\n \"colors.white\": \"wit\",\n \"colors.black\": \"zwart\",\n \"colors.red\": \"rood\",\n \"colors.green\": \"groen\",\n \"colors.blue\": \"blauw\",\n \"colors.cyan\": \"cyaan\",\n \"colors.yellow\": \"geel\",\n \"colors.magenta\": \"magenta\",\n \"percent\": \"{value}%\",\n \"settings.subtitles.font.size\": \"Lettertype grootte\",\n \"settings.subtitles.characterEdge\": \"Lettertype rand\",\n \"settings.subtitles.characterEdge.raised\": \"verhoogd\",\n \"settings.subtitles.characterEdge.depressed\": \"verlaagd\",\n \"settings.subtitles.characterEdge.uniform\": \"uniform\",\n \"settings.subtitles.characterEdge.dropshadowed\": \"schaduw\",\n \"settings.subtitles.font.family\": \"Standaard lettertype\",\n \"settings.subtitles.font.family.monospacedserif\": \"monospace serif\",\n \"settings.subtitles.font.family.proportionalserif\": \"proportioneel serif\",\n \"settings.subtitles.font.family.monospacedsansserif\": \"monospace sans-serif\",\n \"settings.subtitles.font.family.proportionalsansserif\": \"proportioneel sans-serif\",\n \"settings.subtitles.font.family.casual\": \"casual\",\n \"settings.subtitles.font.family.cursive\": \"cursief\",\n \"settings.subtitles.font.family.smallcapital\": \"kleine hoofdletters\",\n \"settings.time.hours\": \"Uren\",\n \"settings.time.minutes\": \"Minuten\",\n \"settings.time.seconds\": \"Seconden\",\n \"ads.remainingTime\": \"Deze advertentie eindigt in {remainingTime} seconden.\",\n \"settings\": \"Instellingen\",\n \"fullscreen\": \"Volledig scherm\",\n \"speed\": \"Snelheid\",\n \"playPause\": \"Afspelen/Pauzeren\",\n \"play\": \"Afspelen\",\n \"pause\": \"Pauzeren\",\n \"open\": \"Openen\",\n \"close\": \"Sluiten\",\n \"pictureInPicture\": \"Picture-in-Picture\",\n \"appleAirplay\": \"Apple AirPlay\",\n \"googleCast\": \"Google Cast\",\n \"vr\": \"VR\",\n \"off\": \"uit\",\n \"auto\": \"automatisch\",\n \"ecoMode\": \"Eco-modus\",\n \"ecoMode.title\": \"Eco-modus\",\n \"back\": \"Terug\",\n \"reset\": \"Reset\",\n \"replay\": \"Opnieuw afspelen\",\n \"normal\": \"normaal\",\n \"default\": \"standaard\",\n \"live\": \"Live\",\n \"subtitle.example\": \"voorbeeld ondertiteling\",\n \"subtitle.select\": \"Selecteer ondertiteling\",\n \"playingOn\": \"Speelt af op <strong>{castDeviceName}</strong>\",\n \"connectingTo\": \"Verbinden met <strong>{castDeviceName}</strong>...\",\n \"watermarkLink\": \"Link naar homepage\",\n \"controlBar\": \"Videospeler bediening\",\n \"player\": \"Videospeler\",\n \"seekBar\": \"Video tijdlijn\",\n \"seekBar.value\": \"Waarde\",\n \"seekBar.timeshift\": \"Tijdverschuiving\",\n \"seekBar.durationText\": \"van\",\n \"quickseek.forward\": \"Vooruitspoelen\",\n \"quickseek.rewind\": \"Terugspoelen\"\n}","export const version: string = '{{VERSION}}';\n// Management\nexport * from './uimanager';\nexport * from './uiconfig';\n// Factories\nexport { UIFactory } from './uifactory';\nexport { DemoFactory } from './demofactory';\n// Utils\nexport { ArrayUtils } from './arrayutils';\nexport { StringUtils } from './stringutils';\nexport { PlayerUtils } from './playerutils';\nexport { UIUtils } from './uiutils';\nexport { BrowserUtils } from './browserutils';\nexport { StorageUtils } from './storageutils';\nexport { ErrorUtils } from './errorutils';\n// Localization\nexport { i18n, I18n, Vocabulary, Vocabularies, CustomVocabulary, LocalizableText, Localizer } from './localization/i18n';\n// Spatial Navigation\nexport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nexport { NavigationGroup } from './spatialnavigation/navigationgroup';\nexport { RootNavigationGroup } from './spatialnavigation/rootnavigationgroup';\nexport { ListNavigationGroup, ListOrientation } from './spatialnavigation/ListNavigationGroup';\n// Components\nexport { Button, ButtonConfig } from './components/button';\nexport { ControlBar, ControlBarConfig } from './components/controlbar';\nexport { FullscreenToggleButton } from './components/fullscreentogglebutton';\nexport { HugePlaybackToggleButton } from './components/hugeplaybacktogglebutton';\nexport { PlaybackTimeLabel, PlaybackTimeLabelConfig, PlaybackTimeLabelMode } from './components/playbacktimelabel';\nexport { PlaybackToggleButton, PlaybackToggleButtonConfig } from './components/playbacktogglebutton';\nexport { SeekBar, SeekBarConfig, SeekPreviewEventArgs, SeekBarMarker } from './components/seekbar';\nexport { SelectBox } from './components/selectbox';\nexport { ItemSelectionList } from './components/itemselectionlist';\nexport { SettingsPanel, SettingsPanelConfig } from './components/settingspanel';\nexport { SettingsToggleButton, SettingsToggleButtonConfig } from './components/settingstogglebutton';\nexport { ToggleButton, ToggleButtonConfig } from './components/togglebutton';\nexport { VideoQualitySelectBox } from './components/videoqualityselectbox';\nexport { VolumeToggleButton } from './components/volumetogglebutton';\nexport { VRToggleButton } from './components/vrtogglebutton';\nexport { Watermark, WatermarkConfig } from './components/watermark';\nexport { UIContainer, UIContainerConfig } from './components/uicontainer';\nexport { Container, ContainerConfig } from './components/container';\nexport { Label, LabelConfig } from './components/label';\nexport { AudioQualitySelectBox } from './components/audioqualityselectbox';\nexport { AudioTrackSelectBox } from './components/audiotrackselectbox';\nexport { CastStatusOverlay } from './components/caststatusoverlay';\nexport { CastToggleButton } from './components/casttogglebutton';\nexport { Component, ComponentConfig, ComponentHoverChangedEventArgs } from './components/component';\nexport { ErrorMessageOverlay, ErrorMessageOverlayConfig, ErrorMessageTranslator, ErrorMessageMap } from './components/errormessageoverlay';\nexport { RecommendationOverlay } from './components/recommendationoverlay';\nexport { SeekBarLabel, SeekBarLabelConfig } from './components/seekbarlabel';\nexport { SubtitleOverlay } from './components/subtitleoverlay';\nexport { SubtitleSelectBox } from './components/subtitleselectbox';\nexport { TitleBar, TitleBarConfig } from './components/titlebar';\nexport { VolumeControlButton, VolumeControlButtonConfig } from './components/volumecontrolbutton';\nexport { ClickOverlay, ClickOverlayConfig } from './components/clickoverlay';\nexport { AdSkipButton, AdSkipButtonConfig } from './components/adskipbutton';\nexport { AdMessageLabel } from './components/admessagelabel';\nexport { AdClickOverlay } from './components/adclickoverlay';\nexport { PlaybackSpeedSelectBox } from './components/playbackspeedselectbox';\nexport { HugeReplayButton } from './components/hugereplaybutton';\nexport { BufferingOverlay, BufferingOverlayConfig } from './components/bufferingoverlay';\nexport { CastUIContainer } from './components/castuicontainer';\nexport { PlaybackToggleOverlay, PlaybackToggleOverlayConfig } from './components/playbacktoggleoverlay';\nexport { CloseButton, CloseButtonConfig } from './components/closebutton';\nexport { MetadataLabel, MetadataLabelContent, MetadataLabelConfig } from './components/metadatalabel';\nexport { AirPlayToggleButton } from './components/airplaytogglebutton';\nexport { VolumeSlider, VolumeSliderConfig } from './components/volumeslider';\nexport { PictureInPictureToggleButton } from './components/pictureinpicturetogglebutton';\nexport { Spacer } from './components/spacer';\nexport { BackgroundColorSelectBox } from './components/subtitlesettings/backgroundcolorselectbox';\nexport { BackgroundOpacitySelectBox } from './components/subtitlesettings/backgroundopacityselectbox';\nexport { CharacterEdgeSelectBox } from './components/subtitlesettings/characteredgeselectbox';\nexport { FontColorSelectBox } from './components/subtitlesettings/fontcolorselectbox';\nexport { FontFamilySelectBox } from './components/subtitlesettings/fontfamilyselectbox';\nexport { FontOpacitySelectBox } from './components/subtitlesettings/fontopacityselectbox';\nexport { FontSizeSelectBox } from './components/subtitlesettings/fontsizeselectbox';\nexport { SubtitleSettingSelectBox } from './components/subtitlesettings/subtitlesettingselectbox';\nexport { SubtitleSettingsLabel } from './components/subtitlesettings/subtitlesettingslabel';\nexport { WindowColorSelectBox } from './components/subtitlesettings/windowcolorselectbox';\nexport { WindowOpacitySelectBox } from './components/subtitlesettings/windowopacityselectbox';\nexport { SubtitleSettingsResetButton } from './components/subtitlesettings/subtitlesettingsresetbutton';\nexport { ListBox } from './components/listbox';\nexport { SubtitleListBox } from './components/subtitlelistbox';\nexport { AudioTrackListBox } from './components/audiotracklistbox';\nexport { SettingsPanelPage } from './components/settingspanelpage';\nexport { SettingsPanelPageBackButton } from './components/settingspanelpagebackbutton';\nexport { SettingsPanelPageOpenButton } from './components/settingspanelpageopenbutton';\nexport { SubtitleSettingsPanelPage, SubtitleSettingsPanelPageConfig } from './components/subtitlesettings/subtitlesettingspanelpage';\nexport { SettingsPanelItem } from './components/settingspanelitem';\nexport { ReplayButton } from './components/replaybutton';\nexport { QuickSeekButton, QuickSeekButtonConfig } from './components/quickseekbutton';\nexport { ListSelector, ListSelectorConfig, ListItem, ListItemFilter, ListItemLabelTranslator } from './components/listselector';\n\n// Object.assign polyfill for ES5/IE9\n// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\nif (typeof Object.assign !== 'function') {\n Object.assign = function(target: any) {\n 'use strict';\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n target = Object(target);\n for (let index = 1; index < arguments.length; index++) {\n let source = arguments[index];\n if (source != null) {\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n }\n return target;\n };\n}\n","import { PlayerAPI, PlayerEvent, PlayerEventBase, PlayerEventCallback } from 'bitmovin-player';\nimport { WrappedPlayer } from './uimanager';\n\nexport enum MobileV3PlayerEvent {\n SourceError = 'sourceerror',\n PlayerError = 'playererror',\n PlaylistTransition = 'playlisttransition',\n}\n\nexport interface MobileV3PlayerErrorEvent extends PlayerEventBase {\n code: number;\n message: string;\n}\n\nexport interface MobileV3SourceErrorEvent extends PlayerEventBase {\n code: number;\n message: string;\n}\n\nexport type MobileV3PlayerEventType = PlayerEvent | MobileV3PlayerEvent;\n\nexport interface MobileV3PlayerAPI extends PlayerAPI {\n on(eventType: MobileV3PlayerEventType, callback: PlayerEventCallback): void;\n exports: PlayerAPI['exports'] & { PlayerEvent: MobileV3PlayerEventType };\n}\n\nexport function isMobileV3PlayerAPI(player: WrappedPlayer | PlayerAPI | MobileV3PlayerAPI): player is MobileV3PlayerAPI {\n for (const key in MobileV3PlayerEvent) {\n if (MobileV3PlayerEvent.hasOwnProperty(key) && !player.exports.PlayerEvent.hasOwnProperty(key)) {\n return false;\n }\n }\n\n return true;\n}\n","import {Event, EventDispatcher, NoArgs} from './eventdispatcher';\nimport {BrowserUtils} from './browserutils';\nimport { UIInstanceManager } from './uimanager';\nimport { PlayerAPI, TimeRange } from 'bitmovin-player';\n\n/**\n * @category Utils\n */\nexport namespace PlayerUtils {\n\n export enum PlayerState {\n Idle,\n Prepared,\n Playing,\n Paused,\n Finished,\n }\n\n export function isTimeShiftAvailable(player: PlayerAPI): boolean {\n return player.isLive() && player.getMaxTimeShift() !== 0;\n }\n\n export function getState(player: PlayerAPI): PlayerState {\n if (player.hasEnded()) {\n return PlayerState.Finished;\n } else if (player.isPlaying()) {\n return PlayerState.Playing;\n } else if (player.isPaused()) {\n return PlayerState.Paused;\n } else if (player.getSource() != null) {\n return PlayerState.Prepared;\n } else {\n return PlayerState.Idle;\n }\n }\n\n /**\n * Returns the currentTime - seekableRange.start. This ensures a user-friendly currentTime after a live stream\n * transitioned to VoD.\n * @param player\n */\n export function getCurrentTimeRelativeToSeekableRange(player: PlayerAPI): number {\n const currentTime = player.getCurrentTime();\n if (player.isLive()) {\n return currentTime;\n }\n\n const seekableRangeStart = PlayerUtils.getSeekableRangeStart(player, 0);\n return currentTime - seekableRangeStart;\n }\n\n /**\n * Returns the start value of the seekable range or the defaultValue if no seekableRange is present.\n * For now this happens only in combination with Mobile SDKs.\n *\n * TODO: remove this function in next major release\n *\n * @param player\n * @param defaultValue\n */\n export function getSeekableRangeStart(player: PlayerAPI, defaultValue: number = 0) {\n return player.getSeekableRange() && player.getSeekableRange().start || defaultValue;\n }\n\n /**\n * Calculates player seekable time range for live.\n * As the player returns `{ start: -1, end: -1 }` for live streams we need to calculate the `seekableRange` based on `maxTimeshift`.\n *\n * @param player\n */\n export function getSeekableRangeRespectingLive(player: PlayerAPI): TimeRange {\n if (!player.isLive()) {\n return player.getSeekableRange();\n }\n\n const currentTimeshift = -player.getTimeShift();\n const maxTimeshift = -player.getMaxTimeShift();\n const currentTime = player.getCurrentTime();\n\n const end = currentTime + (currentTimeshift);\n const start = currentTime - (maxTimeshift - currentTimeshift);\n\n return { start, end };\n }\n\n export interface TimeShiftAvailabilityChangedArgs extends NoArgs {\n timeShiftAvailable: boolean;\n }\n\n export class TimeShiftAvailabilityDetector {\n\n private player: PlayerAPI;\n private timeShiftAvailable: boolean;\n private timeShiftAvailabilityChangedEvent = new EventDispatcher<PlayerAPI, TimeShiftAvailabilityChangedArgs>();\n\n constructor(player: PlayerAPI) {\n this.player = player;\n this.timeShiftAvailable = undefined;\n\n let timeShiftDetector = () => {\n this.detect();\n };\n // Try to detect timeshift availability when source is loaded, which works for DASH streams\n player.on(player.exports.PlayerEvent.SourceLoaded, timeShiftDetector);\n // With HLS/NativePlayer streams, getMaxTimeShift can be 0 before the buffer fills, so we need to additionally\n // check timeshift availability in TimeChanged\n player.on(player.exports.PlayerEvent.TimeChanged, timeShiftDetector);\n }\n\n detect(): void {\n if (this.player.isLive()) {\n let timeShiftAvailableNow = PlayerUtils.isTimeShiftAvailable(this.player);\n\n // When the availability changes, we fire the event\n if (timeShiftAvailableNow !== this.timeShiftAvailable) {\n this.timeShiftAvailabilityChangedEvent.dispatch(this.player, { timeShiftAvailable: timeShiftAvailableNow });\n this.timeShiftAvailable = timeShiftAvailableNow;\n }\n }\n }\n\n get onTimeShiftAvailabilityChanged(): Event<PlayerAPI, TimeShiftAvailabilityChangedArgs> {\n return this.timeShiftAvailabilityChangedEvent.getEvent();\n }\n }\n\n export interface LiveStreamDetectorEventArgs extends NoArgs {\n live: boolean;\n }\n\n /**\n * Detects changes of the stream type, i.e. changes of the return value of the player#isLive method.\n * Normally, a stream cannot change its type during playback, it's either VOD or live. Due to bugs on some\n * platforms or browsers, it can still change. It is therefore unreliable to just check #isLive and this detector\n * should be used as a workaround instead.\n *\n * Additionally starting with player v8.19.0 we have the use-case that a live stream changes into a vod.\n * The DurationChanged event indicates this switch.\n *\n * Known cases:\n *\n * - HLS VOD on Android 4.3\n * Video duration is initially 'Infinity' and only gets available after playback starts, so streams are wrongly\n * reported as 'live' before playback (the live-check in the player checks for infinite duration).\n *\n * @deprecated since UI v3.9.0 in combination with player v8.19.0 use PlayerEvent.DurationChanged instead\n *\n * TODO: remove this class in next major release\n */\n export class LiveStreamDetector {\n\n private player: PlayerAPI;\n private live: boolean;\n private liveChangedEvent = new EventDispatcher<PlayerAPI, LiveStreamDetectorEventArgs>();\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, uimanager: UIInstanceManager) {\n this.player = player;\n this.uimanager = uimanager;\n this.live = undefined;\n\n let liveDetector = () => {\n this.detect();\n };\n this.uimanager.getConfig().events.onUpdated.subscribe(liveDetector);\n // Re-evaluate when playback starts\n player.on(player.exports.PlayerEvent.Play, liveDetector);\n\n // HLS live detection workaround for Android:\n // Also re-evaluate during playback, because that is when the live flag might change.\n // (Doing it only in Android Chrome saves unnecessary overhead on other platforms)\n if (BrowserUtils.isAndroid && BrowserUtils.isChrome) {\n player.on(player.exports.PlayerEvent.TimeChanged, liveDetector);\n }\n\n // DurationChanged event was introduced with player v8.19.0\n if (player.exports.PlayerEvent.DurationChanged) {\n player.on(player.exports.PlayerEvent.DurationChanged, liveDetector);\n }\n\n // Ad video's isLive() might be different than the actual video's isLive().\n player.on(player.exports.PlayerEvent.AdBreakStarted, liveDetector);\n player.on(player.exports.PlayerEvent.AdBreakFinished, liveDetector);\n }\n\n detect(): void {\n let liveNow = this.player.isLive();\n\n // Compare current to previous live state flag and fire event when it changes. Since we initialize the flag\n // with undefined, there is always at least an initial event fired that tells listeners the live state.\n if (liveNow !== this.live) {\n this.liveChangedEvent.dispatch(this.player, { live: liveNow });\n this.live = liveNow;\n }\n }\n\n get onLiveChanged(): Event<PlayerAPI, LiveStreamDetectorEventArgs> {\n return this.liveChangedEvent.getEvent();\n }\n }\n\n export function clampValueToRange(value: number, boundary1: number, boundary2: number): number {\n const lowerBoundary = Math.min(boundary1, boundary2);\n const upperBoundary = Math.max(boundary1, boundary2);\n return Math.min(Math.max(value, lowerBoundary), upperBoundary);\n }\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { Action, Direction } from './types';\nimport { Container } from '../components/container';\nimport { Component } from '../components/component';\n\nexport enum ListOrientation {\n Horizontal = 'horizontal',\n Vertical = 'vertical',\n}\n\n/**\n * @category Components\n */\nexport class ListNavigationGroup extends NavigationGroup {\n private readonly listNavigationDirections: Direction[];\n\n constructor(orientation: ListOrientation, container: Container<unknown>, ...components: Component<unknown>[]) {\n super(container, ...components);\n\n switch (orientation) {\n case ListOrientation.Vertical:\n this.listNavigationDirections = [Direction.UP, Direction.DOWN];\n break;\n\n case ListOrientation.Horizontal:\n this.listNavigationDirections = [Direction.LEFT, Direction.RIGHT];\n break;\n }\n }\n\n public handleAction(action: Action): void {\n super.handleAction(action);\n\n if (action === Action.SELECT) {\n // close the container when a list entry is selected\n this.handleAction(Action.BACK);\n }\n }\n\n public handleNavigation(direction: Direction): void {\n super.handleNavigation(direction);\n\n if (!this.listNavigationDirections.includes(direction)) {\n // close the container on navigation inputs that don't align\n // with the orientation of the list\n this.handleAction(Action.BACK);\n }\n }\n}\n","import { Component } from '../components/component';\nimport { Container } from '../components/container';\nimport { isComponent, isContainer, isListBox } from './typeguards';\n\n/**\n * Recursively resolves a container and the components contained within them, building a flat list of components.\n *\n * @param container The container to get the contained components from\n */\nfunction resolveAllComponents(container: Container<unknown>): Component<unknown>[] {\n const childComponents: Component<unknown>[] = [];\n\n container.getComponents().forEach(containerOrComponent => {\n if (isContainer(containerOrComponent)) {\n childComponents.push(...resolveAllComponents(containerOrComponent));\n } else if (isComponent(containerOrComponent)) {\n childComponents.push(containerOrComponent);\n }\n });\n\n return childComponents;\n}\n\n/**\n * Returns the HTML elements associated to the provided component.\n *\n * @param component The component to get the HTML elements from\n */\nfunction toHtmlElement(component: Component<unknown>): HTMLElement[] {\n if (isListBox(component)) {\n return [].slice.call(component.getDomElement().get()[0].children);\n } else {\n return component.getDomElement().get().slice(0, 1);\n }\n}\n\n/**\n * Takes the provided list of components and flat-maps them to a list of their respective HTML elements. In case a\n * provided component is a container, the children of that container will be resolved recursively. Ignores components\n * that are hidden.\n *\n * @param components The components to map to HTML elements\n */\nexport function getHtmlElementsFromComponents(components: Component<unknown>[]): HTMLElement[] {\n const htmlElements: HTMLElement[] = [];\n\n components\n .filter(component => !component.isHidden())\n .forEach(component => {\n const elementsToConsider = component instanceof Container ? resolveAllComponents(component) : [component];\n\n elementsToConsider.forEach(component => {\n htmlElements.push(...toHtmlElement(component));\n });\n });\n\n return htmlElements;\n}\n","import { Action, Direction, KeyMap } from './types';\nimport { BrowserUtils } from '../browserutils';\n\nconst TizenKeyMap = {\n isApplicable: () => BrowserUtils.isTizen,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 10009: Action.BACK,\n },\n};\n\nconst WebOsKeyMap = {\n isApplicable: () => BrowserUtils.isWebOs,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 461: Action.BACK,\n },\n};\n\nconst PlayStationKeyMap = {\n isApplicable: () => BrowserUtils.isPlayStation,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // Cross\n 13: Action.SELECT,\n // Circle\n 27: Action.BACK,\n },\n};\n\nconst AndroidKeyMap = {\n isApplicable: () => BrowserUtils.isAndroid,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // D-pad OK\n 13: Action.SELECT,\n // Back\n 27: Action.BACK,\n },\n};\n\nconst HisenseKeyMap = {\n isApplicable: () => BrowserUtils.isHisense,\n keyCodes: {\n // D-pad Up\n 38: Direction.UP,\n // D-pad Down\n 40: Direction.DOWN,\n // D-pad Left\n 37: Direction.LEFT,\n // D-pad Right\n 39: Direction.RIGHT,\n // OK\n 13: Action.SELECT,\n // Back\n 8: Action.BACK,\n },\n};\n\n// Default key map used on desktops\nconst DefaultKeyMap = {\n // Arrow Up\n 38: Direction.UP,\n // Arrow Down\n 40: Direction.DOWN,\n // Arrow Left\n 37: Direction.LEFT,\n // Arrow Right\n 39: Direction.RIGHT,\n // Enter\n 13: Action.SELECT,\n // Escape\n 27: Action.BACK,\n};\n\n/**\n * Returns the matching key map for the current platform.\n */\nexport function getKeyMapForPlatform(): KeyMap {\n const applicableKeyMap = [\n WebOsKeyMap,\n TizenKeyMap,\n PlayStationKeyMap,\n HisenseKeyMap,\n AndroidKeyMap,\n ].find(keyMap => keyMap.isApplicable());\n\n if (applicableKeyMap) {\n return applicableKeyMap.keyCodes;\n } else {\n return DefaultKeyMap;\n }\n}\n","import { Direction } from './types';\n\ninterface Vector {\n x: number;\n y: number;\n}\n\n/**\n * Calculates the length of a vector.\n *\n * @param vector The vector to calculate the length of\n */\nfunction length(vector: Vector): number {\n return Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));\n}\n\n/**\n * Normalizes the given vector.\n *\n * @param vector The vector to normalize\n */\nfunction normalize(vector: Vector): Vector {\n const len = length(vector);\n\n return {\n x: vector.x / len,\n y: vector.y / len,\n };\n}\n\n/**\n * Calculates the dot product between 2 vectors.\n *\n * @param a The first vector\n * @param b The second vector\n */\nfunction dotProduct(a: Vector, b: Vector): number {\n return a.x * b.x + a.y * b.y;\n}\n\n/**\n * Calculates the distance between the 2 points pointed to by the provided vectors.\n *\n * @param a The first vector\n * @param b The second vector\n */\nfunction distance(a: Vector, b: Vector): number {\n return length({\n x: b.x - a.x,\n y: b.y - a.y,\n });\n}\n\n/**\n * Returns a vector that corresponds to the center of the provided element.\n *\n * @param element The element to get the center of\n */\nfunction getElementVector(element: HTMLElement): Vector {\n const boundingRect = getBoundingRectFromElement(element);\n\n return {\n x: boundingRect.x + boundingRect.width / 2,\n y: boundingRect.y + boundingRect.height / 2,\n };\n}\n\n/**\n * Returns the angle in degrees between the unit vector pointing in the given {Direction} and the unit vector that\n * points from the current element to another element.\n *\n * @param a The vector of the current element\n * @param b The vector of the other element\n * @param direction The direction to move along\n */\nfunction calculateAngle(a: Vector, b: Vector, direction: Direction): number {\n const directionVector = {\n x: (direction === Direction.LEFT ? -1 : direction === Direction.RIGHT ? 1 : 0),\n y: (direction === Direction.UP ? -1 : direction === Direction.DOWN ? 1 : 0),\n };\n\n const elementVector = normalize({\n x: b.x - a.x,\n y: b.y - a.y,\n });\n\n const angleCos = dotProduct(directionVector, elementVector) / (length(directionVector) * length(elementVector));\n\n return Math.acos(angleCos) * 180 / Math.PI;\n}\n\n/**\n * Returns the closest element to the current element when trying to navigate in the provided direction. Returns\n * undefined, if there is not element in the given direction.\n *\n * @param activeElement The currently selected element\n * @param elements The list of all elements that can be navigated to\n * @param direction The direction in which to navigate\n */\nexport function getElementInDirection(\n activeElement: HTMLElement,\n elements: HTMLElement[],\n direction: Direction,\n): HTMLElement | undefined {\n if (!activeElement) return undefined;\n\n const cutoffAngle = 45;\n const activeElemVector = getElementVector(activeElement);\n\n return elements\n // don't take the current element into account\n .filter(elem => elem !== activeElement)\n // get the angle between, and distance to any other element from the current element\n .map(element => {\n const elementVector = getElementVector(element);\n const dist = distance(activeElemVector, elementVector);\n const angle = calculateAngle(activeElemVector, elementVector, direction);\n\n return { angle, dist, element };\n })\n // filter out any elements that don't align with the direction we're trying to move in\n .filter(({ angle }) => angle <= cutoffAngle)\n // sort the resulting elements based on their distance to the current element in ascending order\n .sort(({ angle: angleA, dist: distA }, { angle: angleB, dist: distB }) => (angleA - angleB) + (distA - distB))\n // return the element closest to the current element\n .shift()?.element;\n}\n\n/**\n * Returns DOMRect like object containing horizontal X and vertical Y coordinates from and HTMLElement.\n * Handles use-cases for getBoundingClientRect when the return type can be either\n * a ClientRect or DOMRect object type.\n *\n * @param element The currently selected element\n */\nexport function getBoundingRectFromElement(element: HTMLElement) {\n const boundingRect = element.getBoundingClientRect();\n\n if (typeof boundingRect.x !== 'number' && typeof boundingRect.y !== 'number') {\n boundingRect.x = boundingRect.left;\n boundingRect.y = boundingRect.top;\n }\n\n return boundingRect;\n}\n\n","import { Container } from '../components/container';\nimport { Component } from '../components/component';\nimport { getElementInDirection } from './navigationalgorithm';\nimport { getHtmlElementsFromComponents } from './gethtmlelementsfromcomponents';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { isSettingsPanel } from './typeguards';\nimport { Action, ActionCallback, Callback, Direction, NavigationCallback } from './types';\n\n/**\n * Used as part of spatial navigation. Groups together different components to which you can navigate to, in a single\n * navigation group.\n *\n * Responsible for finding elements in direction on navigation and for tracking active element inside the group.\n * Triggers blur and focus on element when active element is changed, as well as click on element on `Action.SELECT`.\n * Will call `hideUi()` on passed in container if `Action.BACK` is called.\n *\n * @category Components\n */\nexport class NavigationGroup {\n private activeElement?: HTMLElement;\n private activeElementBeforeDisable?: HTMLElement;\n private readonly components: Component<unknown>[];\n private removeElementHoverEventListeners = () => {};\n private readonly eventSubscriber: NodeEventSubscriber;\n\n constructor(public readonly container: Container<unknown>, ...components: Component<unknown>[]) {\n this.components = components;\n this.eventSubscriber = new NodeEventSubscriber();\n }\n\n /**\n * If overwritten, allows to implement custom navigation behavior. Per default, the internal handler will still be\n * executed. To prevent execution of the default navigation handler, call `preventDefault()`;\n *\n * @param direction {Direction} The direction to move along\n * @param target {HTMLElement} The target element for the event\n * @param preventDefault {() => void} A function that, when called, will prevent the execution of the default handler\n */\n public onNavigation?: NavigationCallback;\n\n /**\n * If overwritten, allows to implement custom action behavior. Per default, the internal handler will still be\n * executed. To prevent execution of the default action handler, call `preventDefault()`;\n *\n * @param action {Action} The action that was called\n * @param target {HTMLElement} The target element that action was called on\n * @param preventDefault {() => void} A function that, when called, will prevent the execution of the default handler\n */\n public onAction?: ActionCallback;\n\n /**\n * Returns the active HTMLElement.\n */\n public getActiveElement(): HTMLElement | undefined {\n return this.activeElement;\n }\n\n private focusElement(element: HTMLElement): void {\n this.blurActiveElement();\n this.activeElement = element;\n this.activeElement.focus();\n }\n\n private blurActiveElement(): void {\n this.activeElement?.blur();\n }\n\n private focusFirstElement(): void {\n const element = getHtmlElementsFromComponents(this.components)[0];\n if (element) {\n this.focusElement(element);\n }\n }\n\n protected defaultNavigationHandler(direction: Direction): void {\n const targetElement = getElementInDirection(\n this.activeElement,\n getHtmlElementsFromComponents(this.components),\n direction,\n );\n\n if (targetElement) {\n this.focusElement(targetElement);\n }\n }\n\n protected defaultActionHandler(action: Action): void {\n switch (action) {\n case(Action.SELECT):\n this.activeElement.click();\n break;\n case(Action.BACK):\n this.container.hide();\n break;\n }\n }\n\n private handleInput<T>(data: T, defaultHandler: (data: T) => void, userHandler?: Callback<T>): void {\n let handleDefault = true;\n const preventDefault = () => (handleDefault = false);\n\n userHandler?.(data, this.activeElement, preventDefault);\n\n if (handleDefault) {\n defaultHandler.call(this, data);\n }\n }\n\n /**\n * Handles a navigation event.\n *\n * @param direction The direction of the navigation event\n */\n public handleNavigation(direction: Direction): void {\n if (!this.activeElement) {\n // If we do not have an active element, the active element has been disabled by a mouseleave\n // event. We should continue the navigation at the exact place where we left off.\n if (this.activeElementBeforeDisable) {\n this.focusElement(this.activeElementBeforeDisable);\n } else {\n this.focusFirstElement();\n }\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.handleInput(direction, this.defaultNavigationHandler, this.onNavigation);\n }\n\n /**\n * Handles an action event.\n *\n * @param action The action of the event\n */\n public handleAction(action: Action): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.handleInput(action, this.defaultActionHandler, this.onAction);\n }\n\n /**\n * Disable navigation group\n *\n * Call blur on active element, set as undefined, and track it as element before disable.\n */\n public disable(): void {\n if (this.activeElement) {\n this.activeElementBeforeDisable = this.activeElement;\n this.blurActiveElement();\n this.activeElement = undefined;\n }\n }\n\n /**\n * Enable navigation group\n *\n * Sets active element to either element that was active before disable, or first element of tracked elements.\n * If it is settings panel, it will always focus first element in the list.\n */\n public enable(): void {\n if (this.activeElementBeforeDisable && !isSettingsPanel(this.container)) {\n this.focusElement(this.activeElementBeforeDisable);\n this.activeElementBeforeDisable = undefined;\n } else {\n this.focusFirstElement();\n }\n\n this.trackElementHover();\n }\n\n /**\n * Adds event listener for `mouseenter` on tracked elements to ensure tracking of active element will work together\n * in combination of using mouse and key events.\n */\n private trackElementHover(): void {\n this.removeElementHoverEventListeners();\n\n const removeEventListenerFunctions = getHtmlElementsFromComponents(this.components).map(htmlElem => {\n const enterListener = this.focusElement.bind(this, htmlElem);\n const exitListener = () => this.disable();\n\n this.eventSubscriber.on(htmlElem, 'mouseenter', enterListener);\n this.eventSubscriber.on(htmlElem, 'mouseleave', exitListener);\n\n return () => {\n this.eventSubscriber.off(htmlElem, 'mouseenter', enterListener);\n this.eventSubscriber.off(htmlElem, 'mouseleave', exitListener);\n };\n });\n\n this.removeElementHoverEventListeners = () => removeEventListenerFunctions.forEach(fn => fn());\n }\n\n /**\n * Dispose of navigation group\n */\n public release(): void {\n this.eventSubscriber.release();\n this.activeElement = undefined;\n this.components.splice(0, this.components.length);\n this.removeElementHoverEventListeners();\n }\n}\n","type Listeners = ([Node, EventListenerOrEventListenerObject, boolean | AddEventListenerOptions])[];\n\n/**\n * Allows to subscribe to Node events.\n */\nexport class NodeEventSubscriber {\n private readonly attachedListeners: Map<keyof HTMLElementEventMap, Listeners>;\n\n constructor() {\n this.attachedListeners = new Map();\n }\n\n private getEventListenersOfType(type: keyof HTMLElementEventMap): Listeners {\n if (!this.attachedListeners.has(type)) {\n this.attachedListeners.set(type, []);\n }\n\n return this.attachedListeners.get(type);\n }\n\n /**\n * Adds the given event listener to the node.\n *\n * @param node The node to remove the event listener from\n * @param type The event to listen to\n * @param listener The listener to remove\n * @param options The event listener options\n */\n public on(\n node: Node,\n type: keyof HTMLElementEventMap,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n node.addEventListener(type, listener, options);\n this.getEventListenersOfType(type).push([node, listener, options]);\n }\n\n /**\n * Removes the given event listener from the node.\n *\n * @param node The node to attach the event listener to\n * @param type The event to listen to\n * @param listener The listener to add\n * @param options The event listener options\n */\n public off(\n node: Node,\n type: keyof HTMLElementEventMap,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n const listenersOfType = this.getEventListenersOfType(type);\n const listenerIndex = listenersOfType.findIndex(([otherNode, otherListener, otherOptions]) => {\n return otherNode === node && otherListener === listener && otherOptions === options;\n });\n\n node.removeEventListener(type, listener, options);\n\n if (listenerIndex > -1) {\n listenersOfType.splice(listenerIndex, 1);\n }\n }\n\n /**\n * Removes all attached event listeners.\n */\n public release(): void {\n this.attachedListeners.forEach((listenersOfType, type) => {\n listenersOfType.forEach(([element, listener, options]) => {\n this.off(element, type, listener, options);\n });\n });\n this.attachedListeners.clear();\n }\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { Component } from '../components/component';\nimport { UIContainer } from '../components/uicontainer';\nimport { Action, Direction } from './types';\n\n/**\n * Extends NavigationGroup and provides additional logic for hiding and showing the UI on the root container.\n *\n * @category Components\n */\nexport class RootNavigationGroup extends NavigationGroup {\n constructor(public readonly container: UIContainer, ...elements: Component<unknown>[]) {\n super(container, ...elements);\n }\n\n public handleAction(action: Action) {\n this.container.showUi();\n\n super.handleAction(action);\n }\n\n public handleNavigation(direction: Direction) {\n this.container.showUi();\n\n super.handleNavigation(direction);\n }\n\n protected defaultActionHandler(action: Action): void {\n if (action === Action.BACK) {\n this.container.hideUi();\n } else {\n super.defaultActionHandler(action);\n }\n }\n\n public release(): void {\n super.release();\n }\n}\n","import { RootNavigationGroup } from './rootnavigationgroup';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { Action, Direction } from './types';\nimport {getBoundingRectFromElement} from './navigationalgorithm';\n\nconst DefaultScrubSpeedPercentage = 0.005;\nconst ScrubSpeedClearInterval = 100;\nconst ScrubSpeedMultiplier = 1.1;\n\n/**\n * Handles Spatial Navigation interaction with the seek bar. Ensures, that seek operations can be executed and that the\n * scrubbing tooltip is shown as if the user scrubbed using the mouse/touchscreen.\n */\nexport class SeekBarHandler {\n private readonly cursorPosition = { x: 0, y: 0};\n private readonly eventSubscriber: NodeEventSubscriber;\n private isScrubbing = false;\n private scrubSpeedResetTimeout: number;\n private scrubSpeedPercentage = DefaultScrubSpeedPercentage;\n\n constructor(private readonly rootNavigationGroup: RootNavigationGroup) {\n this.rootNavigationGroup.onAction = this.onAction;\n this.eventSubscriber = new NodeEventSubscriber();\n this.rootNavigationGroup.onNavigation = this.onNavigation;\n }\n\n private updateScrubSpeedPercentage(): void {\n clearTimeout(this.scrubSpeedResetTimeout);\n this.scrubSpeedPercentage *= ScrubSpeedMultiplier;\n this.scrubSpeedResetTimeout = window.setTimeout(\n () => this.scrubSpeedPercentage = DefaultScrubSpeedPercentage, ScrubSpeedClearInterval,\n );\n }\n\n private getIncrement(direction: Direction, seekBarWrapper: HTMLElement): number {\n this.updateScrubSpeedPercentage();\n\n const seekBarWidth = seekBarWrapper.getBoundingClientRect().width;\n const increment = seekBarWidth * this.scrubSpeedPercentage;\n\n return direction === Direction.RIGHT ? increment : -increment;\n }\n\n private resetCursorPosition(): void {\n this.cursorPosition.x = 0;\n this.cursorPosition.y = 0;\n }\n\n private updateCursorPosition(direction: Direction, seekBarWrapper: HTMLElement): void {\n this.cursorPosition.x += this.getIncrement(direction, seekBarWrapper);\n }\n\n private initializeCursorPosition(seekBarWrapper: HTMLElement): void {\n const playbackPositionMarker = getPlaybackPositionMarker(seekBarWrapper);\n const rect = getBoundingRectFromElement(playbackPositionMarker);\n\n\n const startX = rect.x + (rect.width / 2);\n const startY = rect.y;\n\n this.cursorPosition.x = startX;\n this.cursorPosition.y = startY;\n }\n\n private initializeOrUpdateCursorPosition(seekBarWrapper: HTMLElement, direction: Direction): void {\n if (this.isScrubbing) {\n this.updateCursorPosition(direction, seekBarWrapper);\n } else {\n this.initializeCursorPosition(seekBarWrapper);\n }\n\n this.isScrubbing = true;\n }\n\n private getCursorPositionMouseEventInit(): MouseEventInit {\n return {\n clientX: this.cursorPosition.x,\n clientY: this.cursorPosition.y,\n };\n }\n\n private dispatchMouseMoveEvent(seekBar: Element): void {\n seekBar.dispatchEvent(new MouseEvent('mousemove', this.getCursorPositionMouseEventInit()));\n }\n\n private readonly onNavigation = (direction: Direction, target: HTMLElement, preventDefault: () => void): void => {\n if (!isSeekBarWrapper(target)) {\n return;\n }\n\n if (direction === Direction.UP || direction === Direction.DOWN) {\n this.stopSeeking(getSeekBar(target));\n\n return;\n }\n\n this.initializeOrUpdateCursorPosition(target, direction);\n this.dispatchMouseMoveEvent(getSeekBar(target));\n\n preventDefault();\n };\n\n private dispatchMouseClickEvent(seekBar: Element): void {\n const mouseDownHandler = () => {\n const mouseEventInit = this.getCursorPositionMouseEventInit();\n\n document.dispatchEvent(new MouseEvent('mouseup', mouseEventInit));\n this.eventSubscriber.off(seekBar, 'mousedown', mouseDownHandler);\n this.stopSeeking(seekBar);\n };\n\n this.eventSubscriber.on(seekBar, 'mousedown', mouseDownHandler);\n seekBar.dispatchEvent(new MouseEvent('mousedown'));\n }\n\n private stopSeeking(seekBar: Element): void {\n this.resetCursorPosition();\n this.isScrubbing = false;\n this.dispatchMouseLeaveEvent(seekBar);\n }\n\n private dispatchMouseLeaveEvent(seekBar: Element): void {\n seekBar.dispatchEvent(new MouseEvent('mouseleave'));\n }\n\n private readonly onAction = (action: Action, target: HTMLElement, preventDefault: () => void): void => {\n if (!isSeekBarWrapper(target)) {\n return;\n }\n\n const seekBar = getSeekBar(target);\n\n if (action === Action.SELECT && this.isScrubbing) {\n this.dispatchMouseClickEvent(seekBar);\n preventDefault();\n } else if (action === Action.BACK) {\n this.stopSeeking(seekBar);\n preventDefault();\n }\n };\n\n /**\n * Releases the SeekBraHandler, making sure all event subscribers are removed.\n */\n public release(): void {\n this.eventSubscriber.release();\n this.rootNavigationGroup.onAction = undefined;\n this.rootNavigationGroup.onNavigation = undefined;\n }\n}\n\nfunction isSeekBarWrapper(element: HTMLElement): boolean {\n return Array.from(element.classList).findIndex(className => /-ui-seekbar$/.test(className)) > -1;\n}\n\nfunction getSeekBar(seekBarWrapper: HTMLElement): Element {\n return seekBarWrapper.children.item(0);\n}\n\nfunction getPlaybackPositionMarker(seekBarWrapper: HTMLElement): HTMLElement {\n return seekBarWrapper.querySelector('[class*=\"seekbar-playbackposition-marker\"]');\n}\n","import { NavigationGroup } from './navigationgroup';\nimport { RootNavigationGroup } from './rootnavigationgroup';\nimport { NodeEventSubscriber } from './nodeeventsubscriber';\nimport { SeekBarHandler } from './seekbarhandler';\nimport { getKeyMapForPlatform } from './keymap';\nimport { Action, Direction, KeyMap } from './types';\nimport { isAction, isDirection } from './typeguards';\n\n/**\n * SpatialNavigation keeps track of all navigation groups, and updates the active navigation group when visibility\n * changes on group container.\n *\n * It listens to key events, and triggers either handleNavigation or handleAction on the active group.\n * SeekBarHandler will get instantiated with root navigation group and disposed on release of the spatial navigation.\n */\nexport class SpatialNavigation {\n private unsubscribeVisibilityChangesFns: (() => void)[];\n private readonly navigationGroups: NavigationGroup[] = [];\n private readonly activeNavigationGroups: NavigationGroup[];\n private readonly eventSubscriber: NodeEventSubscriber;\n private readonly seekBarHandler: SeekBarHandler;\n private readonly keyMap: KeyMap;\n\n constructor(rootNavigationGroup: RootNavigationGroup, ...navigationGroups: NavigationGroup[]) {\n this.seekBarHandler = new SeekBarHandler(rootNavigationGroup);\n\n this.activeNavigationGroups = [];\n this.unsubscribeVisibilityChangesFns = [];\n this.eventSubscriber = new NodeEventSubscriber();\n this.navigationGroups = [rootNavigationGroup, ...navigationGroups];\n this.keyMap = getKeyMapForPlatform();\n\n this.subscribeToNavigationGroupVisibilityChanges();\n this.attachKeyEventHandler();\n this.enableDefaultNavigationGroup();\n }\n\n private attachKeyEventHandler(): void {\n this.eventSubscriber.on(document, 'keydown', this.handleKeyEvent, true);\n }\n\n private onShow = (group: NavigationGroup): void => {\n this.activeNavigationGroups.push(group);\n this.updateEnabledNavigationGroup();\n };\n\n private onHide = (group: NavigationGroup): void => {\n const groupIndex = this.activeNavigationGroups.findIndex(other => other === group);\n\n if (groupIndex > -1) {\n group.disable();\n this.activeNavigationGroups.splice(groupIndex, 1);\n this.updateEnabledNavigationGroup();\n }\n };\n\n /**\n * Subscribes to onHide and onShow on all navigation groups containers as Spatial navigation tracks active navigation\n * group based on their container visibility.\n */\n private subscribeToNavigationGroupVisibilityChanges(): void {\n this.navigationGroups.forEach(group => {\n const onShowHandler = () => this.onShow(group);\n const onHideHandler = () => this.onHide(group);\n\n group.container.onShow.subscribe(onShowHandler);\n group.container.onHide.subscribe(onHideHandler);\n\n this.unsubscribeVisibilityChangesFns.push(\n () => group.container.onShow.unsubscribe(onShowHandler),\n () => group.container.onHide.unsubscribe(onHideHandler),\n );\n });\n }\n\n private unsubscribeFromNavigationGroupVisibilityChanges(): void {\n this.unsubscribeVisibilityChangesFns.forEach(unsub => unsub());\n this.unsubscribeVisibilityChangesFns = [];\n }\n\n /**\n * It will enable group of which container is currently shown\n * If there are no groups with containers that are currently visible, it will enable root navigation group\n */\n private enableDefaultNavigationGroup(): void {\n const isShown = (group: NavigationGroup) => group.container.isShown();\n const groupToEnable = this.navigationGroups.find(isShown) ?? this.navigationGroups[0];\n\n if (groupToEnable) {\n this.activeNavigationGroups.push(groupToEnable);\n this.updateEnabledNavigationGroup();\n }\n }\n\n /**\n * Disables navigation groups that are no longer active and calls enable on last pushed navigation group\n */\n private updateEnabledNavigationGroup(): void {\n this.activeNavigationGroups.forEach((group, idx) => {\n if (idx < this.activeNavigationGroups.length - 1) {\n group.disable();\n } else {\n group.enable();\n }\n });\n }\n\n /**\n * Returns currently active navigation group\n */\n public getActiveNavigationGroup(): NavigationGroup | undefined {\n return this.activeNavigationGroups[this.activeNavigationGroups.length - 1];\n }\n\n /**\n * Checks if keyboard event keycode is tracked either as Direction or Action and calls appropriate handler on active\n * navigation group\n *\n * @param e {KeyboardEvent}\n */\n private handleKeyEvent = (e: KeyboardEvent): void => {\n const event: Direction | Action | undefined = this.keyMap[getKeyCode(e)];\n\n const active = this.getActiveNavigationGroup();\n if (!active || !active.container || active.container.isHidden() || active.container.isDisabled()) {\n return;\n }\n\n if (isDirection(event)) {\n active.handleNavigation(event);\n\n e.preventDefault();\n e.stopPropagation();\n }\n if (isAction(event)) {\n active.handleAction(event);\n\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n /**\n * Dispose of SpatialNavigation\n *\n * Remove all event handlers, release seekbar handler and release all navigation groups.\n */\n public release(): void {\n this.unsubscribeFromNavigationGroupVisibilityChanges();\n this.eventSubscriber.release();\n this.navigationGroups.forEach(group => group.release());\n this.seekBarHandler.release();\n }\n}\n\nfunction getKeyCode(event: KeyboardEvent): number {\n return event.keyCode;\n}\n","import { Component } from '../components/component';\nimport { SettingsPanel } from '../components/settingspanel';\nimport { Container } from '../components/container';\nimport { ListBox } from '../components/listbox';\nimport { Action, Direction } from './types';\n\nexport function isSettingsPanel(component: Component<unknown>): component is SettingsPanel {\n return component instanceof SettingsPanel;\n}\n\nexport function isComponent(obj: unknown): obj is Component<unknown> {\n return obj !== null && obj !== undefined && obj instanceof Component;\n}\n\nexport function isContainer(obj: unknown): obj is Container<unknown> {\n return obj !== null && obj !== undefined && obj instanceof Container;\n}\n\nexport function isListBox(obj: unknown): obj is ListBox {\n return obj instanceof ListBox;\n}\n\nexport function isDirection(direction: unknown): direction is Direction {\n return typeof direction === 'string' && Object.values<string>(Direction).includes(direction);\n}\n\nexport function isAction(action: unknown): action is Action {\n return typeof action === 'string' && Object.values<string>(Action).includes(action);\n}\n","export type Callback<T> = (data: T, target: HTMLElement, preventDefault: () => void) => void;\nexport type NavigationCallback = Callback<Direction>;\nexport type ActionCallback = Callback<Action>;\nexport type KeyMap = {\n [keyCode: number]: Action | Direction;\n};\n\nexport enum Direction {\n UP = 'up',\n DOWN = 'down',\n LEFT = 'left',\n RIGHT = 'right',\n}\n\nexport enum Action {\n SELECT = 'select',\n BACK = 'back',\n}\n","import { UIConfig } from './uiconfig';\n\n/**\n * @category Utils\n */\nexport namespace StorageUtils {\n let disableStorageApi: boolean;\n\n export function setStorageApiDisabled(uiConfig: UIConfig) {\n disableStorageApi = uiConfig.disableStorageApi;\n }\n\n function shouldUseLocalStorage(): boolean {\n try {\n return (\n !disableStorageApi &&\n window.localStorage &&\n typeof localStorage.getItem === 'function' &&\n typeof localStorage.setItem === 'function'\n );\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Stores a string item into localStorage.\n * @param key the item's key\n * @param data the item's data\n */\n export function setItem(key: string, data: string): void {\n if (shouldUseLocalStorage()) {\n try {\n window.localStorage.setItem(key, data);\n } catch (e) {\n console.debug(`Failed to set storage item ${key}`, e);\n }\n }\n }\n\n /**\n * Gets an item's string value from the localStorage.\n * @param key the key to look up its associated value\n * @return {string | null} Returns the string if found, null if there is no data stored for the key\n */\n export function getItem(key: string): string | null {\n if (shouldUseLocalStorage()) {\n try {\n return window.localStorage.getItem(key);\n } catch (e) {\n console.debug(`Failed to get storage item ${key}`, e);\n }\n }\n\n return null;\n }\n\n /**\n * Stores an object into localStorage. The object will be serialized to JSON. The following types are supported\n * in addition to the default types:\n * - ColorUtils.Color\n *\n * @param key the key to store the data to\n * @param data the object to store\n */\n export function setObject<T>(key: string, data: T): void {\n let json = JSON.stringify(data);\n setItem(key, json);\n }\n\n /**\n * Gets an object for the given key from localStorage. The object will be deserialized from JSON. Beside the\n * default types, the following types are supported:\n * - ColorUtils.Color\n *\n * @param key the key to look up its associated object\n * @return {any} Returns the object if found, null otherwise\n */\n export function getObject<T>(key: string): T | null {\n let json = getItem(key);\n\n if (json) {\n let object = JSON.parse(json);\n return <T>object;\n }\n return null;\n }\n}\n","import { Ad, LinearAd, PlayerAPI } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * @category Utils\n */\nexport namespace StringUtils {\n\n export let FORMAT_HHMMSS: string = 'hh:mm:ss';\n export let FORMAT_MMSS: string = 'mm:ss';\n\n /**\n * Formats a number of seconds into a time string with the pattern hh:mm:ss.\n *\n * @param totalSeconds the total number of seconds to format to string\n * @param format the time format to output (default: hh:mm:ss)\n * @returns {string} the formatted time string\n */\n export function secondsToTime(totalSeconds: number, format: string = FORMAT_HHMMSS): string {\n let isNegative = totalSeconds < 0;\n\n if (isNegative) {\n // If the time is negative, we make it positive for the calculation below\n // (else we'd get all negative numbers) and reattach the negative sign later.\n totalSeconds = -totalSeconds;\n }\n\n // Split into separate time parts\n let hours = Math.floor(totalSeconds / 3600);\n let minutes = Math.floor(totalSeconds / 60) - hours * 60;\n let seconds = Math.floor(totalSeconds) % 60;\n\n return (isNegative ? '-' : '') + format\n .replace('hh', leftPadWithZeros(hours, 2))\n .replace('mm', leftPadWithZeros(minutes, 2))\n .replace('ss', leftPadWithZeros(seconds, 2));\n }\n\n export function secondsToText(totalSeconds: number): string {\n const isNegative = totalSeconds < 0;\n\n if (isNegative) {\n // If the time is negative, we make it positive for the calculation below\n // (else we'd get all negative numbers) and reattach the negative sign later.\n totalSeconds = -totalSeconds;\n }\n\n // Split into separate time parts\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor(totalSeconds / 60) - hours * 60;\n const seconds = Math.floor(totalSeconds) % 60;\n\n return (isNegative ? '-' : '') +\n (hours !== 0 ? `${leftPadWithZeros(hours, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.hours'))} ` : '') +\n (minutes !== 0 ? `${leftPadWithZeros(minutes, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.minutes'))} ` : '') +\n `${leftPadWithZeros(seconds, 2)} ${i18n.performLocalization(i18n.getLocalizer('settings.time.seconds'))}`;\n }\n\n /**\n * Converts a number to a string and left-pads it with zeros to the specified length.\n * Example: leftPadWithZeros(123, 5) => '00123'\n *\n * @param num the number to convert to string and pad with zeros\n * @param length the desired length of the padded string\n * @returns {string} the padded number as string\n */\n function leftPadWithZeros(num: number | string, length: number): string {\n let text = num + '';\n let padding = '0000000000'.substr(0, length - text.length);\n return padding + text;\n }\n\n /**\n * Fills out placeholders in an ad message.\n *\n * Has the placeholders '{remainingTime[formatString]}', '{playedTime[formatString]}',\n * '{adDuration[formatString]}' and {adBreakRemainingTime[formatString]}, which are replaced by the remaining time until the ad can be skipped, the current\n * time or the ad duration. The format string is optional. If not specified, the placeholder is replaced by the time\n * in seconds. If specified, it must be of the following format:\n * - %d - Inserts the time as an integer.\n * - %0Nd - Inserts the time as an integer with leading zeroes, if the length of the time string is smaller than N.\n * - %f - Inserts the time as a float.\n * - %0Nf - Inserts the time as a float with leading zeroes.\n * - %.Mf - Inserts the time as a float with M decimal places. Can be combined with %0Nf, e.g. %04.2f (the time\n * 10.123 would be printed as 0010.12).\n * - %hh:mm:ss\n * - %mm:ss\n *\n * Examples:\n * - { text: 'Ad: {remainingTime%mm:ss} secs' }\n * An input value of 100 would be displayed as: 'Ad: 01:40 secs'\n * - { text: 'Ad: {remainingTime%f} secs' }\n * An input value of 100 would be displayed as: 'Ad: 100.0 secs'\n * - { text: 'Adbreak: {adBreakRemainingTime%f} secs' }\n * Adbreak with 2 ads each 50 seconds would be displayed as: 'Ad: 100.0 secs'\n *\n * @param adMessage an ad message with optional placeholders to fill\n * @param skipOffset if specified, {remainingTime} will be filled with the remaining time until the ad can be skipped\n * @param player the player to get the time data from\n * @returns {string} the ad message with filled placeholders\n */\n export function replaceAdMessagePlaceholders(adMessage: string, skipOffset: number, player: PlayerAPI) {\n let adMessagePlaceholderRegex = new RegExp(\n '\\\\{(remainingTime|playedTime|adDuration|adBreakRemainingTime)(}|%((0[1-9]\\\\d*(\\\\.\\\\d+(d|f)|d|f)|\\\\.\\\\d+f|d|f)|hh:mm:ss|mm:ss)})',\n 'g',\n );\n\n return adMessage.replace(adMessagePlaceholderRegex, (formatString) => {\n let time = 0;\n if (formatString.indexOf('remainingTime') > -1) {\n if (skipOffset) {\n time = Math.ceil(skipOffset - player.getCurrentTime());\n } else {\n time = player.getDuration() - player.getCurrentTime();\n }\n } else if (formatString.indexOf('playedTime') > -1) {\n time = player.getCurrentTime();\n } else if (formatString.indexOf('adDuration') > -1) {\n time = player.getDuration();\n } else if (formatString.indexOf('adBreakRemainingTime') > -1) { // To display the remaining time in the ad break as opposed to in the ad\n time = 0;\n\n // compute list of ads and calculate duration of remaining ads based on index of active ad\n if (player.ads.isLinearAdActive()) {\n const isActiveAd = (ad: Ad) => player.ads.getActiveAd().id === ad.id;\n const indexOfActiveAd = player.ads.getActiveAdBreak().ads.findIndex(isActiveAd);\n const duration = player.ads.getActiveAdBreak().ads\n .slice(indexOfActiveAd)\n .reduce((total, ad) => total + (ad.isLinear ? (ad as LinearAd).duration : 0), 0);\n\n // And remaning ads duration minus time played\n time = duration - player.getCurrentTime();\n }\n }\n\n return formatNumber(Math.round(time), formatString);\n });\n }\n\n function formatNumber(time: number, format: string) {\n let formatStringValidationRegex = /%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)/;\n let leadingZeroesRegex = /(%0[1-9]\\d*)(?=(\\.\\d+f|f|d))/;\n let decimalPlacesRegex = /\\.\\d*(?=f)/;\n\n if (!formatStringValidationRegex.test(format)) {\n // If the format is invalid, we set a default fallback format\n format = '%d';\n }\n\n // Determine the number of leading zeros\n let leadingZeroes = 0;\n let leadingZeroesMatches = format.match(leadingZeroesRegex);\n if (leadingZeroesMatches) {\n leadingZeroes = parseInt(leadingZeroesMatches[0].substring(2));\n }\n\n // Determine the number of decimal places\n let numDecimalPlaces = null;\n let decimalPlacesMatches = format.match(decimalPlacesRegex);\n if (decimalPlacesMatches && !isNaN(parseInt(decimalPlacesMatches[0].substring(1)))) {\n numDecimalPlaces = parseInt(decimalPlacesMatches[0].substring(1));\n if (numDecimalPlaces > 20) {\n numDecimalPlaces = 20;\n }\n }\n\n // Float format\n if (format.indexOf('f') > -1) {\n let timeString = '';\n\n if (numDecimalPlaces !== null) {\n // Apply fixed number of decimal places\n timeString = time.toFixed(numDecimalPlaces);\n } else {\n timeString = '' + time;\n }\n\n // Apply leading zeros\n if (timeString.indexOf('.') > -1) {\n return leftPadWithZeros(timeString, timeString.length + (leadingZeroes - timeString.indexOf('.')));\n } else {\n return leftPadWithZeros(timeString, leadingZeroes);\n }\n\n }\n // Time format\n else if (format.indexOf(':') > -1) {\n let totalSeconds = Math.ceil(time);\n\n // hh:mm:ss format\n if (format.indexOf('hh') > -1) {\n return secondsToTime(totalSeconds);\n }\n // mm:ss format\n else {\n let minutes = Math.floor(totalSeconds / 60);\n let seconds = totalSeconds % 60;\n\n return leftPadWithZeros(minutes, 2) + ':' + leftPadWithZeros(seconds, 2);\n }\n }\n // Integer format\n else {\n return leftPadWithZeros(Math.ceil(time), leadingZeroes);\n }\n }\n}\n","import { ListItem, ListSelector, ListSelectorConfig } from './components/listselector';\nimport { UIInstanceManager } from './uimanager';\nimport { PlayerAPI, SubtitleEvent, SubtitleTrack } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\n\n/**\n * Helper class to handle all subtitle related events\n *\n * This class listens to player events as well as the `ListSelector` event if selection changed\n *\n * @category Utils\n */\nexport class SubtitleSwitchHandler {\n\n private static SUBTITLES_OFF_KEY: string = 'null';\n\n private player: PlayerAPI;\n private listElement: ListSelector<ListSelectorConfig>;\n private uimanager: UIInstanceManager;\n\n constructor(player: PlayerAPI, element: ListSelector<ListSelectorConfig>, uimanager: UIInstanceManager) {\n this.player = player;\n this.listElement = element;\n this.uimanager = uimanager;\n\n this.bindSelectionEvent();\n this.bindPlayerEvents();\n this.refreshSubtitles();\n }\n\n private bindSelectionEvent(): void {\n this.listElement.onItemSelected.subscribe((_, value: string) => {\n // TODO add support for multiple concurrent subtitle selections\n if (value === SubtitleSwitchHandler.SUBTITLES_OFF_KEY) {\n const currentSubtitle = this.player.subtitles.list().filter((subtitle) => subtitle.enabled).pop();\n if (currentSubtitle) {\n this.player.subtitles.disable(currentSubtitle.id);\n }\n } else {\n this.player.subtitles.enable(value, true);\n }\n });\n }\n\n private bindPlayerEvents(): void {\n this.player.on(this.player.exports.PlayerEvent.SubtitleAdded, this.addSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleEnabled, this.selectCurrentSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleDisabled, this.selectCurrentSubtitle);\n this.player.on(this.player.exports.PlayerEvent.SubtitleRemoved, this.removeSubtitle);\n // Update subtitles when source goes away\n this.player.on(this.player.exports.PlayerEvent.SourceUnloaded, this.clearSubtitles);\n // Update subtitles when the period within a source changes\n this.player.on(this.player.exports.PlayerEvent.PeriodSwitched, this.refreshSubtitles);\n this.uimanager.getConfig().events.onUpdated.subscribe(this.refreshSubtitles);\n }\n\n private addSubtitle = (event: SubtitleEvent) => {\n const subtitle = event.subtitle;\n if (!this.listElement.hasItem(subtitle.id)) {\n this.listElement.addItem(subtitle.id, subtitle.label);\n }\n };\n\n private removeSubtitle = (event: SubtitleEvent) => {\n const subtitle = event.subtitle;\n if (this.listElement.hasItem(subtitle.id)) {\n this.listElement.removeItem(subtitle.id);\n }\n };\n\n private selectCurrentSubtitle = () => {\n if (!this.player.subtitles) {\n // Subtitles API not available (yet)\n return;\n }\n\n let currentSubtitle = this.player.subtitles.list().filter((subtitle) => subtitle.enabled).pop();\n this.listElement.selectItem(currentSubtitle ? currentSubtitle.id : SubtitleSwitchHandler.SUBTITLES_OFF_KEY);\n };\n\n private clearSubtitles = () => {\n this.listElement.clearItems();\n }\n\n private refreshSubtitles = () => {\n if (!this.player.subtitles) {\n // Subtitles API not available (yet)\n return;\n }\n\n const offListItem: ListItem = {\n key: SubtitleSwitchHandler.SUBTITLES_OFF_KEY,\n label: i18n.getLocalizer('off'),\n };\n\n const subtitles = this.player.subtitles.list();\n const subtitleToListItem = (subtitle: SubtitleTrack): ListItem => {\n return { key: subtitle.id, label: subtitle.label };\n };\n\n this.listElement.synchronizeItems([\n offListItem, ...subtitles.map(subtitleToListItem),\n ]);\n this.selectCurrentSubtitle();\n };\n}\n","// TODO change to internal (not exported) class, how to use in other files?\n/**\n * Executes a callback after a specified amount of time, optionally repeatedly until stopped.\n */\nexport class Timeout {\n\n private readonly delay: number;\n private readonly callback: () => void;\n private readonly repeat: boolean;\n // There's two setTimeout declarations, one on Window which returns type \"number\" and one in NodeJS which returns\n // type \"Timer\". For unknown reasons builds on Jenkins fail due to a type mismatch when we use type \"number\" here,\n // although it works on other platforms (e.g. Windows, Codeship).\n // To work around the issue we use type \"any\". The type does not matter anyway because we're not working with\n // this value except providing it to clearTimeout.\n private timeoutOrIntervalId: any;\n private active: boolean;\n private suspended: boolean;\n\n /**\n * Creates a new timeout callback handler.\n * @param delay the delay in milliseconds after which the callback should be executed\n * @param callback the callback to execute after the delay time\n * @param repeat if true, call the callback repeatedly in delay intervals\n */\n constructor(delay: number, callback: () => void, repeat: boolean = false) {\n this.delay = delay;\n this.callback = callback;\n this.repeat = repeat;\n this.timeoutOrIntervalId = 0;\n this.active = false;\n this.suspended = false;\n }\n\n /**\n * Starts the timeout and calls the callback when the timeout delay has passed. Has no effect when the timeout is\n * suspended.\n * @returns {Timeout} the current timeout (so the start call can be chained to the constructor)\n */\n start(): this {\n this.reset();\n return this;\n }\n\n /**\n * Clears the timeout. The callback will not be called if clear is called during the timeout.\n */\n clear(): void {\n this.clearInternal();\n }\n\n /**\n * Suspends the timeout. The callback will not be called and calls to `start` and `reset` will be ignored until the\n * timeout is resumed.\n */\n suspend() {\n this.suspended = true;\n this.clearInternal();\n\n return this;\n }\n\n /**\n * Resumes the timeout.\n * @param reset whether to reset the timeout after resuming\n */\n resume(reset: boolean) {\n this.suspended = false;\n\n if (reset) {\n this.reset();\n }\n\n return this;\n }\n\n /**\n * Resets the passed timeout delay to zero. Can be used to defer the calling of the callback. Has no effect if the\n * timeout is suspended.\n */\n reset(): void {\n this.clearInternal();\n\n if (this.suspended) {\n return;\n }\n\n if (this.repeat) {\n this.timeoutOrIntervalId = setInterval(this.callback, this.delay);\n } else {\n this.timeoutOrIntervalId = setTimeout(() => {\n this.active = false;\n this.callback();\n }, this.delay);\n }\n this.active = true;\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n private clearInternal(): void {\n if (this.repeat) {\n clearInterval(this.timeoutOrIntervalId);\n } else {\n clearTimeout(this.timeoutOrIntervalId);\n }\n this.active = false;\n }\n}","import { SubtitleOverlay } from './components/subtitleoverlay';\nimport { SettingsPanelPage } from './components/settingspanelpage';\nimport { SettingsPanelItem } from './components/settingspanelitem';\nimport { VideoQualitySelectBox } from './components/videoqualityselectbox';\nimport { PlaybackSpeedSelectBox } from './components/playbackspeedselectbox';\nimport { AudioTrackSelectBox } from './components/audiotrackselectbox';\nimport { AudioQualitySelectBox } from './components/audioqualityselectbox';\nimport { SettingsPanel } from './components/settingspanel';\nimport { SubtitleSettingsPanelPage } from './components/subtitlesettings/subtitlesettingspanelpage';\nimport { SettingsPanelPageOpenButton } from './components/settingspanelpageopenbutton';\nimport { SubtitleSettingsLabel } from './components/subtitlesettings/subtitlesettingslabel';\nimport { SubtitleSelectBox } from './components/subtitleselectbox';\nimport { ControlBar } from './components/controlbar';\nimport { Container, ContainerConfig } from './components/container';\nimport { PlaybackTimeLabel, PlaybackTimeLabelMode } from './components/playbacktimelabel';\nimport { SeekBar } from './components/seekbar';\nimport { SeekBarLabel } from './components/seekbarlabel';\nimport { PlaybackToggleButton } from './components/playbacktogglebutton';\nimport { VolumeToggleButton } from './components/volumetogglebutton';\nimport { VolumeSlider } from './components/volumeslider';\nimport { Spacer } from './components/spacer';\nimport { PictureInPictureToggleButton } from './components/pictureinpicturetogglebutton';\nimport { AirPlayToggleButton } from './components/airplaytogglebutton';\nimport { CastToggleButton } from './components/casttogglebutton';\nimport { VRToggleButton } from './components/vrtogglebutton';\nimport { SettingsToggleButton } from './components/settingstogglebutton';\nimport { FullscreenToggleButton } from './components/fullscreentogglebutton';\nimport { UIContainer } from './components/uicontainer';\nimport { BufferingOverlay } from './components/bufferingoverlay';\nimport { PlaybackToggleOverlay } from './components/playbacktoggleoverlay';\nimport { CastStatusOverlay } from './components/caststatusoverlay';\nimport { TitleBar } from './components/titlebar';\nimport { RecommendationOverlay } from './components/recommendationoverlay';\nimport { Watermark } from './components/watermark';\nimport { ErrorMessageOverlay } from './components/errormessageoverlay';\nimport { AdClickOverlay } from './components/adclickoverlay';\nimport { AdMessageLabel } from './components/admessagelabel';\nimport { AdSkipButton } from './components/adskipbutton';\nimport { CloseButton } from './components/closebutton';\nimport { MetadataLabel, MetadataLabelContent } from './components/metadatalabel';\nimport { PlayerUtils } from './playerutils';\nimport { Label } from './components/label';\nimport { CastUIContainer } from './components/castuicontainer';\nimport { UIConditionContext, UIManager } from './uimanager';\nimport { UIConfig } from './uiconfig';\nimport { PlayerAPI } from 'bitmovin-player';\nimport { i18n } from './localization/i18n';\nimport { SubtitleListBox } from './components/subtitlelistbox';\nimport { AudioTrackListBox } from './components/audiotracklistbox';\nimport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nimport { RootNavigationGroup } from './spatialnavigation/rootnavigationgroup';\nimport { ListNavigationGroup, ListOrientation } from './spatialnavigation/ListNavigationGroup';\nimport { EcoModeContainer } from './components/ecomodecontainer';\n\nexport namespace UIFactory {\n export function buildDefaultUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernUI(player, config);\n }\n\n export function buildDefaultSmallScreenUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernSmallScreenUI(player, config);\n }\n\n export function buildDefaultCastReceiverUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernCastReceiverUI(player, config);\n }\n\n export function buildDefaultTvUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return UIFactory.buildModernTvUI(player, config);\n }\n\n export function modernUI(config: UIConfig) {\n let subtitleOverlay = new SubtitleOverlay();\n\n let mainSettingsPanelPage: SettingsPanelPage;\n\n const components: Container<ContainerConfig>[] = [\n new SettingsPanelItem(i18n.getLocalizer('settings.video.quality'), new VideoQualitySelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('speed'), new PlaybackSpeedSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.track'), new AudioTrackSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.quality'), new AudioQualitySelectBox()),\n ];\n\n if (config.ecoMode) {\n const ecoModeContainer = new EcoModeContainer();\n\n ecoModeContainer.setOnToggleCallback(() => {\n // forces the browser to re-calculate the height of the settings panel when adding/removing elements\n settingsPanel.getDomElement().css({ width: '', height: '' });\n });\n\n components.unshift(ecoModeContainer);\n }\n\n mainSettingsPanelPage = new SettingsPanelPage({\n components,\n });\n\n let settingsPanel = new SettingsPanel({\n components: [mainSettingsPanelPage],\n hidden: true,\n });\n\n let subtitleSettingsPanelPage = new SubtitleSettingsPanelPage({\n settingsPanel: settingsPanel,\n overlay: subtitleOverlay,\n });\n\n const subtitleSelectBox = new SubtitleSelectBox();\n\n let subtitleSettingsOpenButton = new SettingsPanelPageOpenButton({\n targetPage: subtitleSettingsPanelPage,\n container: settingsPanel,\n ariaLabel: i18n.getLocalizer('settings.subtitles'),\n text: i18n.getLocalizer('open'),\n });\n\n mainSettingsPanelPage.addComponent(\n new SettingsPanelItem(\n new SubtitleSettingsLabel({\n text: i18n.getLocalizer('settings.subtitles'),\n opener: subtitleSettingsOpenButton,\n }),\n subtitleSelectBox,\n {\n role: 'menubar',\n },\n ),\n );\n\n settingsPanel.addComponent(subtitleSettingsPanelPage);\n\n let controlBar = new ControlBar({\n components: [\n settingsPanel,\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n new Container({\n components: [\n new PlaybackToggleButton(),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new CastToggleButton(),\n new VRToggleButton(),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new CastStatusOverlay(),\n controlBar,\n new TitleBar(),\n new RecommendationOverlay(),\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernAdsUI() {\n return new UIContainer({\n components: [\n new BufferingOverlay(),\n new AdClickOverlay(),\n new PlaybackToggleOverlay(),\n new Container({\n components: [new AdMessageLabel({ text: i18n.getLocalizer('ads.remainingTime') }), new AdSkipButton()],\n cssClass: 'ui-ads-status',\n }),\n new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackToggleButton(),\n new VolumeToggleButton(),\n new VolumeSlider(),\n new Spacer(),\n new FullscreenToggleButton(),\n ],\n cssClasses: ['controlbar-bottom'],\n }),\n ],\n }),\n ],\n cssClasses: ['ui-skin-ads'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernSmallScreenUI() {\n let subtitleOverlay = new SubtitleOverlay();\n\n let mainSettingsPanelPage = new SettingsPanelPage({\n components: [\n new SettingsPanelItem(i18n.getLocalizer('settings.video.quality'), new VideoQualitySelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('speed'), new PlaybackSpeedSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.track'), new AudioTrackSelectBox()),\n new SettingsPanelItem(i18n.getLocalizer('settings.audio.quality'), new AudioQualitySelectBox()),\n ],\n });\n\n let settingsPanel = new SettingsPanel({\n components: [mainSettingsPanelPage],\n hidden: true,\n pageTransitionAnimation: false,\n hideDelay: -1,\n });\n\n let subtitleSettingsPanelPage = new SubtitleSettingsPanelPage({\n settingsPanel: settingsPanel,\n overlay: subtitleOverlay,\n });\n\n let subtitleSettingsOpenButton = new SettingsPanelPageOpenButton({\n targetPage: subtitleSettingsPanelPage,\n container: settingsPanel,\n ariaLabel: i18n.getLocalizer('settings.subtitles'),\n text: i18n.getLocalizer('open'),\n });\n\n const subtitleSelectBox = new SubtitleSelectBox();\n\n mainSettingsPanelPage.addComponent(\n new SettingsPanelItem(\n new SubtitleSettingsLabel({\n text: i18n.getLocalizer('settings.subtitles'),\n opener: subtitleSettingsOpenButton,\n }),\n subtitleSelectBox,\n {\n role: 'menubar',\n },\n ),\n );\n\n settingsPanel.addComponent(subtitleSettingsPanelPage);\n\n settingsPanel.addComponent(new CloseButton({ target: settingsPanel }));\n subtitleSettingsPanelPage.addComponent(new CloseButton({ target: settingsPanel }));\n\n let controlBar = new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ label: new SeekBarLabel() }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n });\n\n return new UIContainer({\n components: [\n subtitleOverlay,\n new BufferingOverlay(),\n new CastStatusOverlay(),\n new PlaybackToggleOverlay(),\n new RecommendationOverlay(),\n controlBar,\n new TitleBar({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n new CastToggleButton(),\n new VRToggleButton(),\n new PictureInPictureToggleButton(),\n new AirPlayToggleButton(),\n new VolumeToggleButton(),\n new SettingsToggleButton({ settingsPanel: settingsPanel }),\n new FullscreenToggleButton(),\n ],\n }),\n settingsPanel,\n new Watermark(),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-smallscreen'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernSmallScreenAdsUI() {\n return new UIContainer({\n components: [\n new BufferingOverlay(),\n new AdClickOverlay(),\n new PlaybackToggleOverlay(),\n new TitleBar({\n components: [\n // dummy label with no content to move buttons to the right\n new Label({ cssClass: 'label-metadata-title' }),\n new FullscreenToggleButton(),\n ],\n }),\n new Container({\n components: [new AdMessageLabel({ text: 'Ad: {remainingTime} secs' }), new AdSkipButton()],\n cssClass: 'ui-ads-status',\n }),\n ],\n cssClasses: ['ui-skin-ads', 'ui-skin-smallscreen'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function modernCastReceiverUI() {\n let controlBar = new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n new SeekBar({ smoothPlaybackPositionUpdateIntervalMs: -1 }),\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.TotalTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n });\n\n return new CastUIContainer({\n components: [\n new SubtitleOverlay(),\n new BufferingOverlay(),\n new PlaybackToggleOverlay(),\n new Watermark(),\n controlBar,\n new TitleBar({ keepHiddenWithoutMetadata: true }),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-cast-receiver'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n }\n\n export function buildModernUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n // show smallScreen UI only on mobile/handheld devices\n let smallScreenSwitchWidth = 600;\n\n return new UIManager(\n player,\n [\n {\n ui: modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return (\n context.isMobile && context.documentWidth < smallScreenSwitchWidth && context.isAd && context.adRequiresUi\n );\n },\n },\n {\n ui: modernAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n },\n {\n ui: modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return (\n !context.isAd &&\n !context.adRequiresUi &&\n context.isMobile &&\n context.documentWidth < smallScreenSwitchWidth\n );\n },\n },\n {\n ui: modernUI(config),\n condition: (context: UIConditionContext) => {\n return !context.isAd && !context.adRequiresUi;\n },\n },\n ],\n config,\n );\n }\n\n export function buildModernSmallScreenUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(\n player,\n [\n {\n ui: modernSmallScreenAdsUI(),\n condition: (context: UIConditionContext) => {\n return context.isAd && context.adRequiresUi;\n },\n },\n {\n ui: modernSmallScreenUI(),\n condition: (context: UIConditionContext) => {\n return !context.isAd && !context.adRequiresUi;\n },\n },\n ],\n config,\n );\n }\n\n export function buildModernCastReceiverUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(player, modernCastReceiverUI(), config);\n }\n\n export function buildModernTvUI(player: PlayerAPI, config: UIConfig = {}): UIManager {\n return new UIManager(\n player,\n [\n {\n ...modernTvUI(),\n },\n ],\n config,\n );\n }\n\n export function modernTvUI() {\n const subtitleListBox = new SubtitleListBox();\n const subtitleListPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [new SettingsPanelItem(null, subtitleListBox)],\n }),\n ],\n hidden: true,\n });\n\n const audioTrackListBox = new AudioTrackListBox();\n const audioTrackListPanel = new SettingsPanel({\n components: [\n new SettingsPanelPage({\n components: [new SettingsPanelItem(null, audioTrackListBox)],\n }),\n ],\n hidden: true,\n });\n\n const seekBar = new SeekBar({ label: new SeekBarLabel() });\n const playbackToggleOverlay = new PlaybackToggleOverlay();\n const subtitleToggleButton = new SettingsToggleButton({\n settingsPanel: subtitleListPanel,\n autoHideWhenNoActiveSettings: true,\n cssClass: 'ui-subtitlesettingstogglebutton',\n text: i18n.getLocalizer('settings.subtitles'),\n });\n const audioToggleButton = new SettingsToggleButton({\n settingsPanel: audioTrackListPanel,\n autoHideWhenNoActiveSettings: true,\n cssClass: 'ui-audiotracksettingstogglebutton',\n ariaLabel: i18n.getLocalizer('settings.audio.track'),\n text: i18n.getLocalizer('settings.audio.track'),\n });\n const uiContainer = new UIContainer({\n components: [\n new SubtitleOverlay(),\n new BufferingOverlay(),\n playbackToggleOverlay,\n new ControlBar({\n components: [\n new Container({\n components: [\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.CurrentTime,\n hideInLivePlayback: true,\n }),\n seekBar,\n new PlaybackTimeLabel({\n timeLabelMode: PlaybackTimeLabelMode.RemainingTime,\n cssClasses: ['text-right'],\n }),\n ],\n cssClasses: ['controlbar-top'],\n }),\n ],\n }),\n new TitleBar({\n components: [\n new Container({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Title }),\n subtitleToggleButton,\n audioToggleButton,\n ],\n cssClasses: ['ui-titlebar-top'],\n }),\n new Container({\n components: [\n new MetadataLabel({ content: MetadataLabelContent.Description }),\n subtitleListPanel,\n audioTrackListPanel,\n ],\n cssClasses: ['ui-titlebar-bottom'],\n }),\n ],\n }),\n new RecommendationOverlay(),\n new ErrorMessageOverlay(),\n ],\n cssClasses: ['ui-skin-tv'],\n hideDelay: 2000,\n hidePlayerStateExceptions: [\n PlayerUtils.PlayerState.Prepared,\n PlayerUtils.PlayerState.Paused,\n PlayerUtils.PlayerState.Finished,\n ],\n });\n\n const spatialNavigation = new SpatialNavigation(\n new RootNavigationGroup(uiContainer, playbackToggleOverlay, seekBar, audioToggleButton, subtitleToggleButton),\n new ListNavigationGroup(ListOrientation.Vertical, subtitleListPanel, subtitleListBox),\n new ListNavigationGroup(ListOrientation.Vertical, audioTrackListPanel, audioTrackListBox),\n );\n\n return {\n ui: uiContainer,\n spatialNavigation: spatialNavigation,\n };\n }\n}\n","import {UIContainer} from './components/uicontainer';\nimport {DOM} from './dom';\nimport { Component, ComponentConfig, ViewModeChangedEventArgs } from './components/component';\nimport {Container} from './components/container';\nimport { SeekBar, SeekBarMarker } from './components/seekbar';\nimport {NoArgs, EventDispatcher, CancelEventArgs} from './eventdispatcher';\nimport {UIUtils} from './uiutils';\nimport {ArrayUtils} from './arrayutils';\nimport {BrowserUtils} from './browserutils';\nimport { TimelineMarker, UIConfig } from './uiconfig';\nimport { PlayerAPI, PlayerEventCallback, PlayerEventBase, PlayerEvent, AdEvent, LinearAd } from 'bitmovin-player';\nimport { VolumeController } from './volumecontroller';\nimport { i18n, CustomVocabulary, Vocabularies } from './localization/i18n';\nimport { FocusVisibilityTracker } from './focusvisibilitytracker';\nimport { isMobileV3PlayerAPI, MobileV3PlayerAPI, MobileV3PlayerEvent } from './mobilev3playerapi';\nimport { SpatialNavigation } from './spatialnavigation/spatialnavigation';\nimport { SubtitleSettingsManager } from './components/subtitlesettings/subtitlesettingsmanager';\nimport { StorageUtils } from './storageutils';\n\n/**\n * @category Configs\n */\nexport interface LocalizationConfig {\n /**\n * Sets the desired language, and falls back to 'en' if there is no vocabulary for the desired language. Setting it\n * to \"auto\" will enable language detection from the browser's locale.\n */\n language?: 'auto' | 'en' | 'de' | string;\n /**\n * A map of `language` to {@link CustomVocabulary} definitions. Can be used to overwrite default translations and add\n * custom strings or additional languages.\n */\n vocabularies?: Vocabularies;\n}\n\n/**\n * @category Configs\n */\nexport interface InternalUIConfig extends UIConfig {\n events: {\n /**\n * Fires when the configuration has been updated/changed.\n */\n onUpdated: EventDispatcher<UIManager, void>;\n };\n volumeController: VolumeController;\n}\n\n/**\n * The context that will be passed to a {@link UIConditionResolver} to determine if it's conditions fulfil the context.\n */\nexport interface UIConditionContext {\n /**\n * Tells if the player is loading or playing an ad.\n */\n isAd: boolean;\n /**\n * Tells if the current ad requires an external UI, if {@link #isAd} is true.\n */\n adRequiresUi: boolean;\n /**\n * Tells if the player is currently in fullscreen mode.\n */\n isFullscreen: boolean;\n /**\n * Tells if the UI is running in a mobile browser.\n */\n isMobile: boolean;\n /**\n * Tells if the player is in playing or paused state.\n */\n isPlaying: boolean;\n /**\n * The width of the player/UI element.\n */\n width: number;\n /**\n * The width of the document where the player/UI is embedded in.\n */\n documentWidth: number;\n}\n\n/**\n * Resolves the conditions of its associated UI in a {@link UIVariant} upon a {@link UIConditionContext} and decides\n * if the UI should be displayed. If it returns true, the UI is a candidate for display; if it returns false, it will\n * not be displayed in the given context.\n */\nexport interface UIConditionResolver {\n (context: UIConditionContext): boolean;\n}\n\n/**\n * Associates a UI instance with an optional {@link UIConditionResolver} that determines if the UI should be displayed.\n */\nexport interface UIVariant {\n ui: UIContainer;\n condition?: UIConditionResolver;\n spatialNavigation?: SpatialNavigation;\n}\n\nexport interface ActiveUiChangedArgs extends NoArgs {\n /**\n * The previously active {@link UIInstanceManager} prior to the {@link UIManager} switching to a different UI variant.\n */\n previousUi: UIInstanceManager;\n /**\n * The currently active {@link UIInstanceManager}.\n */\n currentUi: UIInstanceManager;\n}\n\nexport class UIManager {\n\n private player: PlayerAPI;\n private uiContainerElement: DOM;\n private uiVariants: UIVariant[];\n private uiInstanceManagers: InternalUIInstanceManager[];\n private currentUi: InternalUIInstanceManager;\n private config: InternalUIConfig; // Conjunction of provided uiConfig and sourceConfig from the player\n private managerPlayerWrapper: PlayerWrapper;\n private focusVisibilityTracker: FocusVisibilityTracker;\n private subtitleSettingsManager: SubtitleSettingsManager;\n\n private events = {\n onUiVariantResolve: new EventDispatcher<UIManager, UIConditionContext>(),\n onActiveUiChanged: new EventDispatcher<UIManager, ActiveUiChangedArgs>(),\n };\n\n /**\n * Creates a UI manager with a single UI variant that will be permanently shown.\n * @param player the associated player of this UI\n * @param ui the UI to add to the player\n * @param uiconfig optional UI configuration\n */\n constructor(player: PlayerAPI, ui: UIContainer, uiconfig?: UIConfig);\n /**\n * Creates a UI manager with a list of UI variants that will be dynamically selected and switched according to\n * the context of the UI.\n *\n * Every time the UI context changes, the conditions of the UI variants will be sequentially resolved and the first\n * UI, whose condition evaluates to true, will be selected and displayed. The last variant in the list might omit the\n * condition resolver and will be selected as default/fallback UI when all other conditions fail. If there is no\n * fallback UI and all conditions fail, no UI will be displayed.\n *\n * @param player the associated player of this UI\n * @param uiVariants a list of UI variants that will be dynamically switched\n * @param uiconfig optional UI configuration\n */\n constructor(player: PlayerAPI, uiVariants: UIVariant[], uiconfig?: UIConfig);\n constructor(player: PlayerAPI, playerUiOrUiVariants: UIContainer | UIVariant[], uiconfig: UIConfig = {}) {\n if (playerUiOrUiVariants instanceof UIContainer) {\n // Single-UI constructor has been called, transform arguments to UIVariant[] signature\n let playerUi = <UIContainer>playerUiOrUiVariants;\n let uiVariants = [];\n\n // Add the default player UI\n uiVariants.push({ ui: playerUi });\n\n this.uiVariants = uiVariants;\n }\n else {\n // Default constructor (UIVariant[]) has been called\n this.uiVariants = <UIVariant[]>playerUiOrUiVariants;\n }\n\n this.subtitleSettingsManager = new SubtitleSettingsManager();\n this.player = player;\n this.managerPlayerWrapper = new PlayerWrapper(player);\n\n // ensure that at least the metadata object does exist in the uiconfig\n uiconfig.metadata = uiconfig.metadata ? uiconfig.metadata : {};\n\n this.config = {\n playbackSpeedSelectionEnabled: true, // Switch on speed selector by default\n autoUiVariantResolve: true, // Switch on auto UI resolving by default\n disableAutoHideWhenHovered: false, // Disable auto hide when UI is hovered\n enableSeekPreview: true,\n ...uiconfig,\n events: {\n onUpdated: new EventDispatcher<UIManager, void>(),\n },\n volumeController: new VolumeController(this.managerPlayerWrapper.getPlayer()),\n };\n\n /**\n * Gathers configuration data from the UI config and player source config and creates a merged UI config\n * that is used throughout the UI instance.\n */\n const updateConfig = () => {\n const playerSourceConfig = player.getSource() || {};\n this.config.metadata = JSON.parse(JSON.stringify(uiconfig.metadata || {}));\n\n // Extract the UI-related config properties from the source config\n const playerSourceUiConfig: UIConfig = {\n metadata: {\n // TODO move metadata into source.metadata namespace in player v8\n title: playerSourceConfig.title,\n description: playerSourceConfig.description,\n markers: (playerSourceConfig as any).markers,\n },\n recommendations: (playerSourceConfig as any).recommendations,\n };\n\n // Player source config takes precedence over the UI config, because the config in the source is attached\n // to a source which changes with every player.load, whereas the UI config stays the same for the whole\n // lifetime of the player instance.\n this.config.metadata.title = playerSourceUiConfig.metadata.title || uiconfig.metadata.title;\n this.config.metadata.description = playerSourceUiConfig.metadata.description || uiconfig.metadata.description;\n this.config.metadata.markers = playerSourceUiConfig.metadata.markers || uiconfig.metadata.markers || [];\n this.config.recommendations = playerSourceUiConfig.recommendations || uiconfig.recommendations || [];\n\n StorageUtils.setStorageApiDisabled(uiconfig);\n };\n\n updateConfig();\n this.subtitleSettingsManager.initialize();\n\n // Update the source configuration when a new source is loaded and dispatch onUpdated\n const updateSource = () => {\n updateConfig();\n this.config.events.onUpdated.dispatch(this);\n };\n\n const wrappedPlayer = this.managerPlayerWrapper.getPlayer();\n\n wrappedPlayer.on(this.player.exports.PlayerEvent.SourceLoaded, updateSource);\n\n // The PlaylistTransition event is only available on Mobile v3 for now.\n // This event is fired when a new source becomes active in the player.\n if (isMobileV3PlayerAPI(wrappedPlayer)) {\n wrappedPlayer.on(MobileV3PlayerEvent.PlaylistTransition, updateSource);\n }\n\n if (uiconfig.container) {\n // Unfortunately \"uiContainerElement = new DOM(config.container)\" will not accept the container with\n // string|HTMLElement type directly, although it accepts both types, so we need to spit these two cases up here.\n // TODO check in upcoming TS versions if the container can be passed in directly, or fix the constructor\n this.uiContainerElement = uiconfig.container instanceof HTMLElement ?\n new DOM(uiconfig.container) : new DOM(uiconfig.container);\n } else {\n this.uiContainerElement = new DOM(player.getContainer());\n }\n\n // Create UI instance managers for the UI variants\n // The instance managers map to the corresponding UI variants by their array index\n this.uiInstanceManagers = [];\n let uiVariantsWithoutCondition = [];\n for (let uiVariant of this.uiVariants) {\n if (uiVariant.condition == null) {\n // Collect variants without conditions for error checking\n uiVariantsWithoutCondition.push(uiVariant);\n }\n // Create the instance manager for a UI variant\n this.uiInstanceManagers.push(new InternalUIInstanceManager(\n player,\n uiVariant.ui,\n this.config,\n this.subtitleSettingsManager,\n uiVariant.spatialNavigation,\n ));\n }\n // Make sure that there is only one UI variant without a condition\n // It does not make sense to have multiple variants without condition, because only the first one in the list\n // (the one with the lowest index) will ever be selected.\n if (uiVariantsWithoutCondition.length > 1) {\n throw Error('Too many UIs without a condition: You cannot have more than one default UI');\n }\n // Make sure that the default UI variant, if defined, is at the end of the list (last index)\n // If it comes earlier, the variants with conditions that come afterwards will never be selected because the\n // default variant without a condition always evaluates to 'true'\n if (uiVariantsWithoutCondition.length > 0\n && uiVariantsWithoutCondition[0] !== this.uiVariants[this.uiVariants.length - 1]) {\n throw Error('Invalid UI variant order: the default UI (without condition) must be at the end of the list');\n }\n\n let adStartedEvent: AdEvent = null; // keep the event stored here during ad playback\n\n // Dynamically select a UI variant that matches the current UI condition.\n let resolveUiVariant = (event: PlayerEventBase) => {\n // Make sure that the AdStarted event data is persisted through ad playback in case other events happen\n // in the meantime, e.g. player resize. We need to store this data because there is no other way to find out\n // ad details while an ad is playing (in v8.0 at least; from v8.1 there will be ads.getActiveAd()).\n // Existing event data signals that an ad is currently active (instead of ads.isLinearAdActive()).\n if (event != null) {\n switch (event.type) {\n // The ads UI is shown upon the first AdStarted event. Subsequent AdStarted events within an ad break\n // will not change the condition context and thus not lead to undesired UI variant resolving.\n // The ads UI is shown upon AdStarted instead of AdBreakStarted because there can be a loading delay\n // between these two events in the player, and the AdBreakStarted event does not carry any metadata to\n // initialize the ads UI, so it would be rendered in an uninitialized state for a certain amount of time.\n // TODO show ads UI upon AdBreakStarted and display loading overlay between AdBreakStarted and first AdStarted\n // TODO display loading overlay between AdFinished and next AdStarted\n case player.exports.PlayerEvent.AdStarted:\n adStartedEvent = event as AdEvent;\n break;\n // The ads UI is hidden only when the ad break is finished, i.e. not on AdFinished events. This way we keep\n // the ads UI variant active throughout an ad break, as reacting to AdFinished would lead to undesired UI\n // variant switching between two ads in an ad break, e.g. ads UI -> AdFinished -> content UI ->\n // AdStarted -> ads UI.\n case player.exports.PlayerEvent.AdBreakFinished:\n adStartedEvent = null;\n // When switching to a variant for the first time, a config.events.onUpdated event is fired to trigger a UI\n // update of the new variant, because most components subscribe to this event to update themselves. When\n // switching to the ads UI on the first AdStarted, all UI variants update themselves with the ad data, so\n // when switching back to the \"normal\" UI it will carry properties of the ad instead of the main content.\n // We thus fire this event here to force an UI update with the properties of the main content. This is\n // basically a hack because the config.events.onUpdated event is abused in many places and not just used\n // for config updates (e.g. adding a marker to the seekbar).\n // TODO introduce an event that is fired when the playback content is updated, a switch to/from ads\n this.config.events.onUpdated.dispatch(this);\n break;\n // When a new source is loaded during ad playback, there will be no Ad(Break)Finished event\n case player.exports.PlayerEvent.SourceLoaded:\n case player.exports.PlayerEvent.SourceUnloaded:\n adStartedEvent = null;\n break;\n }\n }\n\n // Detect if an ad has started\n let isAd = adStartedEvent != null;\n let adRequiresUi = false;\n if (isAd) {\n let ad = adStartedEvent.ad;\n // for now only linear ads can request a UI\n if (ad.isLinear) {\n let linearAd = ad as LinearAd;\n adRequiresUi = linearAd.uiConfig && linearAd.uiConfig.requestsUi || false;\n }\n }\n\n if (adRequiresUi) {\n // we dispatch onUpdated event because if there are multiple adBreaks for same position\n // `Play` and `Playing` events will not be dispatched which will cause `PlaybackButton` state\n // to be out of sync\n this.config.events.onUpdated.dispatch(this);\n }\n\n this.resolveUiVariant({\n isAd: isAd,\n adRequiresUi: adRequiresUi,\n }, (context) => {\n // If this is an ad UI, we need to relay the saved ON_AD_STARTED event data so ad components can configure\n // themselves for the current ad.\n if (context.isAd) {\n /* Relay the ON_AD_STARTED event to the ads UI\n *\n * Because the ads UI is initialized in the ON_AD_STARTED handler, i.e. when the ON_AD_STARTED event has\n * already been fired, components in the ads UI that listen for the ON_AD_STARTED event never receive it.\n * Since this can break functionality of components that rely on this event, we relay the event to the\n * ads UI components with the following call.\n */\n this.currentUi.getWrappedPlayer().fireEventInUI(this.player.exports.PlayerEvent.AdStarted, adStartedEvent);\n }\n });\n };\n\n // Listen to the following events to trigger UI variant resolution\n if (this.config.autoUiVariantResolve) {\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.SourceLoaded, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.SourceUnloaded, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.Play, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.Paused, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.AdStarted, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.AdBreakFinished, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.PlayerResized, resolveUiVariant);\n this.managerPlayerWrapper.getPlayer().on(this.player.exports.PlayerEvent.ViewModeChanged, resolveUiVariant);\n }\n\n this.focusVisibilityTracker = new FocusVisibilityTracker('{{PREFIX}}');\n\n // Initialize the UI\n resolveUiVariant(null);\n }\n\n /**\n * Exposes i18n.getLocalizer() function\n * @returns {I18nApi.getLocalizer()}\n */\n static localize<V extends CustomVocabulary<Record<string, string>>>(key: keyof V) {\n return i18n.getLocalizer(key);\n }\n\n /**\n * Provide configuration to support Custom UI languages\n * default language: 'en'\n */\n static setLocalizationConfig(localizationConfig: LocalizationConfig) {\n i18n.setConfig(localizationConfig);\n }\n\n getSubtitleSettingsManager() {\n return this.subtitleSettingsManager;\n }\n\n getConfig(): UIConfig {\n return this.config;\n }\n\n /**\n * Returns the list of UI variants as passed into the constructor of {@link UIManager}.\n * @returns {UIVariant[]} the list of available UI variants\n */\n getUiVariants(): UIVariant[] {\n return this.uiVariants;\n }\n\n /**\n * Switches to a UI variant from the list returned by {@link getUiVariants}.\n * @param {UIVariant} uiVariant the UI variant to switch to\n * @param {() => void} onShow a callback that is executed just before the new UI variant is shown\n */\n switchToUiVariant(uiVariant: UIVariant, onShow?: () => void): void {\n let uiVariantIndex = this.uiVariants.indexOf(uiVariant);\n\n const previousUi = this.currentUi;\n const nextUi: InternalUIInstanceManager = this.uiInstanceManagers[uiVariantIndex];\n // Determine if the UI variant is changing\n // Only if the UI variant is changing, we need to do some stuff. Else we just leave everything as-is.\n if (nextUi === this.currentUi) {\n return;\n // console.log('switched from ', this.currentUi ? this.currentUi.getUI() : 'none',\n // ' to ', nextUi ? nextUi.getUI() : 'none');\n }\n\n // Hide the currently active UI variant\n if (this.currentUi) {\n this.currentUi.getUI().hide();\n }\n\n // Assign the new UI variant as current UI\n this.currentUi = nextUi;\n\n // When we switch to a different UI instance, there's some additional stuff to manage. If we do not switch\n // to an instance, we're done here.\n if (this.currentUi == null) {\n return;\n }\n // Add the UI to the DOM (and configure it) the first time it is selected\n if (!this.currentUi.isConfigured()) {\n this.addUi(this.currentUi);\n // ensure that the internal state is ready for the upcoming show call\n if (!this.currentUi.getUI().isHidden()) {\n this.currentUi.getUI().hide();\n }\n }\n if (onShow) {\n onShow();\n }\n this.currentUi.getUI().show();\n this.events.onActiveUiChanged.dispatch(this, { previousUi, currentUi: nextUi });\n }\n\n /**\n * Triggers a UI variant switch as triggered by events when automatic switching is enabled. It allows to overwrite\n * properties of the {@link UIConditionContext}.\n * @param {Partial<UIConditionContext>} context an optional set of properties that overwrite properties of the\n * automatically determined context\n * @param {(context: UIConditionContext) => void} onShow a callback that is executed just before the new UI variant\n * is shown (if a switch is happening)\n */\n resolveUiVariant(context: Partial<UIConditionContext> = {}, onShow?: (context: UIConditionContext) => void): void {\n // Determine the current context for which the UI variant will be resolved\n const defaultContext: UIConditionContext = {\n isAd: false,\n adRequiresUi: false,\n isFullscreen: this.player.getViewMode() === this.player.exports.ViewMode.Fullscreen,\n isMobile: BrowserUtils.isMobile,\n isPlaying: this.player.isPlaying(),\n width: this.uiContainerElement.width(),\n documentWidth: document.body.clientWidth,\n };\n\n // Overwrite properties of the default context with passed in context properties\n const switchingContext = { ...defaultContext, ...context };\n\n // Fire the event and allow modification of the context before it is used to resolve the UI variant\n this.events.onUiVariantResolve.dispatch(this, switchingContext);\n\n let nextUiVariant: UIVariant = null;\n\n // Select new UI variant\n // If no variant condition is fulfilled, we switch to *no* UI\n for (let uiVariant of this.uiVariants) {\n const matchesCondition = uiVariant.condition == null || uiVariant.condition(switchingContext) === true;\n if (nextUiVariant == null && matchesCondition) {\n nextUiVariant = uiVariant;\n } else {\n // hide all UIs besides the one which should be active\n uiVariant.ui.hide();\n }\n }\n\n this.switchToUiVariant(nextUiVariant, () => {\n if (onShow) {\n onShow(switchingContext);\n }\n });\n }\n\n private addUi(ui: InternalUIInstanceManager): void {\n let dom = ui.getUI().getDomElement();\n let player = ui.getWrappedPlayer();\n\n ui.configureControls();\n /* Append the UI DOM after configuration to avoid CSS transitions at initialization\n * Example: Components are hidden during configuration and these hides may trigger CSS transitions that are\n * undesirable at this time. */\n this.uiContainerElement.append(dom);\n\n // When the UI is loaded after a source was loaded, we need to tell the components to initialize themselves\n if (player.getSource()) {\n this.config.events.onUpdated.dispatch(this);\n\n }\n\n // Fire onConfigured after UI DOM elements are successfully added. When fired immediately, the DOM elements\n // might not be fully configured and e.g. do not have a size.\n // https://swizec.com/blog/how-to-properly-wait-for-dom-elements-to-show-up-in-modern-browsers/swizec/6663\n if (window.requestAnimationFrame) {\n requestAnimationFrame(() => { ui.onConfigured.dispatch(ui.getUI()); });\n } else {\n // IE9 fallback\n setTimeout(() => { ui.onConfigured.dispatch(ui.getUI()); }, 0);\n }\n }\n\n private releaseUi(ui: InternalUIInstanceManager): void {\n ui.releaseControls();\n\n const uiContainer = ui.getUI();\n if (uiContainer.hasDomElement()) {\n uiContainer.getDomElement().remove();\n }\n\n ui.clearEventHandlers();\n }\n\n release(): void {\n for (let uiInstanceManager of this.uiInstanceManagers) {\n this.releaseUi(uiInstanceManager);\n }\n this.managerPlayerWrapper.clearEventHandlers();\n this.focusVisibilityTracker.release();\n }\n\n /**\n * Fires just before UI variants are about to be resolved and the UI variant is possibly switched. It is fired when\n * the switch is triggered from an automatic switch and when calling {@link resolveUiVariant}.\n * Can be used to modify the {@link UIConditionContext} before resolving is done.\n * @returns {EventDispatcher<UIManager, UIConditionContext>}\n */\n get onUiVariantResolve(): EventDispatcher<UIManager, UIConditionContext> {\n return this.events.onUiVariantResolve;\n }\n\n /**\n * Fires after the UIManager has switched to a different UI variant.\n * @returns {EventDispatcher<UIManager, ActiveUiChangedArgs>}\n */\n get onActiveUiChanged(): EventDispatcher<UIManager, ActiveUiChangedArgs> {\n return this.events.onActiveUiChanged;\n }\n\n /**\n * The current active {@link UIInstanceManager}.\n */\n get activeUi(): UIInstanceManager {\n return this.currentUi;\n }\n\n /**\n * Returns the list of all added markers in undefined order.\n */\n getTimelineMarkers(): TimelineMarker[] {\n return this.config.metadata.markers;\n }\n\n /**\n * Adds a marker to the timeline. Does not check for duplicates/overlaps at the `time`.\n */\n addTimelineMarker(timelineMarker: TimelineMarker): void {\n this.config.metadata.markers.push(timelineMarker);\n this.config.events.onUpdated.dispatch(this);\n }\n\n /**\n * Removes a marker from the timeline (by reference) and returns `true` if the marker has\n * been part of the timeline and successfully removed, or `false` if the marker could not\n * be found and thus not removed.\n */\n removeTimelineMarker(timelineMarker: TimelineMarker): boolean {\n if (ArrayUtils.remove(this.config.metadata.markers, timelineMarker) === timelineMarker) {\n this.config.events.onUpdated.dispatch(this);\n return true;\n }\n\n return false;\n }\n}\n\nexport interface SeekPreviewArgs extends NoArgs {\n /**\n * The timeline position in percent where the event originates from.\n */\n position: number;\n /**\n * The timeline marker associated with the current position, if existing.\n */\n marker?: SeekBarMarker;\n}\n\n/**\n * Encapsulates functionality to manage a UI instance. Used by the {@link UIManager} to manage multiple UI instances.\n */\nexport class UIInstanceManager {\n private playerWrapper: PlayerWrapper;\n private ui: UIContainer;\n private config: InternalUIConfig;\n private subtitleSettingsManager: SubtitleSettingsManager;\n protected spatialNavigation?: SpatialNavigation;\n\n private events = {\n onConfigured: new EventDispatcher<UIContainer, NoArgs>(),\n onSeek: new EventDispatcher<SeekBar, NoArgs>(),\n onSeekPreview: new EventDispatcher<SeekBar, SeekPreviewArgs>(),\n onSeeked: new EventDispatcher<SeekBar, NoArgs>(),\n onComponentShow: new EventDispatcher<Component<ComponentConfig>, NoArgs>(),\n onComponentHide: new EventDispatcher<Component<ComponentConfig>, NoArgs>(),\n onComponentViewModeChanged: new EventDispatcher<Component<ComponentConfig>, ViewModeChangedEventArgs>(),\n onControlsShow: new EventDispatcher<UIContainer, NoArgs>(),\n onPreviewControlsHide: new EventDispatcher<UIContainer, CancelEventArgs>(),\n onControlsHide: new EventDispatcher<UIContainer, NoArgs>(),\n onRelease: new EventDispatcher<UIContainer, NoArgs>(),\n };\n\n constructor(player: PlayerAPI, ui: UIContainer, config: InternalUIConfig, subtitleSettingsManager: SubtitleSettingsManager, spatialNavigation?: SpatialNavigation) {\n this.playerWrapper = new PlayerWrapper(player);\n this.ui = ui;\n this.config = config;\n this.subtitleSettingsManager = subtitleSettingsManager;\n this.spatialNavigation = spatialNavigation;\n }\n\n getSubtitleSettingsManager() {\n return this.subtitleSettingsManager;\n }\n\n getConfig(): InternalUIConfig {\n return this.config;\n }\n\n getUI(): UIContainer {\n return this.ui;\n }\n\n getPlayer(): PlayerAPI {\n return this.playerWrapper.getPlayer();\n }\n\n /**\n * Fires when the UI is fully configured and added to the DOM.\n * @returns {EventDispatcher}\n */\n get onConfigured(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onConfigured;\n }\n\n /**\n * Fires when a seek starts.\n * @returns {EventDispatcher}\n */\n get onSeek(): EventDispatcher<SeekBar, NoArgs> {\n return this.events.onSeek;\n }\n\n /**\n * Fires when the seek timeline is scrubbed.\n * @returns {EventDispatcher}\n */\n get onSeekPreview(): EventDispatcher<SeekBar, SeekPreviewArgs> {\n return this.events.onSeekPreview;\n }\n\n /**\n * Fires when a seek is finished.\n * @returns {EventDispatcher}\n */\n get onSeeked(): EventDispatcher<SeekBar, NoArgs> {\n return this.events.onSeeked;\n }\n\n /**\n * Fires when a component is showing.\n * @returns {EventDispatcher}\n */\n get onComponentShow(): EventDispatcher<Component<ComponentConfig>, NoArgs> {\n return this.events.onComponentShow;\n }\n\n /**\n * Fires when a component is hiding.\n * @returns {EventDispatcher}\n */\n get onComponentHide(): EventDispatcher<Component<ComponentConfig>, NoArgs> {\n return this.events.onComponentHide;\n }\n\n /**\n * Fires when the UI controls are showing.\n * @returns {EventDispatcher}\n */\n get onControlsShow(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onControlsShow;\n }\n\n /**\n * Fires before the UI controls are hiding to check if they are allowed to hide.\n * @returns {EventDispatcher}\n */\n get onPreviewControlsHide(): EventDispatcher<UIContainer, CancelEventArgs> {\n return this.events.onPreviewControlsHide;\n }\n\n /**\n * Fires when the UI controls are hiding.\n * @returns {EventDispatcher}\n */\n get onControlsHide(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onControlsHide;\n }\n\n /**\n * Fires when the UI controls are released.\n * @returns {EventDispatcher}\n */\n get onRelease(): EventDispatcher<UIContainer, NoArgs> {\n return this.events.onRelease;\n }\n\n get onComponentViewModeChanged(): EventDispatcher<Component<ComponentConfig>, ViewModeChangedEventArgs> {\n return this.events.onComponentViewModeChanged;\n }\n\n protected clearEventHandlers(): void {\n this.playerWrapper.clearEventHandlers();\n\n let events = <any>this.events; // avoid TS7017\n for (let event in events) {\n let dispatcher = <EventDispatcher<Object, Object>>events[event];\n dispatcher.unsubscribeAll();\n }\n }\n}\n\n/**\n * Extends the {@link UIInstanceManager} for internal use in the {@link UIManager} and provides access to functionality\n * that components receiving a reference to the {@link UIInstanceManager} should not have access to.\n */\nclass InternalUIInstanceManager extends UIInstanceManager {\n\n private configured: boolean;\n private released: boolean;\n\n getWrappedPlayer(): WrappedPlayer {\n // TODO find a non-hacky way to provide the WrappedPlayer to the UIManager without exporting it\n // getPlayer() actually returns the WrappedPlayer but its return type is set to Player so the WrappedPlayer does\n // not need to be exported\n return <WrappedPlayer>this.getPlayer();\n }\n\n configureControls(): void {\n this.configureControlsTree(this.getUI());\n this.configured = true;\n }\n\n isConfigured(): boolean {\n return this.configured;\n }\n\n private configureControlsTree(component: Component<ComponentConfig>) {\n let configuredComponents: Component<ComponentConfig>[] = [];\n\n UIUtils.traverseTree(component, (component) => {\n // First, check if we have already configured a component, and throw an error if we did. Multiple configuration\n // of the same component leads to unexpected UI behavior. Also, a component that is in the UI tree multiple\n // times hints at a wrong UI structure.\n // We could just skip configuration in such a case and not throw an exception, but enforcing a clean UI tree\n // seems like the better choice.\n for (let configuredComponent of configuredComponents) {\n if (configuredComponent === component) {\n // Write the component to the console to simplify identification of the culprit\n // (e.g. by inspecting the config)\n if (console) {\n console.error('Circular reference in UI tree', component);\n }\n\n // Additionally throw an error, because this case must not happen and leads to unexpected UI behavior.\n throw Error('Circular reference in UI tree: ' + component.constructor.name);\n }\n }\n\n component.initialize();\n component.configure(this.getPlayer(), this);\n configuredComponents.push(component);\n });\n }\n\n releaseControls(): void {\n // Do not call release methods if the components have never been configured; this can result in exceptions\n if (this.configured) {\n this.onRelease.dispatch(this.getUI());\n this.releaseControlsTree(this.getUI());\n this.configured = false;\n }\n this.spatialNavigation?.release();\n this.released = true;\n }\n\n isReleased(): boolean {\n return this.released;\n }\n\n private releaseControlsTree(component: Component<ComponentConfig>) {\n component.release();\n\n if (component instanceof Container) {\n for (let childComponent of component.getComponents()) {\n this.releaseControlsTree(childComponent);\n }\n }\n }\n\n clearEventHandlers(): void {\n super.clearEventHandlers();\n }\n}\n\n/**\n * Extended interface of the {@link Player} for use in the UI.\n */\nexport interface WrappedPlayer extends PlayerAPI {\n /**\n * Fires an event on the player that targets all handlers in the UI but never enters the real player.\n * @param event the event to fire\n * @param data data to send with the event\n */\n fireEventInUI(event: PlayerEvent, data: {}): void;\n}\n\n/**\n * Wraps the player to track event handlers and provide a simple method to remove all registered event\n * handlers from the player.\n *\n * @category Utils\n */\nexport class PlayerWrapper {\n\n private player: PlayerAPI;\n private wrapper: WrappedPlayer;\n\n private eventHandlers: { [eventType: string]: PlayerEventCallback[]; } = {};\n\n constructor(player: PlayerAPI) {\n this.player = player;\n\n // Collect all members of the player (public API methods and properties of the player)\n const objectProtoPropertyNames = Object.getOwnPropertyNames(Object.getPrototypeOf({}));\n const namesToIgnore = ['constructor', ...objectProtoPropertyNames];\n const members = getAllPropertyNames(player).filter(name => namesToIgnore.indexOf(name) === -1);\n // Split the members into methods and properties\n let methods = <any[]>[];\n let properties = <any[]>[];\n\n for (let member of members) {\n if (typeof (<any>player)[member] === 'function') {\n methods.push(member);\n } else {\n properties.push(member);\n }\n }\n\n // Create wrapper object\n let wrapper = <any>{};\n\n // Add function wrappers for all API methods that do nothing but calling the base method on the player\n for (let method of methods) {\n wrapper[method] = function() {\n // console.log('called ' + member); // track method calls on the player\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n return (<any>player)[method].apply(player, arguments);\n };\n }\n\n // Add all public properties of the player to the wrapper\n for (let property of properties) {\n // Get an eventually existing property descriptor to differentiate between plain properties and properties with\n // getters/setters.\n const propertyDescriptor = ((target: PlayerAPI) => {\n while (target) {\n const propertyDescriptor = Object.getOwnPropertyDescriptor(target, property);\n if (propertyDescriptor) {\n return propertyDescriptor;\n }\n // Check if the PropertyDescriptor exists on a child prototype in case we have an inheritance of the player\n target = Object.getPrototypeOf(target);\n }\n })(player);\n\n // If the property has getters/setters, wrap them accordingly...\n if (propertyDescriptor && (propertyDescriptor.get || propertyDescriptor.set)) {\n Object.defineProperty(wrapper, property, {\n get: () => propertyDescriptor.get.call(player),\n set: (value: any) => propertyDescriptor.set.call(player, value),\n });\n }\n // ... else just transfer the property to the wrapper\n else {\n wrapper[property] = (<any>player)[property];\n }\n }\n\n // Explicitly add a wrapper method for 'on' that adds added event handlers to the event list\n wrapper.on = (eventType: PlayerEvent, callback: PlayerEventCallback) => {\n player.on(eventType, callback);\n\n if (!this.eventHandlers[eventType]) {\n this.eventHandlers[eventType] = [];\n }\n\n this.eventHandlers[eventType].push(callback);\n\n return wrapper;\n };\n\n // Explicitly add a wrapper method for 'off' that removes removed event handlers from the event list\n wrapper.off = (eventType: PlayerEvent, callback: PlayerEventCallback) => {\n player.off(eventType, callback);\n\n if (this.eventHandlers[eventType]) {\n ArrayUtils.remove(this.eventHandlers[eventType], callback);\n }\n\n return wrapper;\n };\n\n wrapper.fireEventInUI = (event: PlayerEvent, data: {}) => {\n if (this.eventHandlers[event]) { // check if there are handlers for this event registered\n // Extend the data object with default values to convert it to a {@link PlayerEventBase} object.\n let playerEventData = <PlayerEventBase>Object.assign({}, {\n timestamp: Date.now(),\n type: event,\n // Add a marker property so the UI can detect UI-internal player events\n uiSourced: true,\n }, data);\n\n // Execute the registered callbacks\n for (let callback of this.eventHandlers[event]) {\n callback(playerEventData);\n }\n }\n };\n\n this.wrapper = <WrappedPlayer>wrapper;\n }\n\n /**\n * Returns a wrapped player object that can be used on place of the normal player object.\n * @returns {WrappedPlayer} a wrapped player\n */\n getPlayer(): WrappedPlayer {\n return this.wrapper;\n }\n\n /**\n * Clears all registered event handlers from the player that were added through the wrapped player.\n */\n clearEventHandlers(): void {\n try {\n // Call the player API to check if the instance is still valid or already destroyed.\n // This can be any call throwing the PlayerAPINotAvailableError when the player instance is destroyed.\n this.player.getSource();\n } catch (error) {\n if (error instanceof this.player.exports.PlayerAPINotAvailableError) {\n // We have detected that the player instance is already destroyed, so we clear the event handlers to avoid\n // event handler unsubscription attempts (which would result in PlayerAPINotAvailableError errors).\n this.eventHandlers = {};\n }\n }\n\n for (let eventType in this.eventHandlers) {\n for (let callback of this.eventHandlers[eventType]) {\n this.player.off(eventType as PlayerEvent, callback);\n }\n }\n }\n}\n\nfunction getAllPropertyNames(target: Object): string[] {\n let names: string[] = [];\n\n while (target) {\n const newNames = Object.getOwnPropertyNames(target).filter(name => names.indexOf(name) === -1);\n names = names.concat(newNames);\n // go up prototype chain\n target = Object.getPrototypeOf(target);\n }\n\n return names;\n}\n","import {Component, ComponentConfig} from './components/component';\nimport {Container} from './components/container';\n\n/**\n * @category Utils\n */\nexport namespace UIUtils {\n export interface TreeTraversalCallback {\n (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>): void;\n }\n\n export function traverseTree(component: Component<ComponentConfig>, visit: TreeTraversalCallback): void {\n let recursiveTreeWalker = (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>) => {\n visit(component, parent);\n\n // If the current component is a container, visit it's children\n if (component instanceof Container) {\n for (let childComponent of component.getComponents()) {\n recursiveTreeWalker(childComponent, component);\n }\n }\n };\n\n // Walk and configure the component tree\n recursiveTreeWalker(component);\n }\n\n // From: https://github.com/nfriend/ts-keycode-enum/blob/master/Key.enum.ts\n export enum KeyCode {\n LeftArrow = 37,\n UpArrow = 38,\n RightArrow = 39,\n DownArrow = 40,\n Space = 32,\n End = 35,\n Home = 36,\n }\n}\n","import { Event, EventDispatcher } from './eventdispatcher';\nimport { PlayerAPI } from 'bitmovin-player';\n\nexport interface VolumeSettingChangedArgs {\n volume: number;\n muted: boolean;\n}\n\n/**\n * Can be used to centrally manage and control the volume and mute state of the player from multiple components.\n */\nexport class VolumeController {\n\n private static readonly issuerName = 'ui-volumecontroller';\n\n private readonly events = {\n onChanged: new EventDispatcher<VolumeController, VolumeSettingChangedArgs>(),\n };\n\n private storedVolume: number;\n\n constructor(private readonly player: PlayerAPI) {\n this.storeVolume();\n\n const handler = () => {\n this.onChangedEvent();\n };\n\n player.on(player.exports.PlayerEvent.SourceLoaded, handler);\n player.on(player.exports.PlayerEvent.VolumeChanged, handler);\n player.on(player.exports.PlayerEvent.Muted, handler);\n player.on(player.exports.PlayerEvent.Unmuted, handler);\n }\n\n setVolume(volume: number): void {\n this.player.setVolume(volume, VolumeController.issuerName);\n }\n\n getVolume(): number {\n return this.player.getVolume();\n }\n\n setMuted(muted: boolean): void {\n if (muted) {\n this.player.mute(VolumeController.issuerName);\n } else {\n this.player.unmute(VolumeController.issuerName);\n }\n }\n\n toggleMuted(): void {\n if (this.isMuted() || this.getVolume() === 0) {\n // Unmuting from the mute or zero-volume state recalls the previously saved volume setting. Setting the\n // volume automatically unmutes the player in v7.\n this.recallVolume();\n } else {\n this.setMuted(true);\n }\n }\n\n isMuted(): boolean {\n return this.player.isMuted();\n }\n\n /**\n * Stores (saves) the current volume so it can later be restored with {@link recallVolume}.\n */\n storeVolume(): void {\n this.storedVolume = this.getVolume();\n }\n\n /**\n * Recalls (sets) the volume previously stored with {@link storeVolume}.\n */\n recallVolume(): void {\n this.setMuted(this.storedVolume === 0);\n this.setVolume(this.storedVolume);\n }\n\n startTransition(): VolumeTransition {\n return new VolumeTransition(this);\n }\n\n onChangedEvent() {\n const playerMuted = this.isMuted();\n const playerVolume = this.getVolume();\n\n const uiMuted = playerMuted || playerVolume === 0;\n const uiVolume = playerMuted ? 0 : playerVolume;\n\n this.storeVolume();\n\n this.events.onChanged.dispatch(this, { volume: uiVolume, muted: uiMuted });\n }\n\n /**\n * Gets the event that is fired when the volume settings have changed.\n */\n get onChanged(): Event<VolumeController, VolumeSettingChangedArgs> {\n return this.events.onChanged.getEvent();\n }\n}\n\nexport class VolumeTransition {\n\n constructor(private controller: VolumeController) {\n // Store the volume at the beginning of a volume change so we can recall it later in case we set the volume to\n // zero and actually mute the player.\n controller.storeVolume();\n }\n\n update(volume: number): void {\n // Update the volume while transitioning so the user has a \"live preview\" of the desired target volume\n this.controller.setMuted(false);\n this.controller.setVolume(volume);\n }\n\n finish(volume: number): void {\n if (volume === 0) {\n // When the volume is zero we essentially mute the volume so we recall the volume from the beginning of the\n // transition and mute the player instead. Recalling is necessary to return to the actual audio volume\n // when unmuting.\n // We must first recall the volume and then mute, because recalling sets the volume on the player\n // and setting a player volume > 0 unmutes the player in v7.\n this.controller.recallVolume();\n this.controller.setMuted(true);\n } else {\n this.controller.setMuted(false);\n this.controller.setVolume(volume);\n this.controller.storeVolume();\n }\n }\n}","import { SubtitleRegionContainer, SubtitleLabel } from './components/subtitleoverlay';\nimport { VTTProperties, VTTRegionProperties } from 'bitmovin-player/types/subtitles/vtt/API';\nimport { DOM, Size } from './dom';\n\n// Our default height of a line\nconst lineHeight = 28;\n\n// Default relative line height\nconst lineHeightPercent = 5;\nlet lineCount: number = 1;\n\nconst defaultLineNumber = 21; // Our default amount of lines\n\nenum Direction {\n Top = 'top',\n Bottom = 'bottom',\n Left = 'left',\n Right = 'right',\n}\n\nenum VttVerticalWriting {\n GrowingRight = 'lr',\n GrowingLeft = 'rl',\n}\n\ntype VerticalWritingDirection = Direction.Left | Direction.Right;\n\nconst DirectionPair = new Map<Direction, Direction>([\n [Direction.Top, Direction.Bottom],\n [Direction.Bottom, Direction.Top],\n [Direction.Left, Direction.Right],\n [Direction.Right, Direction.Left],\n]);\n\n/**\n * Sets the default standardized styles for the Cue Box\n * https://w3.org/TR/webvtt1/#applying-css-properties\n */\nconst setDefaultVttStyles = (cueContainerDom: DOM, vtt: VTTProperties) => {\n if (vtt.region) {\n cueContainerDom.css('position', 'relative');\n cueContainerDom.css('unicode-bidi', 'plaintext');\n } else {\n cueContainerDom.css('position', 'absolute');\n cueContainerDom.css('overflow-wrap', 'break-word');\n cueContainerDom.css('overflow', 'hidden');\n cueContainerDom.css('flex-flow', 'column');\n }\n cueContainerDom.css('display', 'inline-flex');\n};\n\n/**\n * Align the Cue Box's line\n * https://w3.org/TR/webvtt1/#webvtt-cue-line-alignment\n */\nconst setVttLineAlign = (\n cueContainerDom: DOM,\n { lineAlign }: VTTProperties,\n direction: Direction,\n relativeCueBoxPosition: number) => {\n switch (lineAlign) {\n case 'center':\n setCssForCenterLineAlign(\n cueContainerDom, direction, relativeCueBoxPosition);\n break;\n case 'end':\n setCssForEndLineAlign(\n cueContainerDom, direction, relativeCueBoxPosition);\n }\n};\n\n/**\n * Defines the line positioning of the Cue Box\n * https://w3.org/TR/webvtt1/#webvtt-cue-line\n */\nconst setVttLine = (\n cueContainerDom: DOM,\n vtt: VTTProperties,\n direction: Direction,\n subtitleOverLaySize: Size,\n) => {\n const overlayReferenceEdge = DirectionPair.get(direction);\n if (vtt.line === 'auto' && vtt.vertical) {\n cueContainerDom.css(overlayReferenceEdge, '0');\n return;\n }\n if (vtt.line === 'auto' && !vtt.vertical) {\n return;\n }\n\n let relativeLinePosition = parseFloat(vtt.line as string);\n\n if (vtt.snapToLines) {\n let targetLine = Number(vtt.line);\n if (targetLine < 0) {\n targetLine = defaultLineNumber + targetLine;\n }\n\n const lineHeight = subtitleOverLaySize.height / defaultLineNumber;\n const absoluteLinePosition = lineHeight * targetLine;\n relativeLinePosition = (100 * absoluteLinePosition) / subtitleOverLaySize.height;\n }\n\n if (vtt.lineAlign !== 'end')\n cueContainerDom.css(\n overlayReferenceEdge, `${relativeLinePosition}%`);\n setVttLineAlign(cueContainerDom, vtt, direction, relativeLinePosition);\n};\n\n/**\n * Defines the writing direction of the Cue Box\n * https://w3.org/TR/webvtt1/#webvtt-cue-writing-direction\n */\nconst setVttWritingDirectionAndCueBoxPositioning = (\n cueContainerDom: DOM, vtt: VTTProperties,\n subtitleOverlaySize: Size,\n) => {\n switch (vtt.vertical) {\n case '':\n cueContainerDom.css('writing-mode', 'horizontal-tb');\n cueContainerDom.css(Direction.Bottom, '0');\n setVttLine(cueContainerDom, vtt, Direction.Bottom, subtitleOverlaySize);\n break;\n case VttVerticalWriting.GrowingRight:\n setCueBoxPositionForVerticalWriting(\n cueContainerDom, Direction.Right, vtt, subtitleOverlaySize);\n break;\n case VttVerticalWriting.GrowingLeft:\n setCueBoxPositionForVerticalWriting(\n cueContainerDom, Direction.Left, vtt, subtitleOverlaySize);\n break;\n }\n};\n\nconst setCueBoxPositionForVerticalWriting = (\n cueContainerDom: DOM,\n direction: VerticalWritingDirection,\n vtt: VTTProperties,\n subtitleOverlaySize: Size,\n) => {\n const writingMode = direction === Direction.Right ?\n 'vertical-lr' : 'vertical-rl';\n\n cueContainerDom.css('writing-mode', writingMode);\n cueContainerDom.css(Direction.Top, '0');\n setVttLine(cueContainerDom, vtt, direction, subtitleOverlaySize);\n};\n\n/**\n * Defines the Cue position alignment\n * https://w3.org/TR/webvtt1/#webvtt-cue-position-alignment\n */\nconst setVttPositionAlign = (cueContainerDom: DOM, vtt: VTTProperties, direction: Direction) => {\n // https://www.w3.org/TR/webvtt1/#webvtt-cue-position\n if (vtt.position === 'auto') {\n cueContainerDom.css(direction, '0');\n } else {\n switch (vtt.positionAlign) {\n case 'line-left':\n cueContainerDom.css(direction, `${vtt.position}%`);\n cueContainerDom.css(DirectionPair.get(direction), 'auto');\n cueContainerDom.css('justify-content', 'flex-start');\n break;\n case 'center':\n cueContainerDom.css(direction, `${vtt.position - vtt.size / 2}%`);\n cueContainerDom.css(DirectionPair.get(direction), 'auto');\n cueContainerDom.css('justify-content', 'center');\n break;\n case 'line-right':\n cueContainerDom.css(direction, 'auto');\n cueContainerDom.css(DirectionPair.get(direction), `${100 - vtt.position}%`);\n cueContainerDom.css('justify-content', 'flex-end');\n break;\n default:\n cueContainerDom.css(direction, `${vtt.position}%`);\n cueContainerDom.css('justify-content', 'flex-start');\n }\n }\n};\n\nconst countLines = (innerHtml: string) =>\n innerHtml.split('<br />').length;\n\nconst setCssForCenterLineAlign = (\n cueContainerDom: DOM,\n direction: Direction,\n relativeCueBoxPosition: number) => {\n switch (direction) {\n case Direction.Bottom:\n cueContainerDom.css('transform', 'translateY(-50%)');\n break;\n case Direction.Left:\n cueContainerDom.css('transform', 'translateX(50%)');\n break;\n case Direction.Right:\n cueContainerDom.css('transform', 'translateX(-50%)');\n break;\n }\n};\n\nconst setCssForEndLineAlign = (\n cueContainerDom: DOM,\n direction: Direction,\n offset: number) => {\n const opositeToOverlayReferenceEdge = direction;\n cueContainerDom.css(opositeToOverlayReferenceEdge, `${100 - offset}%`);\n};\n\n/**\n * @category Utils\n */\nexport namespace VttUtils {\n export const setVttCueBoxStyles = (\n cueContainer: SubtitleLabel,\n subtitleOverlaySize: Size,\n ) => {\n const vtt = cueContainer.vtt;\n const cueContainerDom = cueContainer.getDomElement();\n\n\n setDefaultVttStyles(cueContainerDom, vtt);\n\n lineCount = countLines(cueContainer.getText());\n setVttWritingDirectionAndCueBoxPositioning(cueContainerDom, vtt, subtitleOverlaySize);\n\n // https://w3.org/TR/webvtt1/#webvtt-cue-text-alignment\n const textAlign = vtt.align === 'middle' ? 'center' : vtt.align;\n cueContainerDom.css('text-align', textAlign);\n\n // https://w3.org/TR/webvtt1/#webvtt-cue-size\n const containerSize = vtt.size;\n if (vtt.vertical === '') {\n cueContainerDom.css('width', `${containerSize}%`);\n setVttPositionAlign(cueContainerDom, vtt, Direction.Left);\n } else {\n cueContainerDom.css('height', `${containerSize}%`);\n setVttPositionAlign(cueContainerDom, vtt, Direction.Top);\n }\n };\n\n /** https://www.w3.org/TR/webvtt1/#regions\n * https://www.speechpad.com/captions/webvtt#toc_16\n */\n export const setVttRegionStyles = (\n regionContainer: SubtitleRegionContainer,\n region: VTTRegionProperties,\n overlaySize: Size,\n ) => {\n const regionContainerDom = regionContainer.getDomElement();\n const regionPositionX = overlaySize.width * region.viewportAnchorX / 100 - ((overlaySize.width * region.width / 100) * region.regionAnchorX / 100);\n const regionPositionY = overlaySize.height * region.viewportAnchorY / 100 - ((region.lines * lineHeight) * region.regionAnchorY / 100);\n regionContainerDom.css('position', 'absolute');\n regionContainerDom.css('overflow', 'hidden');\n regionContainerDom.css('width', `${region.width}%`);\n regionContainerDom.css(Direction.Left, `${regionPositionX}px`);\n regionContainerDom.css(Direction.Right, 'unset');\n regionContainerDom.css(Direction.Top, `${regionPositionY}px`);\n regionContainerDom.css(Direction.Bottom, 'unset');\n regionContainerDom.css('height', `${region.lines * lineHeight}px`);\n };\n}\n"]}