define(["appHeader", "itemShortcuts", "itemContextMenu", "backdrop", "appRouter", "playbackManager", "dom", "inputmanager", "datetime", "itemHelper", "mediaInfo", "focusManager", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "./playqueue", "./tvplayqueue", "Modernizr", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!./videoosd"], function(appHeader, itemShortcuts, itemContextMenu, backdrop, appRouter, playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, OsdPlayQueue, TvPlayQueue, Modernizr) {
	"use strict";

	function seriesImageUrl(item, options) {
		return "Episode" !== item.Type ? null : ((options = options || {}).type = options.type || "Primary", "Primary" === options.type && item.SeriesPrimaryImageTag ? (options.tag = item.SeriesPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options)) : "Thumb" === options.type && item.ParentThumbImageTag ? (options.tag = item.ParentThumbImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options)) : null)
	}
	function imageUrl(item, options) {
		return (options = options || {}).type = options.type || "Primary", item.ImageTags && item.ImageTags[options.type] ? (options.tag = item.ImageTags[options.type], connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options)) : "Primary" === options.type && item.AlbumId && item.AlbumPrimaryImageTag ? (options.tag = item.AlbumPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options)) : null
	}
	function logoImageUrl(item, apiClient, options) {
		return (options = options || {}).type = "Logo", item.ImageTags && item.ImageTags.Logo ? (options.tag = item.ImageTags.Logo, apiClient.getScaledImageUrl(item.Id, options)) : item.ParentLogoImageTag ? (options.tag = item.ParentLogoImageTag, apiClient.getScaledImageUrl(item.ParentLogoItemId, options)) : "TvChannel" === item.Type && item.ImageTags && item.ImageTags.Primary ? (options.tag = item.ImageTags.Primary, options.type = "Primary", apiClient.getScaledImageUrl(item.Id, options)) : null
	}
	function isDisplayingLocalVideo(player, mediaType) {
		return player && player.isLocalPlayer && "Video" === (mediaType || playbackManager.getCurrentMediaType(player))
	}
	function setForwardIcon(btnFastForward) {
		var icon = btnFastForward.querySelector("i");
		switch (icon.innerHTML = function() {
			switch (userSettings.skipForwardLength()) {
			case 5e3:
				return "&#xe058;";
			case 1e4:
				return "&#xe056;";
			case 3e4:
				return "&#xe057;";
			default:
				return "&#xE042;"
			}
		}(), userSettings.skipForwardLength()) {
		case 5e3:
		case 1e4:
		case 3e4:
			break;
		default:
			icon.classList.add("videoOsd-forwardIcon-flipped")
		}
	}
	function setRewindIcon(btnRewind) {
		btnRewind.querySelector("i").innerHTML = function() {
			switch (userSettings.skipBackLength()) {
			case 5e3:
				return "&#xe05b;";
			case 1e4:
				return "&#xe059;";
			case 3e4:
				return "&#xe05a;";
			default:
				return "&#xE042;"
			}
		}()
	}
	function showMoreMenu(item, button) {
		return connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function(user) {
			return itemContextMenu.show(function(item, user, button) {
				return {
					item: item,
					open: !1,
					play: !1,
					playAllFromHere: !1,
					queueAllFromHere: !1,
					positionTo: button,
					cancelTimer: !1,
					record: !1,
					deleteItem: !1,
					shuffle: !1,
					instantMix: !1,
					user: user,
					share: !0,
					queue: !1,
					positionY: "top"
				}
			}(item, user, button)).then(function(result) {
				result.updated
			})
		})
	}
	function hideOrShowAll(elems, hide, focusedElement, btnPlayPause) {
		for (var wasFocused, i = 0, length = elems.length; i < length; i++) {
			var elem = elems[i];
			hide ? (focusedElement && focusedElement === elem && (wasFocused = !0), elem.classList.add("hide")) : elem.classList.remove("hide")
		}
		wasFocused && focusManager.focus(btnPlayPause)
	}
	function getTextActionButton(item, text) {
		text = text || itemHelper.getDisplayName(item);
		var html = "<button " + itemShortcuts.getShortcutAttributesHtml(item, {}) + ' type="button" class="itemAction button-link osdTextActionButton" is="emby-button" data-action="link">';
		return html += text, html += "</button>"
	}
	function getSecondaryName(item, enableLinkButton) {
		var title = itemHelper.getDisplayName(item, {
			includeParentInfo: "Program" !== item.Type,
			includeIndexNumber: "Program" !== item.Type
		});
		return enableLinkButton ? getTextActionButton(item, title) : title
	}
	return function(view, params) {
		var currentPlayer, comingUpNextDisplayed, currentUpNextDialog, isEnabled, currentItem, currentMediaSource, currentItemThumbnails, currentItemThumbnailsPromise, recordingButtonManager, enableProgressByTimeOfDay, enableStopOnBack, enableBackOnStop, lastPointerUpType, playQueue, currentVisibleMenu, statsOverlay, subtitleOffsetOverlay, osdHideTimeout, lastPointerMoveData, supportsTouchEvent = "ontouchstart" in document.documentElement,
			currentPlayerSupportedCommands = [],
			currentRuntimeTicks = 0,
			lastUpdateTime = 0,
			programStartDateMs = 0,
			programEndDateMs = 0,
			playbackStartTimeTicks = 0,
			nowPlayingVolumeSlider = view.querySelector(".videoOsdVolumeSlider"),
			nowPlayingVolumeSliderContainer = view.querySelector(".videoOsdVolumeSliderWrapper"),
			nowPlayingPositionSlider = view.querySelector(".videoOsdPositionSlider"),
			nowPlayingPositionText = view.querySelector(".videoOsdPositionText"),
			nowPlayingDurationText = view.querySelector(".videoOsdDurationText"),
			btnRewind = view.querySelector(".btnRewind"),
			btnRewindIcon = btnRewind.querySelector("i"),
			btnFastForward = view.querySelector(".btnOsdFastForward"),
			btnFastForwardIcon = btnFastForward.querySelector("i"),
			btnPause = view.querySelector(".videoOsd-btnPause"),
			stopButtons = view.querySelectorAll(".btnVideoOsd-stop"),
			btnRepeatMode = view.querySelector(".btnOsdRepeatMode"),
			btnMoreButtons = view.querySelectorAll(".btnOsdMore"),
			btnOsdMoreBottom = view.querySelector(".btnOsdMore-bottom"),
			transitionEndEventName = dom.whichTransitionEvent(),
			headerElement = document.querySelector(".skinHeader"),
			osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols"),
			endsAtText = view.querySelector(".videoOsd-endsAtText"),
			btnFavorite = view.querySelector(".btnOsdFavorite"),
			btnPreviousTrack = view.querySelector(".btnPreviousTrack"),
			btnNextTrack = view.querySelector(".btnNextTrack"),
			buttonMute = view.querySelector(".buttonMute"),
			btnSubtitles = view.querySelector(".btnSubtitles"),
			btnAudio = view.querySelector(".btnAudio"),
			btnFullscreen = view.querySelector(".btnFullscreen"),
			videoOsdSecondaryText = view.querySelector(".videoOsdSecondaryText"),
			videoOsdText = view.querySelector(".videoOsdText"),
			osdButtons = view.querySelector(".videoOsdBottom-buttons"),
			centerButtons = view.querySelector(".videoOsd-centerButtons"),
			videoOsdPositionContainer = view.querySelector(".videoOsdPositionContainer"),
			osdTitle = view.querySelector(".videoOsdTitle"),
			osdParentTitle = view.querySelector(".videoOsdParentTitle"),
			backdropContainer = document.querySelector(".backdropContainer"),
			videoOsdBottomButtonsTvplayqueue = document.querySelector(".videoOsdBottom-buttons-tvplayqueue");

		function enableIconAnimation() {
			return Modernizr.cssanimations
		}
		function rewind(player) {
			"osd" === currentVisibleMenu && enableIconAnimation() && (btnRewindIcon.classList.remove("rew-animate"), btnRewindIcon.offsetWidth, btnRewindIcon.classList.add("rew-animate")), playbackManager.rewind(player)
		}
		function onRewindAnimationComplete(e) {
			e && e.target !== e.currentTarget || this.classList.remove("rew-animate")
		}
		function onFastForwardAnimationComplete(e) {
			e && e.target !== e.currentTarget || this.classList.remove("ff-animate")
		}
		function fastForward(player) {
			"osd" === currentVisibleMenu && enableIconAnimation() && (btnFastForwardIcon.classList.remove("ff-animate"), btnFastForwardIcon.offsetWidth, btnFastForwardIcon.classList.add("ff-animate")), playbackManager.fastForward(player)
		}
		function updateRecordingButton(item) {
			if (!item || "Program" !== item.Type) return recordingButtonManager && (recordingButtonManager.destroy(), recordingButtonManager = null), void view.querySelector(".btnRecord").classList.add("hide");
			connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function(user) {
				user.Policy.EnableLiveTvManagement && require(["recordingButton"], function(RecordingButton) {
					recordingButtonManager ? recordingButtonManager.refreshItem(item) : (recordingButtonManager = new RecordingButton({
						item: item,
						button: view.querySelector(".btnRecord")
					}), view.querySelector(".btnRecord").classList.remove("hide"))
				})
			})
		}
		function updateDisplayItem(itemInfo) {
			var item = itemInfo.originalItem;
			currentItem = item, currentItemThumbnails = currentItemThumbnailsPromise = null;
			var displayItem = itemInfo.displayItem || item;
			updateRecordingButton(displayItem);
			var primaryNameText, displayingLocalVideo = isDisplayingLocalVideo(currentPlayer);
			displayItem.EpisodeTitle || displayItem.IsSeries ? primaryNameText = displayItem.Name : displayItem.SeriesName ? (primaryNameText = displayItem.SeriesName, displayItem.SeriesId && !displayingLocalVideo && (primaryNameHtml = getTextActionButton({
				Id: displayItem.SeriesId,
				Type: "Series",
				IsFolder: !0,
				ServerId: displayItem.ServerId,
				Name: displayItem.SeriesName,
				ParentId: displayItem.ParentId
			}))) : displayItem.Album && (primaryNameText = displayItem.Album, primaryNameHtml = displayItem.AlbumId && !displayingLocalVideo ? getTextActionButton({
				Id: displayItem.AlbumId,
				Type: "MusicAlbum",
				IsFolder: !0,
				ServerId: displayItem.ServerId,
				Name: displayItem.Album,
				ParentId: displayItem.ParentId
			}) : primaryNameText, displayItem.ArtistItems && displayItem.ArtistItems.length && (primaryNameHtml = function(displayItem) {
				var html = [],
					artistItems = displayItem.ArtistItems;
				if (!artistItems) return html;
				for (var i = 0, length = artistItems.length; i < length; i++) html.push(getTextActionButton({
					Id: artistItems[i].Id,
					ServerId: displayItem.ServerId,
					Name: artistItems[i].Name,
					Type: "MusicArtist",
					IsFolder: !0
				}));
				return html
			}(displayItem).join(", ") + " - " + primaryNameHtml)), primaryNameHtml = primaryNameHtml || primaryNameText, function(item, originalItem, title) {
				var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {}) || logoImageUrl(originalItem, connectionManager.getApiClient(originalItem.ServerId), {}); {
					var pageTitle;
					url ? (appHeader.setTitle(""), (pageTitle = document.querySelector(".pageTitle")).style.backgroundImage = "url('" + url + "')", pageTitle.classList.add("pageTitleWithLogo"), pageTitle.classList.remove("pageTitleWithDefaultLogo"), pageTitle.innerHTML = "") : appHeader.setTitle("")
				}
				var documentTitle = title || (item ? item.Name : null);
				documentTitle && (document.title = documentTitle)
			}(displayItem, item, primaryNameText);
			var titleElement, temp, primaryNameHtml, secondaryName, backdropItems = [displayItem];
			item.Id !== displayItem.Id && backdropItems.push(item), displayingLocalVideo ? (backdrop.clear(), setPoster(null), playQueue && playQueue.setBackdropItems([])) : (layoutManager.tv ? (backdrop.setBackdrops(backdropItems), setPoster(null)) : (backdrop.setBackdrops(backdropItems), setPoster(displayItem, item)), playQueue && playQueue.setBackdropItems(backdropItems)), titleElement = osdTitle, secondaryName = "Audio" === item.MediaType ? (temp = primaryNameHtml, primaryNameHtml = secondaryName = getSecondaryName(displayItem, !1), temp) : getSecondaryName(displayItem, !displayingLocalVideo), primaryNameHtml || (primaryNameHtml = secondaryName, secondaryName = null), osdParentTitle.innerHTML = primaryNameHtml, secondaryName || displayItem.Type, (titleElement.innerHTML = secondaryName) ? titleElement.classList.remove("hide") : titleElement.classList.add("hide");
			var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, {
				runtime: !1,
				subtitles: !1,
				endsAt: !1,
				episodeTitle: !1,
				originalAirDate: !1,
				episodeTitleIndexNumber: "Program" !== displayItem.Type,
				programIndicator: !1,
				criticRating: !1,
				communityRating: !1,
				container: !1,
				year: "Video" === displayItem.MediaType
			}),
				osdMediaInfo = view.querySelector(".videoOsdMediaInfo");
			(osdMediaInfo.innerHTML = mediaInfoHtml) ? osdMediaInfo.classList.remove("hide") : osdMediaInfo.classList.add("hide");
			var secondaryMediaInfo = view.querySelector(".videoOsdSecondaryMediaInfo"),
				secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
					startDate: !1,
					programTime: !1
				});
			(secondaryMediaInfo.innerHTML = secondaryMediaInfoHtml) ? secondaryMediaInfo.classList.remove("hide") : secondaryMediaInfo.classList.add("hide"), programEndDateMs = enableProgressByTimeOfDay ? (setDisplayTime(nowPlayingPositionText, displayItem.StartDate), setDisplayTime(nowPlayingDurationText, displayItem.EndDate), programStartDateMs = displayItem.StartDate ? datetime.parseISO8601Date(displayItem.StartDate).getTime() : 0, displayItem.EndDate ? datetime.parseISO8601Date(displayItem.EndDate).getTime() : 0) : programStartDateMs = 0
		}
		function getDisplayTimeWithoutAmPm(date, showSeconds) {
			return showSeconds ? datetime.toLocaleTimeString(date, {
				hour: "numeric",
				minute: "2-digit",
				second: "2-digit"
			}).toLowerCase().replace("am", "").replace("pm", "").trim() : datetime.getDisplayTime(date).toLowerCase().replace("am", "").replace("pm", "").trim()
		}
		function setDisplayTime(elem, date) {
			var html;
			date && (html = getDisplayTimeWithoutAmPm(date = datetime.parseISO8601Date(date))), elem.innerHTML = html || ""
		}
		function supportsSubtitleDownloading(apiClient) {
			return apiClient.isMinServerVersion("4.5.1") && -1 !== currentPlayerSupportedCommands.indexOf("RefreshMediaSource")
		}
		function updateNowPlayingInfo(player, state) {
			var item = state.NowPlayingItem;
			if (currentItemThumbnails = currentItemThumbnailsPromise = null, !(currentItem = item)) return setPoster(currentMediaSource = null), updateRecordingButton(null), appHeader.setTitle(""), nowPlayingVolumeSlider.disabled = !0, nowPlayingPositionSlider.disabled = !0, btnFastForward.disabled = !0, btnRewind.disabled = !0, btnSubtitles.classList.add("hide"), btnAudio.classList.add("hide"), osdTitle.innerHTML = "", view.querySelector(".videoOsdMediaInfo").innerHTML = "", void(endsAtText.innerHTML = "");
			currentMediaSource = state.MediaSource, enableProgressByTimeOfDay = function(item, mediaSource) {
				return !("TvChannel" !== item.Type || !item.CurrentProgram || !mediaSource || mediaSource.RunTimeTicks)
			}(item, state.MediaSource), function(item) {
				if ("TvChannel" !== item.Type) return Promise.resolve({
					originalItem: item
				});
				var apiClient = connectionManager.getApiClient(item.ServerId);
				return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function(refreshedItem) {
					return {
						originalItem: refreshedItem,
						displayItem: refreshedItem.CurrentProgram
					}
				})
			}(item).then(updateDisplayItem), nowPlayingVolumeSlider.disabled = !1, nowPlayingPositionSlider.disabled = !1, btnFastForward.disabled = !1, btnRewind.disabled = !1, 1 < playbackManager.audioTracks(player).length ? btnAudio.classList.remove("hide") : btnAudio.classList.add("hide");
			var apiClient = connectionManager.getApiClient(item);
			apiClient.getCurrentUser().then(function(user) {
				playbackManager.subtitleTracks(player).length || itemHelper.canDownloadSubtitles(user, item) && supportsSubtitleDownloading(apiClient) ? btnSubtitles.classList.remove("hide") : btnSubtitles.classList.add("hide")
			})
		}
		function setPoster(item, secondaryItem) {
			var osdPoster = view.querySelector(".osdPoster-img");
			if (item) {
				var imgUrl = function(item, secondaryItem) {
						var imgUrl = seriesImageUrl(item, {
							type: "Primary"
						}) || seriesImageUrl(item, {
							type: "Thumb"
						}) || imageUrl(item, {
							type: "Primary"
						});
						return !imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, {
							type: "Primary"
						}) || seriesImageUrl(secondaryItem, {
							type: "Thumb"
						}) || imageUrl(secondaryItem, {
							type: "Primary"
						})), imgUrl
					}(item, secondaryItem);
				if (imgUrl) return void(osdPoster ? osdPoster.style.backgroundImage = "url('" + imgUrl + "')" : view.querySelector(".videoOsdBottom-maincontrols").insertAdjacentHTML("afterbegin", '<div class="osdPoster-img" loading="lazy" style="background-image:url(' + imgUrl + ');"></div>'))
			}
			osdPoster &&
			function(elem) {
				try {
					elem.parentNode.removeChild(elem)
				} catch (err) {
					console.log("Error removing poster node: " + err)
				}
			}(osdPoster)
		}
		function showOsd(timeoutMs) {
			headerElement.classList.remove("videoOsdHeader-hidden"), function() {
				if (currentVisibleMenu) return;
				var elem = osdBottomElement;
				currentVisibleMenu = "osd", elem.classList.remove("hide"), elem.offsetWidth, elem.classList.remove("videoOsdBottom-hidden"), focusManager.hasExclusiveFocusScope() || focusManager.focus(btnPause);
				view.dispatchEvent(new CustomEvent("video-osd-show", {
					bubbles: !0
				}))
			}(), function(timeoutMs) {
				if (stopOsdHideTimer(), !isDisplayingLocalVideo(currentPlayer)) return;
				0 !== timeoutMs && (osdHideTimeout = setTimeout(hideOsd, timeoutMs || 4e3))
			}(timeoutMs)
		}
		function hideOsd() {
			isDisplayingLocalVideo(currentPlayer) && (headerElement.classList.add("videoOsdHeader-hidden"), function() {
				if ("osd" !== currentVisibleMenu) return;
				osdBottomElement.offsetWidth, osdBottomElement.classList.add("videoOsdBottom-hidden"), currentVisibleMenu = null
			}())
		}
		function stopOsdHideTimer() {
			osdHideTimeout && (clearTimeout(osdHideTimeout), osdHideTimeout = null)
		}
		function onPointerMove(e) {
			var pointerType = e.pointerType;
			if ("touch" !== pointerType && (pointerType || !supportsTouchEvent)) {
				var eventX = e.screenX || 0,
					eventY = e.screenY || 0,
					obj = lastPointerMoveData;
				if (!obj) return lastPointerMoveData = {
					x: eventX,
					y: eventY
				}, void showOsd();
				Math.abs(eventX - obj.x) < 10 && Math.abs(eventY - obj.y) < 10 || (obj.x = eventX, obj.y = eventY, showOsd())
			}
		}
		function onInputCommand(e) {
			var btnRecord;
			if (!playQueue || !playQueue.onInputCommand(e)) switch (e.detail.command) {
			case "back":
				!playQueue && layoutManager.tv && "osd" === currentVisibleMenu && isDisplayingLocalVideo(currentPlayer) && !focusManager.hasExclusiveFocusScope() && (e.preventDefault(), hideOsd());
				break;
			case "left":
				currentVisibleMenu ? showOsd() : currentVisibleMenu || (e.preventDefault(), rewind(currentPlayer));
				break;
			case "right":
				currentVisibleMenu ? showOsd() : currentVisibleMenu || (e.preventDefault(), fastForward(currentPlayer));
				break;
			case "pagedown":
				playbackManager.nextChapter(currentPlayer);
				break;
			case "pageup":
				playbackManager.previousChapter(currentPlayer);
				break;
			case "up":
			case "down":
			case "select":
			case "menu":
			case "info":
			case "play":
			case "playpause":
			case "pause":
			case "fastforward":
			case "rewind":
			case "next":
			case "previous":
				showOsd();
				break;
			case "record":
				showOsd(), (btnRecord = view.querySelector(".btnRecord")).classList.contains("hide") || btnRecord.click();
				break;
			case "togglestats":
				toggleStats();
				break;
			case "movies":
			case "music":
			case "tv":
			case "settings":
			case "nowplaying":
			case "search":
			case "favorites":
			case "livetv":
			case "recordedtv":
			case "guide":
				e.preventDefault()
			}
		}
		function updateFullscreenIcon() {
			playbackManager.isFullscreen(currentPlayer) ? (btnFullscreen.setAttribute("title", globalize.translate("ExitFullscreen")), btnFullscreen.querySelector("i").innerHTML = "&#xE5D1;") : (btnFullscreen.setAttribute("title", globalize.translate("Fullscreen")), btnFullscreen.querySelector("i").innerHTML = "&#xE5D0;")
		}
		function onPlaylistExpanded() {
			osdBottomElement.classList.add("videoOsdBottom-playlistexpanded")
		}
		function onPlaylistCollapsed() {
			osdBottomElement.classList.remove("videoOsdBottom-playlistexpanded")
		}
		function updateTransparency(player, mediaType) {
			var isLocalVideo = isDisplayingLocalVideo(player, mediaType);
			enableBackOnStop = isLocalVideo ? (currentVisibleMenu || (headerElement.classList.add("videoOsdHeader-hidden"), osdBottomElement.classList.add("hide"), osdBottomElement.classList.add("videoOsdBottom-hidden")), headerElement.classList.remove("videoOsdHeader-remotecontrol"), backdropContainer.classList.remove("backdropContainer-remotecontrol"), osdBottomElement.classList.add("videoOsdBottom-video"), videoOsdSecondaryText.classList.add("videoOsdSecondaryText-video"), videoOsdSecondaryText.classList.remove("videoOsdSecondaryText-remotecontrol"), appRouter.setTransparency("full"), hideOrShowAll(stopButtons, !0), videoOsdText.classList.remove("videoOsdText-remotecontrol"), videoOsdText.classList.remove("hide"), btnOsdMoreBottom.classList.remove("hide"), videoOsdBottomButtonsTvplayqueue.classList.add("hide"), osdButtons.classList.remove("videoOsdBottom-buttons-remotecontrol"), osdBottomElement.classList.remove("videoOsdBottom-remotecontrol"), osdTitle.classList.remove("osdTitle-remotecontrol"), osdTitle.classList.remove("secondaryText"), videoOsdPositionContainer.classList.remove("videoOsd-customFont-remotecontrol"), osdButtons.classList.remove("videoOsd-customFont-remotecontrol"), headerElement.classList.remove("videoOsd-customFont-remotecontrol"), enableStopOnBack = !0) : (osdTitle.classList.add("secondaryText"), osdBottomElement.classList.remove("videoOsdBottom-video"), osdBottomElement.classList.remove("videoOsdBottom-hidden"), osdBottomElement.classList.remove("hide"), showOsd(), layoutManager.tv ? (headerElement.classList.remove("videoOsdHeader-remotecontrol"), backdropContainer.classList.remove("backdropContainer-remotecontrol"), videoOsdText.classList.add("hide"), videoOsdText.classList.remove("videoOsdText-remotecontrol"), btnOsdMoreBottom.classList.add("hide"), videoOsdBottomButtonsTvplayqueue.classList.remove("hide"), osdTitle.classList.remove("osdTitle-remotecontrol"), osdBottomElement.classList.remove("videoOsdBottom-remotecontrol"), videoOsdSecondaryText.classList.remove("videoOsdSecondaryText-remotecontrol"), osdButtons.classList.remove("videoOsdBottom-buttons-remotecontrol"), videoOsdPositionContainer.classList.remove("videoOsd-customFont-remotecontrol"), osdButtons.classList.remove("videoOsd-customFont-remotecontrol"), headerElement.classList.remove("videoOsd-customFont-remotecontrol")) : (headerElement.classList.add("videoOsdHeader-remotecontrol"), backdropContainer.classList.add("backdropContainer-remotecontrol"), videoOsdText.classList.remove("hide"), videoOsdText.classList.add("videoOsdText-remotecontrol"), btnOsdMoreBottom.classList.remove("hide"), videoOsdBottomButtonsTvplayqueue.classList.add("hide"), osdTitle.classList.add("osdTitle-remotecontrol"), osdBottomElement.classList.add("videoOsdBottom-remotecontrol"), videoOsdSecondaryText.classList.add("videoOsdSecondaryText-remotecontrol"), osdButtons.classList.add("videoOsdBottom-buttons-remotecontrol"), videoOsdPositionContainer.classList.add("videoOsd-customFont-remotecontrol"), osdButtons.classList.add("videoOsd-customFont-remotecontrol"), headerElement.classList.add("videoOsd-customFont-remotecontrol")), appRouter.setTransparency(0), hideOrShowAll(stopButtons, !1), !(enableStopOnBack = !1)), isLocalVideo ? destroyPlayQueue() : layoutManager.tv ? playQueue = playQueue || new TvPlayQueue({
				parent: view.querySelector(".tvPlayQueue")
			}) : playQueue || (playQueue = new OsdPlayQueue({
				parent: view.querySelector(".osdPlayQueue"),
				toggleBar: !0
			}), events.on(playQueue, "playlistexpanded", onPlaylistExpanded), events.on(playQueue, "playlistcollapsed", onPlaylistCollapsed)), isLocalVideo && !layoutManager.tv ? (centerButtons.classList.add("videoOsd-centerButtons-autolayout"), btnPause.classList.add("videoOsd-btnPause-autolayout"), stopButtons[0].classList.add("btnVideoOsd-stop-center-autolayout"), stopButtons[1].classList.add("btnVideoOsd-stop-bottom-autolayout")) : (centerButtons.classList.remove("videoOsd-centerButtons-autolayout"), btnPause.classList.remove("videoOsd-btnPause-autolayout"), stopButtons[0].classList.remove("btnVideoOsd-stop-center-autolayout"), stopButtons[1].classList.remove("btnVideoOsd-stop-bottom-autolayout"))
		}
		function onPlayerChange(e, player) {
			bindToPlayer(player)
		}
		function onStateChanged(event, state) {
			state.NowPlayingItem && (isEnabled = !0, function(player, state) {
				var playState = state.PlayState || {};
				updatePlayPauseState(playState.IsPaused);
				var supportedCommands = playbackManager.getSupportedCommands(player);
				currentPlayerSupportedCommands = supportedCommands, updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel), nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging && (nowPlayingPositionSlider.disabled = !playState.CanSeek);
				btnFastForward.disabled = !playState.CanSeek, btnRewind.disabled = !playState.CanSeek;
				var nowPlayingItem = state.NowPlayingItem || {};
				updateTransparency(player, nowPlayingItem.MediaType), updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playbackStartTimeTicks = playState.PlaybackStartTimeTicks, playState.BufferedRanges || []), updateNowPlayingInfo(player, state);
				var focusedElement = document.activeElement;
				state.MediaSource && "Video" === nowPlayingItem.MediaType ? view.querySelector(".btnVideoOsdSettings").classList.remove("hide") : hideButton(view.querySelector(".btnVideoOsdSettings"), focusedElement);
				var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
				nowPlayingPositionSlider.setIsClear(isProgressClear), !supportedCommands.includes("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player) ? hideButton(btnFullscreen, focusedElement) : btnFullscreen.classList.remove("hide");
				supportedCommands.includes("PictureInPicture") ? view.querySelector(".btnPip").classList.remove("hide") : hideButton(view.querySelector(".btnPip"), focusedElement);
				updateRepeatModeDisplay(playState.RepeatMode), supportedCommands.includes("SetRepeatMode") && "Video" !== nowPlayingItem.MediaType ? btnRepeatMode.classList.remove("hide") : hideButton(btnRepeatMode, focusedElement);
				var displayingLocalVideo = isDisplayingLocalVideo(player, nowPlayingItem.MediaType);
				displayingLocalVideo ? hideOrShowAll(btnMoreButtons, !0, focusedElement, btnPause) : hideOrShowAll(btnMoreButtons, !1);
				updateFullscreenIcon(), btnFavorite.setItem(nowPlayingItem), !displayingLocalVideo && itemHelper.canRate(nowPlayingItem) && "TvChannel" !== nowPlayingItem.Type ? btnFavorite.classList.remove("hide") : hideButton(btnFavorite, focusedElement);
				var playlistIndex = state.PlaylistIndex,
					playlistLength = state.PlaylistLength; {
					var playlistItemId;
					updatePlaylistButtons(playlistIndex, playlistLength, focusedElement), playQueue && (playlistItemId = state.PlaylistItemId, playQueue.updatePlaylist(player, playlistItemId, playlistIndex, playlistLength))
				}
			}(this, state))
		}
		function onPlayPauseStateChanged(e) {
			isEnabled && updatePlayPauseState(this.paused())
		}
		function onVolumeChanged(e) {
			isEnabled && updatePlayerVolumeState(this, this.isMuted(), this.getVolume())
		}
		function onPlaybackStart(e, state) {
			console.log("nowplaying event: " + e.type);
			onStateChanged.call(this, e, state), setTimeout(resetUpNextDialog, 300)
		}
		function onRepeatModeChange(e) {
			updateRepeatModeDisplay(playbackManager.getRepeatMode(this))
		}
		function onSubtitleTrackChange() {
			destroySubtitleOffsetOverlay()
		}
		function onPlaylistItemAdd(e) {
			var playlistItemId, playlistIndex = playbackManager.getCurrentPlaylistIndex(this),
				playlistLength = playbackManager.getCurrentPlaylistLength(this);
			updatePlaylistButtons(playlistIndex, playlistLength, document.activeElement), playQueue && (playlistItemId = playbackManager.getCurrentPlaylistItemId(this), playQueue.updatePlaylist(this, playlistItemId, playlistIndex, playlistLength))
		}
		function onPlaylistItemMove(e, info) {
			updatePlaylistButtons(playbackManager.getCurrentPlaylistIndex(this), playbackManager.getCurrentPlaylistLength(this), document.activeElement), playQueue && playQueue.onPlaylistItemMoved(this, e, info)
		}
		function onPlaylistItemRemove(e, info) {
			updatePlaylistButtons(playbackManager.getCurrentPlaylistIndex(this), playbackManager.getCurrentPlaylistLength(this), document.activeElement), playQueue && playQueue.onPlaylistItemRemoved(this, e, info)
		}
		function resetUpNextDialog() {
			comingUpNextDisplayed = !1;
			currentUpNextDialog && (currentUpNextDialog.destroy(), currentUpNextDialog = null)
		}
		function onPlaybackStopped(e, state) {
			currentRuntimeTicks = null, resetUpNextDialog(), console.log("nowplaying event: " + e.type), state.NextMediaType || (playQueue && playQueue.onPlaybackStopped(), enableStopOnBack = !1, enableBackOnStop && (enableBackOnStop = !1, appRouter.back()))
		}
		function onMediaStreamsChanged(e) {
			var state = playbackManager.getPlayerState(this);
			onStateChanged.call(this, {
				type: "init"
			}, state)
		}
		function bindToPlayer(player) {
			var state;
			player !== currentPlayer && (releaseCurrentPlayer(), (currentPlayer = player) && (state = playbackManager.getPlayerState(player), onStateChanged.call(player, {
				type: "init"
			}, state), events.on(player, "playbackstart", onPlaybackStart), events.on(player, "playbackstop", onPlaybackStopped), events.on(player, "volumechange", onVolumeChanged), events.on(player, "pause", onPlayPauseStateChanged), events.on(player, "unpause", onPlayPauseStateChanged), events.on(player, "timeupdate", onTimeUpdate), events.on(player, "fullscreenchange", updateFullscreenIcon), events.on(player, "mediastreamschange", onMediaStreamsChanged), events.on(player, "statechange", onStateChanged), events.on(player, "repeatmodechange", onRepeatModeChange), events.on(player, "subtitletrackchange", onSubtitleTrackChange), events.on(player, "playlistitemadd", onPlaylistItemAdd), events.on(player, "playlistitemmove", onPlaylistItemMove), events.on(player, "playlistitemremove", onPlaylistItemRemove), resetUpNextDialog()))
		}
		function releaseCurrentPlayer() {
			destroyStats(), destroySubtitleOffsetOverlay(), resetUpNextDialog();
			var player = currentPlayer;
			player && (events.off(player, "playbackstart", onPlaybackStart), events.off(player, "playbackstop", onPlaybackStopped), events.off(player, "volumechange", onVolumeChanged), events.off(player, "pause", onPlayPauseStateChanged), events.off(player, "unpause", onPlayPauseStateChanged), events.off(player, "timeupdate", onTimeUpdate), events.off(player, "fullscreenchange", updateFullscreenIcon), events.off(player, "mediastreamschange", onMediaStreamsChanged), events.off(player, "statechange", onStateChanged), events.off(player, "repeatmodechange", onRepeatModeChange), events.off(player, "subtitletrackchange", onSubtitleTrackChange), events.off(player, "playlistitemadd", onPlaylistItemAdd), events.off(player, "playlistitemmove", onPlaylistItemMove), events.off(player, "playlistitemremove", onPlaylistItemRemove), currentPlayer = null)
		}
		function onTimeUpdate(e) {
			var now, currentTime, item;
			isEnabled && ((now = Date.now()) - lastUpdateTime < 700 || (lastUpdateTime = now, currentRuntimeTicks = playbackManager.duration(this), updateTimeDisplay(currentTime = playbackManager.currentTime(this), currentRuntimeTicks, playbackManager.playbackStartTime(this), playbackManager.getBufferedRanges(this)), function(player, item) {
				if ("TvChannel" !== item.Type) return;
				var program = item.CurrentProgram;
				if (!program || !program.EndDate) return;
				try {
					var state, endDate = datetime.parseISO8601Date(program.EndDate);
					Date.now() >= endDate.getTime() && (console.log("program info needs to be refreshed"), state = playbackManager.getPlayerState(player), onStateChanged.call(player, {
						type: "init"
					}, state))
				} catch (e) {
					console.log("Error parsing date: " + program.EndDate)
				}
			}(this, item = currentItem), function(player, currentItem, currentTimeTicks, runtimeTicks) {
				{
					var timeRemainingTicks;
					runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && "Episode" === currentItem.Type && userSettings.enableNextVideoInfoOverlay() && (timeRemainingTicks = runtimeTicks - currentTimeTicks, runtimeTicks - 1e3 * (3e10 <= runtimeTicks ? 40 : 24e9 <= runtimeTicks ? 35 : 30) * 1e4 <= currentTimeTicks && 6e9 <= runtimeTicks && 2e8 <= timeRemainingTicks &&
					function(player) {
						require(["upNextDialog"], function(UpNextDialog) {
							currentVisibleMenu || currentUpNextDialog || (currentVisibleMenu = "upnext", comingUpNextDisplayed = !0, playbackManager.nextItem(player).then(function(nextItem) {
								currentUpNextDialog = new UpNextDialog({
									parent: view.querySelector(".upNextContainer"),
									player: player,
									nextItem: nextItem
								}), events.on(currentUpNextDialog, "hide", onUpNextHidden)
							}, onUpNextHidden))
						})
					}(player))
				}
			}(this, item, currentTime, currentRuntimeTicks)))
		}
		function onUpNextHidden() {
			"upnext" === currentVisibleMenu && (currentVisibleMenu = null)
		}
		function updatePlayPauseState(isPaused) {
			isPaused ? (btnPause.querySelector("i").innerHTML = "&#xE037;", btnPause.title = globalize.translate("Play")) : (btnPause.querySelector("i").innerHTML = "&#xE034;", btnPause.title = globalize.translate("Pause")), playQueue && playQueue.setPausedState(isPaused)
		}
		function hideButton(btn, focusedElement) {
			var isFocused = btn === focusedElement;
			btn.classList.add("hide"), isFocused && focusManager.focus(btnPause)
		}
		function updatePlaylistButtons(playlistIndex, playlistLength, focusedElement) {
			playlistIndex ? btnPreviousTrack.classList.remove("hide") : hideButton(btnPreviousTrack, focusedElement), null != playlistIndex && playlistLength && playlistIndex < playlistLength - 1 ? btnNextTrack.classList.remove("hide") : hideButton(btnNextTrack, focusedElement)
		}
		function updateRepeatModeDisplay(repeatMode) {
			"RepeatAll" === repeatMode ? (btnRepeatMode.querySelector("i").innerHTML = "&#xE040;", btnRepeatMode.classList.add("repeatButton-active")) : "RepeatOne" === repeatMode ? (btnRepeatMode.querySelector("i").innerHTML = "&#xE041;", btnRepeatMode.classList.add("repeatButton-active")) : (btnRepeatMode.querySelector("i").innerHTML = "&#xE040;", btnRepeatMode.classList.remove("repeatButton-active"))
		}
		function getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs) {
			return (currentTimeMs - programStartDateMs) / programRuntimeMs * 100
		}
		function updateTimeDisplay(positionTicks, runtimeTicks, playbackStartTimeTicks, bufferedRanges) {
			var currentTimeMs, programRuntimeMs, rangeStart, rangeEnd, pct;
			enableProgressByTimeOfDay ? (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging && (programStartDateMs && programEndDateMs ? (currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4, programRuntimeMs = programEndDateMs - programStartDateMs, nowPlayingPositionSlider.value = (currentTimeMs - programStartDateMs) / programRuntimeMs * 100, bufferedRanges.length ? (rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4), rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4), nowPlayingPositionSlider.setBufferedRanges([{
				start: rangeStart,
				end: rangeEnd
			}])) : nowPlayingPositionSlider.setBufferedRanges([])) : (nowPlayingPositionSlider.value = 0, nowPlayingPositionSlider.setBufferedRanges([]))), endsAtText.innerHTML = "") : (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging && (runtimeTicks ? (pct = positionTicks / runtimeTicks, pct *= 100, nowPlayingPositionSlider.value = pct) : nowPlayingPositionSlider.value = 0, runtimeTicks && null != positionTicks && currentRuntimeTicks && !enableProgressByTimeOfDay && runtimeTicks && "Video" === currentItem.MediaType && currentMediaSource && currentMediaSource.RunTimeTicks ? endsAtText.innerHTML = mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, !0) : endsAtText.innerHTML = ""), nowPlayingPositionSlider && nowPlayingPositionSlider.setBufferedRanges(bufferedRanges, runtimeTicks, positionTicks), updateTimeText(nowPlayingPositionText, positionTicks), updateTimeText(nowPlayingDurationText, runtimeTicks - positionTicks))
		}
		function updatePlayerVolumeState(player, isMuted, volumeLevel) {
			var supportedCommands = currentPlayerSupportedCommands,
				showMuteButton = !0,
				showVolumeSlider = !0;
			supportedCommands.includes("Mute") || (showMuteButton = !1), supportedCommands.includes("SetVolume") || (showVolumeSlider = !1), player.isLocalPlayer && appHost.supports("physicalvolumecontrol") && (showVolumeSlider = showMuteButton = !1), isMuted ? (buttonMute.setAttribute("title", globalize.translate("Unmute")), buttonMute.querySelector("i").innerHTML = "&#xE04F;") : (buttonMute.setAttribute("title", globalize.translate("Mute")), buttonMute.querySelector("i").innerHTML = "&#xE050;"), showMuteButton ? buttonMute.classList.remove("hide") : buttonMute.classList.add("hide"), nowPlayingVolumeSlider && (showVolumeSlider ? nowPlayingVolumeSliderContainer.classList.remove("hide") : nowPlayingVolumeSliderContainer.classList.add("hide"), nowPlayingVolumeSlider.dragging || (nowPlayingVolumeSlider.value = volumeLevel || 0))
		}
		function updateTimeText(elem, ticks, dash) {
			var html;
			null != ticks ? (html = datetime.getDisplayRunningTime(ticks), dash && (html = "-" + html), elem.innerHTML = html) : elem.innerHTML = ""
		}
		function onSettingsOption(selectedOption) {
			"stats" === selectedOption ? toggleStats() : "subtitleoffset" === selectedOption && require(["subtitleOffsetOverlay"], function(SubtitleOffsetOverlay) {
				currentPlayer && (subtitleOffsetOverlay = subtitleOffsetOverlay || new SubtitleOffsetOverlay({
					player: currentPlayer
				})).show()
			})
		}
		function onStatsClosed() {
			"osd" === currentVisibleMenu && focusManager.focus(view.querySelector(".btnVideoOsdSettings"))
		}
		function toggleStats() {
			require(["playerStats"], function(PlayerStats) {
				var player = currentPlayer;
				player && (statsOverlay ? statsOverlay.toggle() : (statsOverlay = new PlayerStats({
					player: player
				}), events.on(statsOverlay, "close", onStatsClosed)))
			})
		}
		function destroyStats() {
			statsOverlay && (statsOverlay.destroy(), statsOverlay = null)
		}
		function destroySubtitleOffsetOverlay() {
			subtitleOffsetOverlay && (subtitleOffsetOverlay.destroy(), subtitleOffsetOverlay = null)
		}
		function destroyPlayQueue() {
			playQueue && (playQueue.destroy(), playQueue = null)
		}
		function onWindowKeyDown(e) {
			var keyCode = e.keyCode;
			if (32 !== keyCode && 13 !== keyCode) switch (e.key) {
			case "b":
			case "B":
				if (e.ctrlKey) return e.shiftKey ? (e.preventDefault(), void rewind(currentPlayer)) : (e.preventDefault(), void playbackManager.previousChapter(currentPlayer));
				break;
			case "f":
			case "F":
				if (e.ctrlKey) return e.shiftKey ? (e.preventDefault(), void fastForward(currentPlayer)) : (e.preventDefault(), void playbackManager.nextChapter(currentPlayer));
				playbackManager.toggleFullscreen(currentPlayer);
				break;
			case "m":
			case "M":
				playbackManager.toggleMute(currentPlayer)
			} else currentVisibleMenu ? showOsd() : e.target.closest("BUTTON") || (playbackManager.playPause(currentPlayer), setTimeout(showOsd, 100), browser.edge && (e.preventDefault(), e.stopPropagation()))
		}
		layoutManager.tv || (videoOsdPositionContainer.classList.add("videoOsd-customFont"), osdButtons.classList.add("videoOsd-customFont"), videoOsdText.classList.add("videoOsdText-customFont")), setRewindIcon(btnRewind), setForwardIcon(btnFastForward), dom.addEventListener(btnRewindIcon, dom.whichAnimationEvent(), onRewindAnimationComplete, {
			passive: !0
		}), dom.addEventListener(btnRewindIcon, dom.whichAnimationCancelEvent(), onRewindAnimationComplete, {
			passive: !0
		}), dom.addEventListener(btnFastForwardIcon, dom.whichAnimationEvent(), onFastForwardAnimationComplete, {
			passive: !0
		}), dom.addEventListener(btnFastForwardIcon, dom.whichAnimationCancelEvent(), onFastForwardAnimationComplete, {
			passive: !0
		}), view.addEventListener("viewbeforeshow", function(e) {
			headerElement.classList.add("videoOsdHeader"), layoutManager.tv || headerElement.classList.add("videoOsd-customFont")
		}), view.addEventListener("viewshow", function(e) {
			events.on(playbackManager, "playerchange", onPlayerChange), bindToPlayer(playbackManager.getCurrentPlayer()), currentPlayer && updateTransparency(currentPlayer), dom.addEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, {
				passive: !0
			}), params.controls ? showOsd(0) : function(view) {
				var activeElement = document.activeElement;
				if (activeElement && !view.contains(activeElement)) try {
					activeElement.blur()
				} catch (err) {
					console.log("Error blurring element from previous view: " + err)
				}
			}(view), inputManager.on(window, onInputCommand), dom.addEventListener(window, "keydown", onWindowKeyDown, {})
		}), view.addEventListener("viewbeforehide", function() {
			var player;
			statsOverlay && statsOverlay.enabled(!1), subtitleOffsetOverlay && destroySubtitleOffsetOverlay(), dom.removeEventListener(window, "keydown", onWindowKeyDown, {}), stopOsdHideTimer(), headerElement.classList.remove("videoOsdHeader"), headerElement.classList.remove("videoOsdHeader-hidden"), headerElement.classList.remove("videoOsd-customFont"), headerElement.classList.remove("videoOsd-customFont-remotecontrol"), headerElement.classList.remove("videoOsdHeader-remotecontrol"), backdropContainer.classList.remove("backdropContainer-remotecontrol"), dom.removeEventListener(document, window.PointerEvent ? "pointermove" : "mousemove", onPointerMove, {
				passive: !0
			}), inputManager.off(window, onInputCommand), events.off(playbackManager, "playerchange", onPlayerChange), enableStopOnBack && (enableBackOnStop = enableStopOnBack = !1, (player = currentPlayer) && playbackManager.isPlayingVideo(player) && playbackManager.stop(player)), releaseCurrentPlayer()
		}), dom.addEventListener(btnFullscreen, "click", function() {
			playbackManager.toggleFullscreen(currentPlayer)
		}, {
			passive: !0
		}), view.querySelector(".btnPip").addEventListener("click", function() {
			playbackManager.togglePictureInPicture(currentPlayer)
		}), view.querySelector(".btnVideoOsdSettings").addEventListener("click", function(e) {
			var btn = this;
			require(["playerSettingsMenu"], function(playerSettingsMenu) {
				currentPlayer && playerSettingsMenu.show({
					player: currentPlayer,
					positionTo: btn,
					stats: !0,
					onOption: onSettingsOption,
					mediaType: currentItem.MediaType
				})
			})
		}), view.addEventListener("viewdestroy", function() {
			itemShortcuts.off(videoOsdText), destroyPlayQueue(), recordingButtonManager && (recordingButtonManager.destroy(), recordingButtonManager = null), destroyStats(), destroySubtitleOffsetOverlay()
		});
		var lastPointerEvent = 0;

		function refreshThumbnailsIfNeeded(itemId, mediaSourceId, apiClient, maxThumbnailWidth) {
			currentItemThumbnails || currentItemThumbnailsPromise ||
			function(itemId, mediaSourceId, apiClient, maxThumbnailWidth) {
				if (currentItemThumbnailsPromise) return;
				var promise = apiClient.getThumbnails(itemId, {
					MediaSourceId: mediaSourceId,
					Width: maxThumbnailWidth
				}).then(function(result) {
					return currentItemThumbnails = result, Promise.resolve(result)
				}, function() {
					currentItemThumbnailsPromise = null
				});
				currentItemThumbnailsPromise = promise
			}(itemId, mediaSourceId, apiClient, maxThumbnailWidth)
		}
		function getThumbnailBubbleHtml(apiClient, itemId, mediaSourceId, thumbnailSet, chapters, positionTicks, maxThumbnailWidth) {
			for (var thumbnail, chapter, thumbnails = thumbnailSet.Thumbnails, i = 0, length = thumbnails.length; i < length; i++) {
				var currentThumbnail = thumbnails[i];
				if (positionTicks >= currentThumbnail.PositionTicks) thumbnail = currentThumbnail;
				else if (thumbnail) break
			}
			if (!thumbnail) return null;
			for (i = 0, length = chapters.length; i < length; i++) {
				var currentChapter = chapters[i];
				if (positionTicks >= currentChapter.StartPositionTicks) chapter = currentChapter;
				else if (chapter) break
			}
			chapter = chapter || {
				Name: "&nbsp;"
			};
			var src = function(itemId, thumbnail, maxWidth, apiClient) {
					return thumbnail.ImageTag ? apiClient.getScaledImageUrl(itemId, {
						maxWidth: maxWidth,
						tag: thumbnail.ImageTag,
						type: "Thumbnail",
						PositionTicks: thumbnail.PositionTicks
					}) : null
				}(itemId, thumbnail, maxThumbnailWidth, apiClient);
			if (src) {
				var html = '<div class="chapterThumbContainer">',
					className = "chapterThumbImageContainer";
				return thumbnailSet.AspectRatio && thumbnailSet.AspectRatio < 1.4 && (className += " chapterThumbImageContainer-fourthree"), html += '<div class="' + className + '" style="background-image:url(\'' + src + "');\">", html += "</div>", html += '<div class="chapterThumbTextContainer">', html += '<div class="chapterThumbTextContainerInner">', html += '<div class="chapterThumbText">', html += datetime.getDisplayRunningTime(positionTicks), html += "</div>", html += "</div>", html += "</div>", html += "</div>"
			}
			return null
		}
		function onStop() {
			playbackManager.stop(currentPlayer)
		}
		function onMoreClick() {
			showMoreMenu(currentItem, this)
		}
		dom.addEventListener(view, window.PointerEvent ? "pointerup" : "click", function(e) {
			var pointerType = e.pointerType;
			if ("touch" === (lastPointerUpType = pointerType = pointerType || (supportsTouchEvent ? "touch" : "mouse"))) {
				if (e.target.closest("BUTTON,INPUT")) return void showOsd();
				var now = Date.now();
				300 < now - lastPointerEvent && (lastPointerEvent = now, "osd" === currentVisibleMenu ? setTimeout(hideOsd, 10) : currentVisibleMenu || setTimeout(showOsd, 10))
			} else {
				if (showOsd(), e.target.closest(".videoOsdBottom,.upNextContainer")) return;
				var player = currentPlayer;
				!e.button && player && isDisplayingLocalVideo(player) && playbackManager.playPause(player)
			}
		}, {
			passive: !0
		}), dom.addEventListener(view, "dblclick", function(e) {
			var clientX, windowSize;
			e.target.closest("BUTTON") || ("mouse" !== lastPointerUpType ? null != (clientX = e.clientX) && (clientX <= .4 * (windowSize = dom.getWindowSize()).innerWidth ? rewind(currentPlayer) : clientX >= .6 * windowSize.innerWidth && fastForward(currentPlayer), e.preventDefault(), e.stopPropagation()) : playbackManager.toggleFullscreen(currentPlayer))
		}, {
			passive: !0
		}), dom.addEventListener(buttonMute, "click", function() {
			playbackManager.toggleMute(currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(nowPlayingVolumeSlider, "change", function() {
			playbackManager.setVolume(this.value, currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(nowPlayingPositionSlider, "change", function() {
			var newPercent, seekAirTimeTicks, player = currentPlayer;
			player && (newPercent = parseFloat(this.value), enableProgressByTimeOfDay ? (seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4, seekAirTimeTicks += 1e4 * programStartDateMs, seekAirTimeTicks -= playbackStartTimeTicks, playbackManager.seek(seekAirTimeTicks, player)) : playbackManager.seekPercent(newPercent, player))
		}, {
			passive: !0
		}), nowPlayingPositionSlider.getBubbleHtml = function(value) {
			if (showOsd(), enableProgressByTimeOfDay) {
				if (programStartDateMs && programEndDateMs) {
					var ms = programEndDateMs - programStartDateMs;
					return ms /= 100, ms *= value, ms += programStartDateMs, '<h1 class="sliderBubbleText">' + getDisplayTimeWithoutAmPm(new Date(parseInt(ms)), !0) + "</h1>"
				}
				return "--:--"
			}
			if (!currentRuntimeTicks) return "--:--";
			var ticks = currentRuntimeTicks;
			ticks /= 100, ticks *= value;
			var item = currentItem;
			if (item) {
				var apiClient = connectionManager.getApiClient(item.ServerId);
				if (refreshThumbnailsIfNeeded(item.Id, "", apiClient, 400), currentItemThumbnails) {
					var html = getThumbnailBubbleHtml(apiClient, item.Id, 0, currentItemThumbnails, item.Chapters || {}, ticks, 400);
					if (html) return html
				}
			}
			return '<h1 class="sliderBubbleText">' + datetime.getDisplayRunningTime(ticks) + "</h1>"
		}, dom.addEventListener(osdBottomElement, transitionEndEventName, function(e) {
			var elem = e.currentTarget;
			elem === e.target && elem.classList.contains("videoOsdBottom-hidden") && (elem.classList.add("hide"), onRewindAnimationComplete.call(btnRewindIcon), onFastForwardAnimationComplete.call(btnFastForwardIcon), view.dispatchEvent(new CustomEvent("video-osd-hide", {
				bubbles: !0
			})))
		}, {
			passive: !0
		}), dom.addEventListener(btnPreviousTrack, "click", function() {
			playbackManager.previousTrack(currentPlayer)
		}, {
			passive: !0
		}), Array.prototype.forEach.call(stopButtons, function(btnStop) {
			btnStop.addEventListener("click", onStop)
		}), dom.addEventListener(btnPause, "click", function() {
			playbackManager.playPause(currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(btnNextTrack, "click", function() {
			playbackManager.nextTrack(currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(btnRewind, "click", function() {
			rewind(currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(btnFastForward, "click", function() {
			fastForward(currentPlayer)
		}, {
			passive: !0
		}), dom.addEventListener(btnRepeatMode, "click", function() {
			!
			function(player) {
				if (player) switch (playbackManager.getRepeatMode(player)) {
				case "RepeatNone":
					playbackManager.setRepeatMode("RepeatAll", player);
					break;
				case "RepeatAll":
					playbackManager.setRepeatMode("RepeatOne", player);
					break;
				case "RepeatOne":
					playbackManager.setRepeatMode("RepeatNone", player)
				}
			}(currentPlayer)
		}, {
			passive: !0
		});
		for (var i = 0, length = btnMoreButtons.length; i < length; i++) dom.addEventListener(btnMoreButtons[i], "click", onMoreClick, {
			passive: !0
		});
		dom.addEventListener(btnAudio, "click", function() {
			var audioTracks, currentIndex, menuItems, positionTo, player = currentPlayer;
			player && (audioTracks = playbackManager.audioTracks(player), currentIndex = playbackManager.getAudioStreamIndex(player), menuItems = audioTracks.map(function(stream) {
				var opt = {
					name: stream.DisplayTitle,
					id: stream.Index
				};
				return stream.Index === currentIndex && (opt.selected = !0), opt
			}), positionTo = this, require(["actionsheet"], function(actionsheet) {
				actionsheet.show({
					items: menuItems,
					title: globalize.translate("Audio"),
					positionTo: positionTo,
					positionY: "top"
				}).then(function(id) {
					var index = parseInt(id);
					index !== currentIndex && playbackManager.setAudioStreamIndex(index, player)
				})
			}))
		}, {
			passive: !0
		}), dom.addEventListener(btnSubtitles, "click", function() {
			var player = currentPlayer,
				streams = playbackManager.subtitleTracks(player),
				currentIndex = playbackManager.getSubtitleStreamIndex(player);
			null == currentIndex && (currentIndex = -1), streams.unshift({
				Index: -1,
				DisplayTitle: globalize.translate("Off")
			});
			var menuItems = streams.map(function(stream) {
				var opt = {
					name: stream.DisplayTitle,
					id: stream.Index
				};
				return stream.Index === currentIndex && (opt.selected = !0), opt
			}),
				positionTo = this,
				apiClient = connectionManager.getApiClient(currentItem);
			apiClient.getCurrentUser().then(function(user) {
				supportsSubtitleDownloading(apiClient) && itemHelper.canDownloadSubtitles(user, currentItem) && menuItems.push({
					name: globalize.translate("SearchForSubtitles"),
					id: "search",
					icon: "search"
				}), require(["actionsheet"], function(actionsheet) {
					actionsheet.show({
						title: globalize.translate("Subtitles"),
						items: menuItems,
						positionTo: positionTo,
						positionY: "top"
					}).then(function(id) {
						if ("search" === id) return item = currentItem, void require(["registrationServices", "subtitleEditor"]).then(function(responses) {
							return responses[0].validateFeature("sync").then(function() {
								return responses[1].show({
									item: item,
									showCurrentSubtitles: !1,
									autoSearch: !0,
									closeOnDownload: !0
								}).then(function(result) {
									playbackManager.setSubtitleStreamIndex(result.NewIndex, currentPlayer, !0)
								})
							})
						});
						var item, index = parseInt(id);
						index !== currentIndex && playbackManager.setSubtitleStreamIndex(index, player)
					})
				})
			})
		}, {
			passive: !0
		}), itemShortcuts.on(videoOsdText)
	}
});
