{"version":3,"sources":["webpack:///./app/javascript/packs/common/movie_player/manifest_menu.js","webpack:///./app/javascript/packs/common/movie_player/fullscreen_menu_button.js","webpack:///./app/javascript/packs/common/movie_player/multi_view_points_menu.js","webpack:///./app/javascript/packs/common/movie_player.js","webpack:///./app/javascript/packs/common/movie_player/neko_player.js","webpack:///./app/javascript/packs/common/progress_button.js","webpack:///./app/javascript/packs/common/movie_player/player_logger.js","webpack:///./node_modules/js-cookie/src/js.cookie.js","webpack:///./app/javascript/packs/common/movie_player/recommendation_container.js","webpack:///./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js","webpack:///./app/javascript/packs/common/movie_player/event_emitter.js","webpack:///./app/javascript/packs/common/schedule_player_timer.js","webpack:///./app/javascript/packs/common/movie_player/end_screen_container.js","webpack:///./app/javascript/packs/common/movie_player/neko_seek_bar.js"],"names":["ManifestMenu","parent","controls","manifests","controlsContainer_","getControlsContainer","addManifestMenuButton_","addManifestMenu_","updateManifestSelection_","eventManager","listen","manifestMenuButton_","onManifestMenuButtonClick_","this","document","createElement","id","classList","add","appendChild","manifestMenu_","selectedIndex","removeAllChildren_","forEach","manifest","index","isSelected","addManifestButton_","textContent","name","manifestButton","addEventListener","onManifestClick_","span","checkmarkIcon_","icon","setAttribute","anySettingsMenusAreOpen","hideSettingsMenus","remove","getPlayer","load","url","element","firstChild","removeChild","lastChild","Shaka","ui","Element","Factory","rootElement","FullscreenMenuButton","buttonHandler","fullscreen_button","_buttonHandler","_fullscreenButton","fullscreenEnabled","MultiViewPointsMenu","playSettings","drm","src","player","_controlsContainer","_video","getVideo","_playSettings","_drm","_userAgent","UAParser","navigator","userAgent","_streamingProtocol","_getStreamingProtocol","_addOverflowMenuButton","_addOverflowMenu","engine","_addSubViewContainer","_updateInterval","setInterval","_isPausing","_updateSubViews","currentViewPoint","_videoElement","Array","prototype","find","call","getVideoContainer","children","child","tagName","undefined","_overflowMenu","e","stopPropagation","setLastTouchEventTime","Date","now","_overflowMenuButton","_onOverflowMenuButtonClick","window","_changeViewPoint","addEvent","NekoPlayer","Events","DidEnterFullscreen","DidExitFullscreen","clearInterval","_","i","buttonContainer","j","viewPointButton","viewPointName","_subViewContainerWrap","_subViewContainer","subView","currentSubViews","_getCurrentSubViewLocations","location","videoWidth","videoHeight","clientWidth","clientHeight","offsetWidth","offsetHeight","offsetX","Math","min","offsetY","path","transform","style","clipPath","canvases","width","height","rowColumn","pop","splice","canvas","context","getContext","ratioY","drawImage","subViewLocations","split","App","_openVideoModalButton","getElementById","_closeVideoModalButton","_downloadButton","_videoModal","_playerContainer","_downloadPlay","_downloadedPlay","_moviePlayer","_playerDataSource","_recommendationContainer","_progressButton","_sessionCheckInterval","isBrowserSupported","console","log","renderer","RecommendationContainer","Renderer","recommendationContainer","hasRecommendationContents","hidden","URL","href","apiEnabled","Number","searchParams","get","playerDataSouce","PlayDataSource","moviePlayer","init","playerLogger","PlayerLogger","key","ticket","DidLoadManifest","error","showErrorMessage","Error","parse","deleteAllEvents","hideControls","sendMessage","startCheckSession","DidStartPlayback","createTime","hidePosterImage","DidPausePlayback","isFinished","updateTime","currentTime","DidBeginSeeking","DidFinishPlayback","show","WillEnterFullscreen","getElementsByClassName","display","getElementsByTagName","paddingTop","scrollTo","WillCloseWindow","isPausing","DidDownloadProgress","content","progress","DidFinishDownload","finish","ProgressButton","Icon","CheckUnderlineCircle","DidFailDownload","DidKeyDown","event","executeKeyEvent","preventDefault","DidReceiveMessage","origin","executeMessage","JSON","data","storage","contentAtOriginalUri","Download","progressButton","a","removeAtOriginalUri","start","download","isManagement","isSchedulePlay","archiveUrl","archive_url","SchedulePlayer","startAt","endAt","duration","isPlayable","isOfflinePlaySupported","findContent","appMetadata","removeAtOfflineUri","offlineUri","checkSession","Rails","ajax","pathname","search","type","response","status","xhr","signInPath","Cookie","_play","fetchPlayData","poster_image_url","configration","dash","initialSegmentLimit","servers","wv_token","pr_token","fp_token","advanced","serverCertificate","playRangeStart","start_time","autoplay","auto_play_enabled","offline","progressCallback","trigger","trackSelectionCallback","tracks","filter","track","sort","b","bandwidth","usePersistentLicense","controlPanelElements","play_button_enabled","push","mute_button_enabled","volume_bar_enabled","time_duration_enabled","fullscreen_button_enabled","elementName","isSupportFullscreen","externalManifests","length","isMultiView","overflow_menu_enabled","overflowMenuButtons","_getOverflowMenuButtons","addBigPlayButton","big_play_button_enabled","addSeekBar","seek_bar_enabled","schedule_play","showControls","is_playable","is_management","play_settings","multi_view_points","timestamp","start_at","end_at","Promise","resolve","reject","dataType","success","DataSource","container","datasource","_container","_datasource","_posterImage","_errorMessage","_player","_storage","_overlay","_isFullscreen","_apiEnabled","reloadData","posterImage","playerPosterImageUri","video","poster","errorMessage","innerHeight","innerWidth","Controls","registerSeekBar","registerSeekBarElement","registerControlElements","registerElement","Player","getNetworkingEngine","registerRequestFilter","Storage","overlay","Overlay","configure","_attachEvents","startTime","WillLoadManifest","playerContentSrc","playerUIConfigration","playerConfigration","unload","uri","metadata","playerDownloadConfigration","store","promise","then","storedContent","play","pause","isFullscreen","requestFullscreen","_disableTouchScroll","passive","exitFullscreen","removeEventListener","isDark","message","innerHTML","errorText","errorMessageCloseButton","hideErrorMessage","button","controlsContainer","_getControlsContainer","keyEvents","enterFullscreen","muted","isMuted","hasOwnProperty","commandFunctions","functionName","postMessage","getControls","_startPlaybackEventHandler","_pausePlaybackEventHandler","_finishPlaybackEventHandler","_seekingEventHandler","_seekedEventHandler","_fullscreenEventHandler","_resizeWindowEventHandler","_rotateWindowEventHandler","_closeWindowEventHandler","_keyDownEventHandler","_receiveMessageEventHandler","DidEndSeeking","DidResizeWindow","angle","screen","orientation","DidRotateWindow","getMediaElement","paused","ended","enable","getAssetUri","fullscreenElement","polyfill","installAll","support","EventEmitter","term","contents","originalManifestUri","list","deleteAll","_serverCertificate","fetch","request","arrayBuffer","certificate","elementByName","Map","set","menuButton","toggleFullscreenIcon","NekoSeekBar","net","NetworkingEngine","RequestType","LICENSE","toLocaleLowerCase","indexOf","headers","Uint8Array","Symbol","code","Code","400","401","403","404","408","util","buttonElement","_buttonElement","_progress","CircleProgress","disabled","value","querySelector","className","_svg","_circle","radius","PI","circle","createElementNS","stroke","strokeWidth","svg","overflow","position","playKey","extraKey","ticketId","_playKey","_extraKey","_ticketId","_previousLogUrl","RegExp","test","_isManager","formData","FormData","append","getResponseHeader","_typeof","iterator","obj","constructor","factory","registeredInModuleLoader","exports","module","OldCookies","Cookies","api","noConflict","extend","result","arguments","attributes","decode","s","replace","decodeURIComponent","converter","defaults","expires","toUTCString","stringify","write","encodeURIComponent","String","escape","stringifiedAttributes","attributeName","cookie","json","jar","cookies","parts","slice","join","charAt","read","getJSON","withConverter","EventKeys","ClickPageControl","pageNumber","selectedPageNumber","reload","ClickRecommendPanel","open","recommendationsData","dataset","recommendations","recommendation","EndScreenContainer","_numberOfRow","_numberOfColumn","_splitNumber","_panelMarginRatio","_luminanceForImage","filteredRecommendations","recommendPanelContainer","containerWidth","containerHight","panelMargin","panelWidth","panelHeight","startIndex","endIndex","panel","_createRecommendPanel","link","image_url","column","row","parseInt","left","top","pageNumbers","ceil","pageControls","keys","pageControl","_createPageControl","linkText","imageUrl","image","title","Image","once","crossOrigin","_loadImage","canvasContext","imageData","getImageData","total","linkClickSelector","buttonClickSelector","selector","exclude","inputChangeSelector","formSubmitSelector","formInputClickSelector","formDisableSelector","formEnableSelector","fileInputSelector","linkDisableSelector","buttonDisableSelector","nonce","loadCSPNonce","ref","cspNonce","m","matches","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","getData","setData","$","querySelectorAll","csrfParam","csrfToken","meta","CSRFProtection","token","setRequestHeader","refreshCSRFTokens","param","input","CustomEvent","fire","params","evt","createEvent","initCustomEvent","bubbles","cancelable","detail","Event","defaultPrevented","Object","defineProperty","dispatchEvent","stopEverything","target","stopImmediatePropagation","delegate","eventType","handler","parentNode","AcceptHeaders","createXHR","prepareOptions","processResponse","text","html","xml","script","options","responseText","floor","statusText","complete","beforeSend","readyState","XMLHttpRequest","OPENED","send","toUpperCase","accept","done","crossDomain","withCredentials","onreadystatechange","DONE","parser","match","head","DOMParser","parseFromString","isCrossDomain","originAnchor","urlAnchor","protocol","host","toArray","serializeElement","additionalParam","inputs","elements","option","selected","checked","map","formElements","form","el","allowAction","handleConfirm","confirm","answer","callback","getAttribute","disableFormElement","disableFormElements","disableLinkElement","enableFormElement","enableFormElements","enableLinkElement","isXhrRedirect","handleDisabledElement","enableElement","disableElement","replacement","originalText","handleMethod","formContent","method","action","body","click","isRemote","handleRemote","enctype","args","formSubmitButtonClick","formNoValidate","preventInsignificantClick","insignificantMetaClick","metaKey","ctrlKey","jQuery","rails","ajaxPrefilter","originalOptions","_rails_loaded","setTimeout","_eventHandlers","eventName","handlers","filteredHandlers","eventHandler","apply","_archiveUrl","_timerTag","TimerTag","formattedStartAt","toLocaleString","timeZoneName","timerStateByFunctions","TimerStatus","Opening","timer","elapsedTime","remainingTime","minStr","padStart","secStr","Start","assetUri","Finished","stop","setArchiveLink","showPosterImage","finishPlayback","Timer","state","Constants","TIMER_INTERVAL","REMINDER_THRESHOLD","MARGIN_TIME","Idling","Playing","Unknown","_now","_startAt","_endAt","_movieDuration","_intervalTimer","_count","_started","_countdown","_stopCountdown","missedTime","playDuration","timerState","parentElement","tagElement","textElement","archiveLinkElement","_tagElement","_textElement","_archiveLinkElement","archiveLinkText","archiveLinkUrl","rootElementId","_renderer","_rootElement","_isHidden","willInsertContainerElement","didInsertContainerElement","render","endScreenContainer","timeTip","thumbnailTip","_timeTip","_thumbnailTip","_updateTip","positionX","seekRange","end","getBoundingClientRect","_updateTimeTip","hours","minutes","seconds","hoursStr","minutesStr","secondsStr","innerText","activeTrack","getImageTracks","active","getThumbnails","thumbnail","SeekBar"],"mappings":"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","file":"js/common/movie_player-d13b64b2bdb988da23b6.chunk.js","sourcesContent":["import Shaka from 'shaka-player/dist/shaka-player.ui'\n\nclass ManifestMenu extends Shaka.ui.Element {\n constructor(parent, controls, manifests) {\n super(parent, controls);\n\n this.manifests = manifests;\n\n this.controlsContainer_ = this.controls.getControlsContainer();\n\n this.addManifestMenuButton_();\n this.addManifestMenu_();\n this.updateManifestSelection_(0);\n\n this.eventManager.listen(this.manifestMenuButton_, 'click', () => {\n this.onManifestMenuButtonClick_();\n });\n }\n\n /**\n * @private\n */\n addManifestMenuButton_() {\n this.manifestMenuButton_ = document.createElement('button');\n this.manifestMenuButton_.id = 'manifest-menu-button';\n this.manifestMenuButton_.classList.add('shaka-no-propagation');\n this.parent.appendChild(this.manifestMenuButton_);\n }\n\n /**\n * @private\n */\n addManifestMenu_() {\n this.manifestMenu_ = document.createElement('div');\n this.manifestMenu_.classList.add('shaka-overflow-menu');\n this.manifestMenu_.classList.add('shaka-no-propagation');\n this.manifestMenu_.classList.add('shaka-show-controls-on-mouse-over');\n this.manifestMenu_.classList.add('shaka-settings-menu');\n\n // \".shaka-resolutions span\" の CSS を借りるため、クラスを付与\n this.manifestMenu_.classList.add('shaka-resolutions');\n\n this.manifestMenu_.classList.add('shaka-hidden');\n this.controlsContainer_.appendChild(this.manifestMenu_);\n }\n\n /**\n * @private\n */\n updateManifestSelection_(selectedIndex) {\n this.removeAllChildren_(this.manifestMenu_);\n\n this.manifests.forEach((manifest, index) => {\n const isSelected = (selectedIndex === index);\n this.addManifestButton_(index, isSelected);\n });\n\n this.manifestMenuButton_.textContent = this.manifests[selectedIndex].name;\n }\n\n /**\n * @private\n */\n addManifestButton_(index, isSelected) {\n const manifestButton = document.createElement('button');\n\n manifestButton.addEventListener('click', () => {\n this.onManifestClick_(index);\n });\n\n // \".shaka-resolutions span\" の CSS を借りるため、span 要素にする\n const span = document.createElement('span');\n span.textContent = this.manifests[index].name;\n manifestButton.appendChild(span);\n\n if (isSelected) {\n manifestButton.appendChild(this.checkmarkIcon_());\n }\n\n this.manifestMenu_.appendChild(manifestButton);\n }\n\n /**\n * @private\n */\n checkmarkIcon_() {\n const icon = document.createElement('i');\n icon.classList.add('shaka-chosen-item');\n\n // チェックマークアイコンを追加\n icon.classList.add('material-icons-round');\n icon.textContent = 'done';\n\n icon.setAttribute('aria-hidden', 'true');\n return icon;\n }\n\n /**\n * @private\n */\n onManifestMenuButtonClick_() {\n if (this.controls.anySettingsMenusAreOpen()) {\n this.controls.hideSettingsMenus();\n } else {\n this.manifestMenu_.classList.remove('shaka-hidden');\n }\n }\n\n /**\n * @private\n */\n onManifestClick_(index) {\n const manifest = this.manifests[index];\n // [NOTE]\n // マニフェストの切り替え時に pause, finish が呼ばれず、\n // 再生ログ的に last_view_point が NULL になる点に注意\n this.controls.getPlayer().load(manifest.url);\n this.updateManifestSelection_(index);\n }\n\n /**\n * @private\n */\n removeAllChildren_(element) {\n while (element.firstChild) {\n element.removeChild(element.lastChild);\n }\n }\n}\n\nManifestMenu.Factory = class {\n /**\n * @param {Array} manifests\n */\n constructor(manifests) {\n this.manifests = manifests;\n }\n\n create(rootElement, controls) {\n return new ManifestMenu(rootElement, controls, this.manifests);\n }\n};\n\nexport default ManifestMenu;\n","\nimport Shaka from 'shaka-player/dist/shaka-player.ui'\n\nclass FullscreenMenuButton extends Shaka.ui.Element {\n constructor(parent, controls, buttonHandler) {\n super(parent, controls)\n\n const fullscreen_button = document.createElement('button')\n fullscreen_button.classList.add('shaka-no-propagation')\n fullscreen_button.classList.add('material-icons', 'mdi', 'mdi-fullscreen')\n this.parent.appendChild(fullscreen_button)\n\n this._buttonHandler = () => buttonHandler(this)\n this._fullscreenButton = fullscreen_button\n\n this.eventManager.listen(this._fullscreenButton, 'click', this._buttonHandler)\n }\n\n /**\n * フルスクリーンアイコンの切り替え\n * @param {Boolean} fullscreenEnabled\n */\n toggleFullscreenIcon(fullscreenEnabled) {\n if (fullscreenEnabled) {\n this._fullscreenButton.classList.remove('mdi-fullscreen')\n this._fullscreenButton.classList.add('mdi-fullscreen-exit')\n } else {\n this._fullscreenButton.classList.remove('mdi-fullscreen-exit')\n this._fullscreenButton.classList.add('mdi-fullscreen')\n }\n }\n}\n\nFullscreenMenuButton.Factory = class {\n constructor(buttonHandler) {\n this._buttonHandler = buttonHandler\n }\n\n create(rootElement, controls) {\n return new FullscreenMenuButton(rootElement, controls, this._buttonHandler)\n }\n}\n\nexport default FullscreenMenuButton\n","import Shaka from 'shaka-player/dist/shaka-player.ui'\nimport UAParser from 'ua-parser-js'\nimport NekoPlayer from \"./neko_player\";\n\nclass MultiViewPointsMenu extends Shaka.ui.Element {\n constructor(parent, controls, playSettings, drm, src, player) {\n super(parent, controls);\n\n this._controlsContainer = this.controls.getControlsContainer();\n this._video = this.controls.getVideo();\n this._playSettings = playSettings;\n this._drm = drm;\n this._userAgent = UAParser(navigator.userAgent)\n this._streamingProtocol = this._getStreamingProtocol(src);\n\n // 視点変更ボタンとそれをオーバーフローした際に表示されるメニューを追加\n this._addOverflowMenuButton();\n this._addOverflowMenu();\n // 「DRM が有効の場合」あるいは「WebKit を使用したブラウザが MPEG-DASH を再生する場合」はサブビューを無効\n if (!this._drm && !(this._userAgent.engine.name === 'WebKit' && this._streamingProtocol === 'dash')) {\n this._addSubViewContainer();\n // NOTE: 現状サブビューは 16ms (60fps) での更新となっている\n this._updateInterval = setInterval(() => {\n if (!this._isPausing) this._updateSubViews(this.currentViewPoint), 16\n });\n }\n\n this._videoElement = Array.prototype.find.call(this.controls.getVideoContainer().children, (child) => {\n return child.tagName === 'VIDEO';\n });\n this._isPausing = true;\n // NOTE: viewPoint は undefined: 全体, 0: 左上, 1: 右上, 2:左下, 3: 右下\n this.currentViewPoint = undefined;\n\n // listen events\n this.eventManager.listen(this._overflowMenu, 'touchstart', (e) => {\n e.stopPropagation();\n this.controls.setLastTouchEventTime(Date.now);\n })\n\n this.eventManager.listen(this._overflowMenuButton, 'click', () => {\n this._onOverflowMenuButtonClick();\n });\n\n this.eventManager.listen(this._video, 'play', () => {\n this._isPausing = false;\n });\n\n this.eventManager.listen(this._video, 'pause', () => {\n this._isPausing = true;\n });\n\n this.eventManager.listen(window, 'resize', () => {\n this._changeViewPoint(this.currentViewPoint);\n });\n\n this.eventManager.listen(document, 'fullscreenchange', () => {\n this._changeViewPoint(this.currentViewPoint);\n });\n\n player.addEvent(NekoPlayer.Events.DidEnterFullscreen, () => {\n this._changeViewPoint(this.currentViewPoint);\n })\n\n player.addEvent(NekoPlayer.Events.DidExitFullscreen, () => {\n this._changeViewPoint(this.currentViewPoint);\n })\n\n window.addEventListener('stopUpdateSubViews', () => {\n window.clearInterval(this._updateInterval)\n })\n }\n\n /**\n * overflowMenuButton を追加\n * @private\n */\n _addOverflowMenuButton() {\n this._overflowMenuButton = document.createElement('button');\n this._overflowMenuButton.id = 'multi-view-points-menu-button';\n // NOTE: class で material-icons mdi アイコン名 を指定するとそのアイコンが表示される\n // https://materialdesignicons.com\n this._overflowMenuButton.classList.add('shaka-overflow-menu-button', 'shaka-no-propagation')\n this._overflowMenuButton.classList.add('material-icons', 'mdi', 'mdi-binoculars');\n this.parent.appendChild(this._overflowMenuButton);\n }\n\n /**\n * overflowMenu を追加\n * @private\n */\n _addOverflowMenu() {\n this._overflowMenu = document.createElement('div');\n this._overflowMenu.classList.add(\n 'shaka-settings-menu',\n 'shaka-no-propagation',\n 'shaka-show-controls-on-mouse-over',\n 'shaka-hidden'\n );\n this._controlsContainer.appendChild(this._overflowMenu);\n\n // 各視点のボタンを追加\n [...Array(2)].forEach((_, i) => {\n const buttonContainer = document.createElement('div');\n buttonContainer.classList.add('view-points-button-container');\n [...Array(2)].forEach((_, j) => {\n const index = i * 2 + j;\n const viewPointButton = document.createElement('button');\n viewPointButton.classList.add('view-point-button');\n const viewPointName = this._playSettings[`view_point_${index + 1}`];\n viewPointButton.textContent = viewPointName ? viewPointName : \"\";\n viewPointButton.addEventListener('click', () => {\n this._changeViewPoint(index);\n })\n buttonContainer.appendChild(viewPointButton);\n })\n this._overflowMenu.appendChild(buttonContainer);\n })\n }\n\n /**\n * subViewContainer を追加\n * @private\n */\n _addSubViewContainer() {\n this._subViewContainerWrap = document.createElement('div');\n this._subViewContainerWrap.classList.add('sub-view-container-wrap');\n this._controlsContainer.appendChild(this._subViewContainerWrap);\n this._subViewContainer = document.createElement('div');\n this._subViewContainer.classList.add('sub-view-container', 'shaka-show-controls-on-mouse-over');\n this._subViewContainerWrap.appendChild(this._subViewContainer);\n\n // 各サブビューを canvas 要素へ描画\n [...Array(3)].forEach((_, i) => {\n const subView = document.createElement('canvas');\n subView.classList.add('sub-view', 'shaka-no-propagation');\n subView.addEventListener('click', () => {\n const currentSubViews = this._getCurrentSubViewLocations(this.currentViewPoint);\n this._changeViewPoint(currentSubViews[i]);\n })\n this._subViewContainer.appendChild(subView);\n })\n }\n\n /**\n * overflowMenuButton がクリックされた時の動作\n * @private\n */\n _onOverflowMenuButtonClick() {\n this._changeViewPoint();\n if (this.controls.anySettingsMenusAreOpen()) {\n this.controls.hideSettingsMenus();\n } else {\n this._overflowMenu.classList.remove('shaka-hidden');\n }\n }\n\n /**\n * メイン画面の視点変更\n * @private\n * @params {number} location - 切り替えする視点の番号(0〜3 | undefined)\n */\n _changeViewPoint(location) {\n const videoWidth = this._video.videoWidth;\n const videoHeight = this._video.videoHeight;\n const clientWidth = this._video.clientWidth;\n const clientHeight = this._video.clientHeight;\n const ratioX = clientWidth / videoWidth;\n const ratioY = clientHeight / videoHeight;\n const offsetWidth = (clientWidth - (ratioY * videoWidth)) / 2;\n const offsetHeight = (clientHeight - (ratioX * videoHeight)) / 2;\n const offsetX = Math.min((0.5 - (offsetWidth / clientWidth)), 0.5) * 100;\n const offsetY = Math.min((0.5 - (offsetHeight / clientHeight)), 0.5) * 100;\n\n let path = 'inset(0 0 0 0)';\n let transform = 'scale(1)';\n switch (location) {\n case 0:\n // TODO: 50.2% はアストロのコンテンツ向けの調整\b\n // 別案件で4視点再生を行う場合は調整が必要な可能性があるため留意\n path = 'inset(0 50% 50.2% 0)';\n transform = `translate(${offsetX}%, ${offsetY}%) scale(2)`;\n break;\n case 1:\n path = 'inset(0 0 50.2% 50%)';\n transform = `translate(-${offsetX}%, ${offsetY}%) scale(2)`;\n break;\n case 2:\n path = 'inset(50% 50% 0 0)';\n transform = `translate(${offsetX}%, -${offsetY}%) scale(2)`;\n break;\n case 3:\n path = 'inset(50% 0 0 50%)';\n transform = `translate(-${offsetX}%, -${offsetY}%) scale(2)`;\n break;\n default:\n break;\n }\n this._video.style.clipPath = path;\n this._video.style.transform = transform;\n this.currentViewPoint = location;\n this._updateSubViews(location);\n }\n\n /**\n * サブ画面の描画\n * @private\n * @params {number} location - 切り替えする視点の番号(0〜3 | undefined)\n */\n _updateSubViews(location) {\n if (this._subViewContainer) {\n const canvases = this._subViewContainer.children;\n const width = this._video.videoWidth / 2;\n const height = this._video.videoHeight / 2;\n\n let rowColumn = [[0, 0], [1, 0], [0, 1], [1, 1]];\n if (typeof location === 'undefined') {\n rowColumn.pop();\n } else {\n rowColumn.splice(location, 1);\n }\n Array.prototype.forEach.call(canvases, (canvas, i) => {\n const context = canvas.getContext('2d');\n const ratioY = canvas.height / height;\n const offsetWidth = (canvas.width - (ratioY * width)) / 2;\n context.drawImage(this._videoElement, rowColumn[i][0] * width, rowColumn[i][1] * height, width, height, offsetWidth, 0, ratioY * width, ratioY * height);\n })\n }\n }\n\n /**\n * location から現在表示されているサブビューの location 取得する\n * @private\n * @params {number} location - 視点の番号(0〜3 | undefined)\n * @return {number[]} subViewLocations - サブビューに表示されている location\n */\n _getCurrentSubViewLocations(location) {\n let subViewLocations = [0, 1, 2];\n switch (location) {\n case 0:\n subViewLocations = [1, 2, 3];\n break;\n case 1:\n subViewLocations = [0, 2, 3];\n break;\n case 2:\n subViewLocations = [0, 1, 3];\n break;\n case 3:\n break;\n default:\n break;\n }\n return subViewLocations;\n };\n\n /**\n * src のストリーミングプロトコルを返す\n * @private\n * @param {string} src - マニフェスト URL\n * @return {string} src のプロトコルが MPEG-DASH なら 'dash'、HLS なら 'hls'、どちらでもなければ 'unknown'\n */\n _getStreamingProtocol(src) {\n const ext = src.split('.').pop()\n switch (ext) {\n case 'mpd':\n return 'dash'\n case 'm3u8':\n return 'hls'\n default:\n return 'unknown'\n }\n }\n}\n\nMultiViewPointsMenu.Factory = class {\n constructor(playSettings, drm, src, player) {\n this.playSettings = playSettings;\n this.drm = drm;\n this.src = src;\n this.player = player;\n }\n\n create(rootElement, controls) {\n return new MultiViewPointsMenu(rootElement, controls, this.playSettings, this.drm, this.src, this.player);\n }\n}\n\nexport default MultiViewPointsMenu;\n","import Rails from '@rails/ujs'\nimport Cookie from 'js-cookie'\n\nimport NekoPlayer from './movie_player/neko_player'\nimport PlayerLogger from './movie_player/player_logger'\nimport SchedulePlayer from './schedule_player_timer'\nimport RecommendationContainer from './movie_player/recommendation_container'\nimport ProgressButton from './progress_button'\n\nclass App {\n constructor() {\n /** @private {HTMLElement} */\n this._openVideoModalButton = document.getElementById('open-video')\n\n /** @private {HTMLElement} */\n this._closeVideoModalButton = document.getElementById('close-video')\n\n /** @private {HTMLElement} */\n this._downloadButton = document.getElementById('download-button')\n\n /** @private {HTMLElement} */\n this._videoModal = document.getElementById('video-modal')\n\n /** @private {HTMLElement} */\n this._playerContainer = document.getElementById('player-container')\n\n /** @private {HTMLElement} */\n this._downloadPlay = document.getElementById('download_play')\n\n /** @private {HTMLElement} */\n this._downloadedPlay = document.getElementById('downloaded_play')\n\n\n /** @private {NekoPlayer} */\n this._moviePlayer = null\n\n /** @private {PlayDataSource} */\n this._playerDataSource = null\n\n /** @private {RecommendationContainer} */\n this._recommendationContainer = null\n\n /** @private {ProgressButton} */\n this._progressButton = null\n\n /** @private {Number} */\n this._sessionCheckInterval = null\n }\n\n async init() {\n if (!NekoPlayer.isBrowserSupported()) {\n console.log('Browser not supported!')\n return\n }\n\n // [TODO] NekoPlayer 側で持たせるか別途検討\n const renderer = new RecommendationContainer.Renderer()\n const recommendationContainer = new RecommendationContainer(renderer)\n if (recommendationContainer.hasRecommendationContents()) {\n recommendationContainer.load()\n recommendationContainer.hidden()\n }\n\n const url = new URL(document.location.href)\n const apiEnabled = Number(url.searchParams.get('apienabled')) === 1\n\n const playerDataSouce = new PlayDataSource()\n const moviePlayer = new NekoPlayer(this._playerContainer, playerDataSouce, apiEnabled)\n await moviePlayer.init()\n\n const playerLogger = new PlayerLogger(\n playerDataSouce.key, undefined, playerDataSouce.ticket\n )\n\n moviePlayer.addEvent(NekoPlayer.Events.DidLoadManifest, (player, error) => {\n if (error) {\n player.showErrorMessage(NekoPlayer.Error.parse(error))\n player.deleteAllEvents()\n player.hideControls()\n console.error(error)\n player.sendMessage('onError')\n } else {\n this.startCheckSession()\n player.sendMessage('onReady')\n }\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidStartPlayback, (player) => {\n playerLogger.createTime()\n player.hidePosterImage()\n this._recommendationContainer.hidden()\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidPausePlayback, (player) => {\n if (!player.isFinished) playerLogger.updateTime(player.currentTime)\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidBeginSeeking, (player) => {\n player.hidePosterImage()\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidFinishPlayback, (player) => {\n playerLogger.updateTime(player.currentTime)\n this._recommendationContainer.show()\n })\n moviePlayer.addEvent(NekoPlayer.Events.WillEnterFullscreen, (player) => {\n const navBar = document.getElementsByClassName('is-fixed-top')[0]\n navBar.style.display = 'none'\n const body = document.getElementsByTagName('body')[0]\n body.style.paddingTop = '0px'\n window.scrollTo(0, 0)\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidExitFullscreen, (player) => {\n const navBar = document.getElementsByClassName('is-fixed-top')[0]\n navBar.style.display = ''\n const body = document.getElementsByTagName('body')[0]\n body.style.paddingTop = ''\n })\n moviePlayer.addEvent(NekoPlayer.Events.WillCloseWindow, (player) => {\n if (!player.isPausing) playerLogger.updateTime(player.currentTime)\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidDownloadProgress, (player, content, progress) => {\n this._progressButton.progress = progress\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidFinishDownload, (player, content) => {\n this._progressButton.finish()\n this._progressButton.icon = ProgressButton.Icon.CheckUnderlineCircle\n this._downloadPlay.classList.add('is-hidden')\n this._downloadedPlay.classList.remove('is-hidden')\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidFailDownload, (player, error) => {\n console.error(error)\n this._progressButton.finish()\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidKeyDown, (player, event) => {\n // プレイヤーが提供するキー操作を一部変更したいなどの場合、適宜バリデーション\n\n if (player.executeKeyEvent(event.key)) {\n event.preventDefault()\n } else {\n // プレイヤーが提供しないキー操作が必要な場合はこの辺りに記載\n }\n })\n moviePlayer.addEvent(NekoPlayer.Events.DidReceiveMessage, (player, event) => {\n const url = new URL(document.location.href)\n const origin = url.searchParams.get('origin')\n if (event.origin !== origin) {\n // URL パラメータで渡された Origin と異なっている場合はエラー\n // 更に厳格に Origin を検証する場合、brand.original_url などとの比較を行う\n console.error(`Invalid Origin`)\n } else {\n player.executeMessage(JSON.parse(event.data))\n }\n })\n\n this._moviePlayer = moviePlayer\n this._playerDataSource = playerDataSouce\n this._recommendationContainer = recommendationContainer\n\n if (this._downloadButton) {\n const content = await this._moviePlayer.storage.contentAtOriginalUri(this._playerDataSource.src)\n\n this._progressButton = new ProgressButton(this._downloadButton)\n this._progressButton.init()\n this._progressButton.icon = content ?\n ProgressButton.Icon.CheckUnderlineCircle : ProgressButton.Icon.Download\n if (content == null) {\n this._downloadPlay.classList.remove('is-hidden')\n this._downloadedPlay.classList.add('is-hidden')\n } else {\n this._downloadPlay.classList.add('is-hidden')\n this._downloadedPlay.classList.remove('is-hidden')\n }\n this._progressButton.addEvent('click', async (progressButton) => {\n const content = await this._moviePlayer.storage.contentAtOriginalUri(this._playerDataSource.src)\n if (content) {\n this._moviePlayer.storage.removeAtOriginalUri(this._playerDataSource.src)\n progressButton.icon = ProgressButton.Icon.Download\n this._downloadPlay.classList.remove('is-hidden')\n this._downloadedPlay.classList.add('is-hidden')\n } else {\n progressButton.start()\n this._moviePlayer.download(this._playerDataSource.src, { key: this._playerDataSource.key })\n }\n })\n }\n\n if (!playerDataSouce.isManagement && playerDataSouce.isSchedulePlay) {\n // 視聴者向け且つ、擬似ライブが有効な場合、SchedulePlayer にプレイヤーの制御を渡す\n\n const archiveUrl = playerDataSouce.playSettings.archive_url\n const schedulePlayer = new SchedulePlayer(moviePlayer, archiveUrl)\n schedulePlayer.start(\n playerDataSouce.currentTime,\n playerDataSouce.startAt,\n playerDataSouce.endAt,\n playerDataSouce.duration\n )\n } else if (playerDataSouce.isPlayable) {\n this._moviePlayer.load()\n } else {\n this._moviePlayer.deleteAllEvents()\n this._moviePlayer.hideControls()\n\n // 通常上映会で視聴が行えない場合、保存済みのデータを削除する\n if (NekoPlayer.isOfflinePlaySupported()) {\n const content = await this._moviePlayer.storage.findContent(content => {\n return content.appMetadata.key === this._playerDataSource.key\n })\n if (content) this._moviePlayer.storage.removeAtOfflineUri(content.offlineUri)\n }\n }\n }\n\n startCheckSession() {\n if (!this._sessionCheckInterval) {\n const checkSession = () => {\n Rails.ajax({\n url: document.location.pathname + '/touch' + (document.location.search || ''),\n type: \"GET\",\n error: (response, status, xhr) => {\n if (xhr.status === 401) {\n window.clearInterval(this._sessionCheckInterval)\n const signInPath = Cookie.get('sign_in_path')\n window.location.href = (signInPath ? signInPath : '/entrance') + '?message=session_limited'\n }\n }\n })\n }\n\n this._sessionCheckInterval = window.setInterval(() => {\n checkSession()\n }, 100000)\n\n // 初回呼び出し\n checkSession()\n }\n }\n}\n\nclass PlayDataSource extends NekoPlayer.DataSource {\n constructor() {\n super()\n\n this._play = null\n }\n\n get isPlayable() { return this._play.is_playable }\n get isManagement() { return this._play.is_management || false }\n get src() { return this._play.src }\n get key() { return this._play.key }\n get ticket() { return this._play.ticket }\n get playSettings() { return this._play.play_settings }\n get drm() { return this._play.drm }\n get isSchedulePlay() { return this.playSettings ? this.playSettings.schedule_play : false }\n get isMultiView() { return this.playSettings ? this.playSettings.multi_view_points : false }\n get externalManifests() { return this._play.manifests }\n get currentTime() { return this._play.timestamp }\n get startAt() { return this._play.start_at }\n get endAt() { return this._play.end_at }\n get duration() { return this._play.duration }\n\n /**\n * @param {string} url\n * @returns {Promise}\n */\n static fetchPlayData(url = document.location.pathname) {\n return new Promise((resolve, reject) => {\n Rails.ajax({\n url: url + (document.location.search || ''),\n type: 'GET',\n dataType: 'json',\n success: (response, status, xhr) => {\n resolve(response)\n },\n error: (response, status, xhr) => {\n resolve(response)\n }\n })\n })\n }\n\n /**\n * @override\n */\n async init() {\n super.init()\n this._play = await PlayDataSource.fetchPlayData()\n }\n\n /**\n * @override\n */\n playerPosterImageUri(player) {\n return this._play.poster_image_url\n }\n\n /**\n * @override\n */\n async playerContentSrc(player) {\n if (NekoPlayer.isOfflinePlaySupported()) {\n const content = await player.storage.contentAtOriginalUri(this.src)\n return content && content.offlineUri || this.src\n }\n\n return this.src\n }\n\n /**\n * @override\n */\n playerConfigration(player) {\n const configration = {\n manifest: {\n dash: {\n initialSegmentLimit: 10000 // IMPORTANT (This must be set according to your total number of segments)\n }\n },\n drm: {\n servers: {\n 'com.widevine.alpha': this._play.wv_token || undefined,\n 'com.microsoft.playready': this._play.pr_token || undefined,\n 'com.apple.fps.1_0': this._play.fp_token || undefined,\n },\n advanced: {\n 'com.widevine.alpha': {\n 'videoRobustness': 'SW_SECURE_CRYPTO',\n 'audioRobustness': 'SW_SECURE_CRYPTO'\n },\n 'com.apple.fps.1_0': {\n serverCertificate: this.serverCertificate\n }\n }\n },\n playRangeStart: this.playSettings.start_time\n }\n\n player.autoplay = this.playSettings.auto_play_enabled\n\n return configration\n }\n\n /**\n * @override\n */\n playerDownloadConfigration(player) {\n const configration = {\n offline: {\n /**\n * @param {shaka.extern.StoredContent} content\n * @param {numver} progress normalize value\n */\n progressCallback: (content, progress) => {\n player.trigger(NekoPlayer.Events.DidDownloadProgress, player, content, progress)\n },\n /**\n * @param {Shaka.extern.TrackList} tracks\n */\n trackSelectionCallback: (tracks) => {\n // [TODO]\n // 言語別にビデオトラックが存在する場合、\n // ダウンロード時に選択するか、あるいは全てダウンロードするかの検討が必要\n // text, image トラックは現状対応していないため、字幕・サムネイル対応時に検討が必要\n const maxBandwidthVideoTrack = tracks\n .filter(track => track.type === 'variant')\n .sort((a, b) => a.bandwidth - b.bandwidth)\n .pop()\n\n return [maxBandwidthVideoTrack]\n },\n usePersistentLicense: false\n }\n }\n\n return configration\n }\n\n /**\n * @override\n */\n playerUIConfigration(player) {\n const controlPanelElements = []\n if (this.playSettings.play_button_enabled) controlPanelElements.push('play_pause')\n if (this.playSettings.mute_button_enabled) controlPanelElements.push('mute')\n if (this.playSettings.volume_bar_enabled) controlPanelElements.push('volume')\n if (this.playSettings.time_duration_enabled) controlPanelElements.push('time_and_duration')\n controlPanelElements.push('spacer')\n if (this.playSettings.fullscreen_button_enabled) {\n const elementName = player.isSupportFullscreen ? 'fullscreen' : 'fullscreen_menu_button'\n controlPanelElements.push(elementName)\n }\n if (this.externalManifests.length !== 0) controlPanelElements.push('manifest_menu')\n if (this.isMultiView) controlPanelElements.push('multi_view_points_menu')\n if (this.playSettings.overflow_menu_enabled) controlPanelElements.push('overflow_menu')\n\n const configration = {\n controlPanelElements: controlPanelElements,\n overflowMenuButtons: this._getOverflowMenuButtons(),\n addBigPlayButton: this.playSettings.big_play_button_enabled,\n addSeekBar: this.playSettings.seek_bar_enabled && (!this.playSettings.schedule_play || this.isManagement)\n }\n\n if (controlPanelElements.length > 1) {\n player.showControls()\n } else {\n // スペーサのみ指定されている場合、コントローラ自体を非表示化\n player.hideControls()\n }\n\n return configration\n }\n\n /**\n * @returns {Array}\n * @private\n */\n _getOverflowMenuButtons() {\n if (this.playSettings.schedule_play) {\n return ['captions', 'quality', 'language']\n } else {\n return ['captions', 'quality', 'language', 'playback_rate']\n }\n }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n const app = new App()\n app.init()\n})\n","import Shaka from 'shaka-player/dist/shaka-player.ui'\n\nimport EventEmitter from './event_emitter'\nimport NekoSeekBar from './neko_seek_bar'\nimport MultiViewPointsMenu from './multi_view_points_menu'\nimport ManifestMenu from './manifest_menu'\nimport FullscreenMenuButton from './fullscreen_menu_button'\n\nclass NekoPlayer extends EventEmitter {\n /**\n * @param {HTMLElement} container\n * @param {NekoPlayer.DataSource} datasource\n * @param {Boolean} apiEnabled\n */\n constructor(container, datasource, apiEnabled = false) {\n super()\n\n /** @private {!HTMLElement} */\n this._container = container\n\n /** @private {NekoPlayer.DataSource} */\n this._datasource = datasource\n\n /** @private {HTMLElement} */\n this._posterImage = null\n\n /** @private {HTMLElement} */\n this._video = null\n\n /** @private {HTMLElement} */\n this._errorMessage = null\n\n /** @private {Shaka.Player} */\n this._player = null\n\n /** @private {Shaka.offline.Storage} */\n this._storage = null\n\n /** @private {Shaka.ui.Overlay} */\n this._overlay = null\n\n /** @private {Boolean} ブラウザがフルスクリーンに対応しない場合に利用 */\n this._isFullscreen = false\n\n /** @private {Boolean} */\n this._apiEnabled = apiEnabled\n }\n\n get container() { return this._container }\n get mediaElement() { return this._player.getMediaElement() }\n\n get isPausing() { return this._video.paused }\n get isFinished() { return this._video.ended }\n get currentTime() { return this._video.currentTime }\n\n get isMuted() { return this._video.muted }\n set muted(enable) { this._video.muted = enable }\n\n set autoplay(enable) { this._video.autoplay = enable }\n\n get assetUri() { return this._player.getAssetUri() }\n\n get storage() { return new NekoPlayer.Storage(this._storage) }\n\n /**\n * shaka.polyfill.Fullscreen が install されている前提である点に注意\n * @requires module:shaka.polyfill.Fullscreen\n */\n get isSupportFullscreen() { return document.fullscreenEnabled !== undefined }\n get isFullscreen() {\n const hasFullscreenElement = this.isSupportFullscreen && document.fullscreenElement !== null\n return hasFullscreenElement || this._isFullscreen\n }\n\n /**\n * @returns {boolean} browser supports shaka player\n */\n static isBrowserSupported() {\n Shaka.polyfill.installAll()\n return Shaka.Player.isBrowserSupported()\n }\n\n /**\n * @returns {boolean} browser supports offline play\n */\n static isOfflinePlaySupported() {\n return Shaka.offline.Storage.support()\n }\n\n /**\n * @async\n */\n async init() {\n if (!this._datasource) {\n return\n }\n\n await this.reloadData()\n\n const posterImage = document.createElement('img')\n posterImage.classList.add('nekojs-player-poster')\n posterImage.src = this._datasource.playerPosterImageUri(this)\n\n const video = document.createElement('video')\n video.classList.add('nekojs-media-play')\n video.poster = 'data:image/gif,AAAA'\n video.autoplay = true\n\n // [TODO] 岡山案件の hotfix 対応のため、別途リファクタリングが必要\n // 今後の方針として、URL パラメータからの再生設定も可能にし\n // 利便性を高めた方が良いか別途検討\n const url = new URL(document.location.href)\n const notplaysinline = Number(url.searchParams.get('notplaysinline')) === 1\n if (!notplaysinline) {\n video.setAttribute('playsinline', '')\n }\n\n video.setAttribute('preload', 'auto')\n\n const errorMessage = document.createElement('div')\n errorMessage.classList.add('nekojs-player-error')\n\n if (window.parent !== window) {\n this._container.style.height = `${window.innerHeight}px`\n this._container.style.width = `${window.innerWidth}px`\n }\n this._container.appendChild(video)\n this._container.appendChild(posterImage)\n this._container.appendChild(errorMessage)\n\n Shaka.ui.Controls.registerSeekBar(this._datasource.registerSeekBarElement(this))\n this._datasource.registerControlElements(this).forEach((element, key) =>\n Shaka.ui.Controls.registerElement(key, element)\n )\n\n const player = new Shaka.Player(video)\n player.getNetworkingEngine().registerRequestFilter(this._datasource.registerRequestFilter(this))\n\n const storage = new Shaka.offline.Storage(player)\n\n const overlay = new Shaka.ui.Overlay(player, this._container, video)\n overlay.configure({ controlPanelElements: [], addSeekBar: false })\n\n this._posterImage = posterImage\n this._video = video\n this._errorMessage = errorMessage\n this._player = player\n this._storage = storage\n this._overlay = overlay\n\n this._attachEvents()\n }\n\n /**\n * DataSource の再読み込み\n * @async\n */\n async reloadData() {\n this._datasource && await this._datasource.init()\n }\n\n /**\n * DataSource.playerContentSrc() に定義されたリソースを読み込む\n * @async\n * @param {?Number} startTime default null\n * @returns {Promise}\n */\n async load(startTime = null) {\n this.trigger(NekoPlayer.Events.WillLoadManifest, this)\n\n const src = await this._datasource.playerContentSrc(this)\n if (!src) {\n return\n }\n\n // 取得したソースが mp4 の場合\n if (src.split('.').pop() === 'mp4') {\n this._video.src = src\n this._video.currentTime = startTime\n this.trigger(NekoPlayer.Events.DidLoadManifest, this, null)\n\n return\n }\n\n this._overlay.configure(this._datasource.playerUIConfigration(this))\n this._player.configure(this._datasource.playerConfigration(this))\n try {\n await this._player.load(src, startTime)\n this.trigger(NekoPlayer.Events.DidLoadManifest, this, null)\n } catch (error) {\n this.trigger(NekoPlayer.Events.DidLoadManifest, this, error)\n }\n }\n\n /**\n * 強制的に再生終了させる。\n * @async\n */\n async finishPlayback() {\n this.trigger(NekoPlayer.Events.DidFinishPlayback, this)\n this.unload()\n this._overlay.configure({ controlPanelElements: [], addSeekBar: false })\n }\n\n async unload() {\n this._player.unload()\n }\n\n removeSrc() {\n this._video.src = ''\n }\n\n /**\n * @param {string} uri\n * @param {Object} metadata\n * @returns @returns {shaka.extern.IAbortableOperation.}\n */\n async download(uri, metadata) {\n this._storage.configure(this._datasource.playerConfigration(this))\n this._storage.configure(this._datasource.playerDownloadConfigration(this))\n\n const operation = this._storage.store(uri, metadata)\n operation.promise\n .then(storedContent => this.trigger(NekoPlayer.Events.DidFinishDownload, this, storedContent))\n .catch(error => this.trigger(NekoPlayer.Events.DidFailDownload, this, error))\n }\n\n start() {\n if (this.isPausing || this.isFinished) {\n this._video.play()\n }\n }\n\n pause() {\n if (!this.isFinished && !this.isPausing) {\n this._video.pause()\n }\n }\n\n /**\n * フルスクリーン移行\n * iPhone など、Element.requestFullscreen が利用できないブラウザの場合、\n * container 要素を window サイズに合わせて擬似的にフルスクリーン化する\n */\n enterFullscreen() {\n if (this.isSupportFullscreen) {\n if (!this.isFullscreen) this._container.requestFullscreen()\n return\n }\n\n this.trigger(NekoPlayer.Events.WillEnterFullscreen, this)\n this._container.style.height = `${window.innerHeight}px`\n this._container.style.width = `${window.innerWidth}px`\n\n // タッチスクロールを無効化\n document.addEventListener('touchmove', this._disableTouchScroll, { passive: false })\n\n this.trigger(NekoPlayer.Events.DidEnterFullscreen, this)\n\n this._isFullscreen = true\n }\n\n /**\n * フルスクリーン解除\n * iPhone など、Element.requestFullscreen が利用できないブラウザの場合、\n * NekoPlayer.enterFullscreen で変更した container の heigh, width をリセット\n */\n exitFullscreen() {\n if (this.isSupportFullscreen) {\n if (this.isFullscreen) this._container.exitFullscreen()\n return\n }\n\n this._container.style.height = ''\n this._container.style.width = ''\n\n document.removeEventListener('touchmove', this._disableTouchScroll, { passive: false })\n\n this.trigger(NekoPlayer.Events.DidExitFullscreen, this)\n\n this._isFullscreen = false\n }\n\n /**\n * @param {boolean} isDark\n */\n showPosterImage(isDark = false) {\n this._posterImage.style.display = ''\n this._posterImage.style.filter = isDark ? 'brightness(0.5)' : ''\n }\n\n hidePosterImage() {\n this._posterImage.style.display = 'none'\n }\n\n /**\n * @param {string} message\n */\n showErrorMessage(message) {\n this._errorMessage.innerHTML = ''\n\n const errorText = document.createElement('p')\n errorText.classList.add('nekojs-player-error-text')\n errorText.textContent = message\n\n const errorMessageCloseButton = document.createElement('p')\n errorMessageCloseButton.classList.add('nekojs-player-error-close')\n errorMessageCloseButton.addEventListener('click', () => this.hideErrorMessage())\n\n const button = document.createElement('a')\n button.classList.add('delete', 'is-medium')\n errorMessageCloseButton.appendChild(button)\n\n this._errorMessage.appendChild(errorText)\n this._errorMessage.appendChild(errorMessageCloseButton)\n this._errorMessage.style.display = 'flex'\n }\n\n hideErrorMessage() {\n this._errorMessage.style.display = 'none'\n this._errorMessage.innerHTML = ''\n }\n\n showControls() {\n const controlsContainer = this._getControlsContainer()\n if (controlsContainer) {\n controlsContainer.style.display = ''\n }\n }\n\n hideControls() {\n const controlsContainer = this._getControlsContainer()\n if (controlsContainer) {\n controlsContainer.style.display = 'none'\n }\n }\n\n /**\n * キーボードによるプレイヤー操作を行う\n * 呼び出し元で event の伝搬を制御する可能性があるため、返り値を用意\n *\n * @param {String} key event.key の中身\n * @returns {Boolean} キーに付随するイベントを実行できていたら true\n */\n executeKeyEvent(key) {\n // NekoPlayer で対応するデフォルトキーイベントの定義を以下に追記する\n const keyEvents = {\n 'f': () => this.enterFullscreen(),\n 'm': () => this.muted = !this.isMuted,\n ' ': () => this.isPausing ? this.start() : this.pause()\n }\n\n if (keyEvents.hasOwnProperty(key)) {\n keyEvents[key]()\n return true\n }\n\n return false\n }\n\n /**\n * プレイヤーの埋め込み元から PostMessage で受け取ったメッセージの実行を行う\n * @param {Object} message\n */\n executeMessage(message) {\n if (message['event'] === 'command') {\n const commandFunctions = {\n 'playVideo': () => this.start(),\n 'pauseVideo': () => this.pause(),\n 'mute': () => this.muted = true,\n 'unMute': () => this.muted = false,\n 'showControls': () => this.showControls(),\n 'hideControls': () => this.hideControls()\n }\n const functionName = message['func']\n // [TODO] 引数が必要な Function の場合、以下の様なメッセージが必要\n // const functionArgs = message['args']\n\n if (commandFunctions.hasOwnProperty(functionName)) {\n commandFunctions[functionName]()\n }\n }\n }\n\n /**\n * IFrame などでプレイヤーを組み込んだ際に、組み込み元の Window に対してメッセージを送出する\n * この際、URL パラメータから渡された origin の値と、受信側の origin が異なる場合は xss のエラーとなる\n * [TODO] Message のやりとりや Origin の検証などは切り出して別のクラスに担当させる予定\n * @param {string} message json string\n */\n sendMessage(message) {\n const url = new URL(document.location.href)\n const origin = url.searchParams.get('origin')\n if (this._apiEnabled && origin && window.parent !== window) {\n window.parent.postMessage(message, origin)\n }\n }\n\n /**\n * @returns {HTMLElement}\n * @private\n */\n _getControlsContainer() {\n const controls = this._overlay.getControls()\n return controls ? controls.getControlsContainer() : null\n }\n\n /**\n * @private\n */\n _attachEvents() {\n const startPlaybackEventHandler = (event) => this._startPlaybackEventHandler(event)\n this._video.addEventListener('play', startPlaybackEventHandler)\n\n const pausePlaybackEventHandler = (event) => this._pausePlaybackEventHandler(event)\n this._video.addEventListener('pause', pausePlaybackEventHandler)\n\n const finishPlaybackEventHandler = (event) => this._finishPlaybackEventHandler(event)\n this._video.addEventListener('ended', finishPlaybackEventHandler)\n\n const seekingEventHandler = (event) => this._seekingEventHandler(event)\n this._video.addEventListener('seeking', seekingEventHandler)\n\n const seekedEventHandler = (event) => this._seekedEventHandler(event)\n this._video.addEventListener('seeked', seekedEventHandler)\n\n const fullscreenEventHandler = (event) => this._fullscreenEventHandler(event)\n this._container.addEventListener('fullscreenchange', fullscreenEventHandler)\n\n const resizeWindowEventHandler = (event) => this._resizeWindowEventHandler(event)\n window.addEventListener('resize', resizeWindowEventHandler)\n\n const rotateWindowEventHandler = (event) => this._rotateWindowEventHandler(event)\n window.addEventListener('orientationchange', rotateWindowEventHandler)\n\n const closeWindowEventHandler = (event) => this._closeWindowEventHandler(event)\n window.addEventListener('beforeunload', closeWindowEventHandler)\n\n const keyDownEventHandler = (event) => this._keyDownEventHandler(event)\n window.addEventListener('keydown', keyDownEventHandler)\n\n if (this._apiEnabled) {\n const receiveMessageEventHandler = (event) => this._receiveMessageEventHandler(event)\n window.addEventListener('message', receiveMessageEventHandler)\n }\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _startPlaybackEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidStartPlayback, this)\n this._video.style.filter = ''\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _pausePlaybackEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidPausePlayback, this)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _seekingEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidBeginSeeking, this)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _seekedEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidEndSeeking, this)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _finishPlaybackEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidFinishPlayback, this)\n\n // PlayReady の場合、再生後の video 要素に対して filter を変更すると、\n // DRM 保護が働くのか、画面が真っ黒になってしまうため、コメントアウトしている。\n // this._video.style.filter = 'brightness(0.5)'\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _closeWindowEventHandler(event) {\n this.trigger(NekoPlayer.Events.WillCloseWindow, this)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _resizeWindowEventHandler(event) {\n if (!this.isSupportFullscreen && this.isFullscreen) {\n // iPhone などブラウザがフルスクリーン非対応時\n this._container.style.height = `${window.innerHeight}px`\n this._container.style.width = `${window.innerWidth}px`\n\n // ツールバーの表示・非表示で位置ずれが起きるため、位置調整\n window.scrollTo(0, 0)\n }\n\n this.trigger(NekoPlayer.Events.DidResizeWindow, this)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _rotateWindowEventHandler(event) {\n let angle = screen && screen.orientation && screen.orientation.angle\n if (angle === undefined) angle = window.orientation // iOS 向け\n this.trigger(NekoPlayer.Events.DidRotateWindow, this, angle)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _fullscreenEventHandler(event) {\n if (this.isFullscreen) {\n this._container.style.width = '100%'\n this._container.style.height = '100%'\n } else {\n this._container.style.width = window.parent !== window ? `${window.innerWidth}px` : ''\n this._container.style.height = window.parent !== window ? `${window.innerHeight}px` : ''\n }\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _keyDownEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidKeyDown, this, event)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _receiveMessageEventHandler(event) {\n this.trigger(NekoPlayer.Events.DidReceiveMessage, this, event)\n }\n\n /**\n * @param {Event} event\n * @private\n */\n _disableTouchScroll(event) {\n event.preventDefault()\n }\n}\n\nNekoPlayer.Storage = class {\n /**\n * @param {Shaka.offline.Storage} storage\n */\n constructor(storage) {\n this._storage = storage\n }\n\n static removeAllContent() {\n Shaka.offline.Storage.deleteAll()\n }\n\n /** @returns {Promise.>} */\n get contents() { return this._storage.list() }\n\n /**\n * @param {function(shaka.extern.StoredContent)} term\n * @returns {Promise}\n */\n async findContent(term) {\n const contents = await this.contents\n return contents.find(term)\n }\n /**\n * @param {string} uri\n * @returns {Promise}\n */\n async contentAtOriginalUri(uri) {\n return await this.findContent(content => content.originalManifestUri === uri)\n }\n\n /**\n * @async\n * @param {string} uri\n */\n async removeAtOfflineUri(uri) {\n this._storage.remove(uri)\n }\n\n /**\n * @param {string} uri\n */\n async removeAtOriginalUri(uri) {\n const content = await this.contentAtOriginalUri(uri)\n if (content) {\n this.removeAtOfflineUri(content.offlineUri)\n }\n }\n}\n\nNekoPlayer.DataSource = class {\n constructor() {\n /** @private {ArrayBuffer} */\n this._serverCertificate = null\n }\n\n /**\n * @returns {Uint8Array}\n */\n get serverCertificate() { return new Uint8Array(this._serverCertificate) }\n\n async init() {\n // override this\n\n const request = await fetch('/fairplay.cer')\n const certificate = await request.arrayBuffer()\n this._serverCertificate = certificate\n }\n\n /**\n * プレイヤーのコントローラに利用するカスタム要素を事前登録する\n *\n * @param {NekoPlayer} player\n * @returns {Map}\n */\n registerControlElements(player) {\n // override this\n\n const elementByName = new Map()\n elementByName.set('multi_view_points_menu', new MultiViewPointsMenu.Factory(this.playSettings, this.drm, this.src, player))\n elementByName.set('manifest_menu', new ManifestMenu.Factory(this.externalManifests))\n elementByName.set('fullscreen_menu_button', new FullscreenMenuButton.Factory((menuButton) => {\n player.isFullscreen ? player.exitFullscreen() : player.enterFullscreen()\n menuButton.toggleFullscreenIcon(player.isFullscreen)\n }))\n\n return elementByName\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {Shaka.ui.SeekBar.Factory}\n */\n registerSeekBarElement(player) {\n // override this\n\n return new NekoSeekBar.Factory()\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {function(shaka.net.NetworkingEngine.RequestType, shaka.extern.Request)}\n */\n registerRequestFilter(player) {\n // override this\n\n const requestFilter = (type, request) => {\n if (type != Shaka.net.NetworkingEngine.RequestType.LICENSE) {\n return\n }\n\n // Set appropriate content-type header\n const userAgent = window.navigator.userAgent.toLocaleLowerCase();\n if (userAgent.indexOf('msie') != -1 || userAgent.indexOf('trident') != -1 || userAgent.indexOf('edg') != -1) {\n // For PlayReady\n request.headers['Content-Type'] = 'text/xml; charset=utf-8'\n } else {\n // For FairPlay. Widevine may ignore this\n request.headers['Content-Type'] = 'application/octet-stream'\n }\n }\n\n return requestFilter\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {string} poster image uri\n */\n playerPosterImageUri(player) {\n // override this\n\n return ''\n }\n\n /**\n * @async\n * @param {NekoPlayer} player\n * @returns {Promise} 再生するコンテンツのソース(URL やパス)\n */\n async playerContentSrc(player) {\n // override this\n\n return ''\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {Object} https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.PlayerConfiguration\n */\n playerConfigration(player) {\n // override this\n\n return {}\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {Object} https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.UIConfiguration\n */\n playerUIConfigration(player) {\n // override this\n\n return {}\n }\n\n /**\n * @param {NekoPlayer} player\n * @returns {Object} https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.OfflineConfiguration\n */\n playerDownloadConfigration(player) {\n // override this\n\n return { offline: {} }\n }\n}\n\nNekoPlayer.Events = {\n WillLoadManifest: Symbol('willLoadManifest'),\n DidLoadManifest: Symbol('didLoadManifest'),\n DidStartPlayback: Symbol('didStartPlayback'),\n DidPausePlayback: Symbol('didPausePlayback'),\n DidBeginSeeking: Symbol('didBeginSeeking'),\n DidEndSeeking: Symbol('didEndSeeking'),\n DidFinishPlayback: Symbol('didFinishPlayback'),\n WillEnterFullscreen: Symbol('willEnterFullscreen'),\n DidEnterFullscreen: Symbol('didEnterFullscreen'),\n DidExitFullscreen: Symbol('didExitFullscreen'),\n DidResizeWindow: Symbol('didResizeWindow'),\n DidRotateWindow: Symbol('didRotateWindow'),\n WillCloseWindow: Symbol('willCloseWindow'),\n DidDownloadProgress: Symbol('didDownloadProgress'),\n DidFinishDownload: Symbol('didFinishDownload'),\n DidFailDownload: Symbol('didFailDownload'),\n DidKeyDown: Symbol('didKeyDown'),\n DidReceiveMessage: Symbol('didReceiveMessage')\n}\n\nNekoPlayer.Error = class {\n /**\n * @todo 各エラーと対応するメッセージが確定した後、改修を予定\n * @param {shaka.util.Error} error\n */\n static parse(error) {\n if (error.code === NekoPlayer.Error.Code['BAD_HTTP_STATUS']) {\n const statusCode = error.data[1]\n const messageByStatusCode = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not Found',\n 408: 'Request Timeout'\n }\n return messageByStatusCode[statusCode] || 'Unknown Error'\n }\n return 'Unknown Error'\n }\n}\nNekoPlayer.Error.Code = Shaka.util.Error.Code\n\nexport default NekoPlayer\n","import EventEmitter from \"./movie_player/event_emitter\"\n\nclass ProgressButton extends EventEmitter {\n /**\n * @param {HTMLElement} buttonElement\n */\n constructor(buttonElement) {\n super()\n\n this._buttonElement = buttonElement\n this._progress = null\n }\n\n init() {\n this._buttonElement.addEventListener('click', (event) => this.trigger('click', this))\n\n this._progress = new ProgressButton.CircleProgress(this._buttonElement)\n this._progress.init()\n this._progress.hidden = true\n }\n\n /** @param {number} value normalize required */\n set progress(value) {\n this._progress.value = value\n }\n\n /**\n * @param {ProgressButton.Icon} value\n */\n set icon(value) {\n const icon = this._buttonElement.querySelector('i')\n icon.className = value\n }\n\n start() {\n this._progress.hidden = false\n this._buttonElement.disabled = true\n }\n\n finish() {\n this._progress.hidden = true\n this._progress.value = 0\n this._buttonElement.disabled = false\n }\n}\n\nProgressButton.Icon = {\n Download: 'mdi mdi-24px mdi-download',\n CheckUnderlineCircle: 'mdi mdi-24px mdi-check-underline-circle'\n}\n\nProgressButton.CircleProgress = class {\n /**\n * @param {HTMLElement} container\n */\n constructor(container) {\n this._container = container\n this._svg = null\n this._circle = null\n }\n\n /** @param {number} value normalize required */\n set value(value) {\n const width = this._container.clientWidth\n const height = this._container.clientHeight\n const radius = Math.min(width, height) / 2\n const length = 2 * Math.PI * radius\n this._circle.setAttribute('stroke-dashoffset', length * (1.0 - value))\n }\n\n /** @param {boolean} value */\n set hidden(value) {\n if (value) {\n this._svg.style.display = 'none'\n } else {\n this._svg.style.display = 'block'\n }\n }\n\n init() {\n const width = this._container.clientWidth\n const height = this._container.clientHeight\n const radius = Math.min(width, height) / 2\n const length = 2 * Math.PI * radius\n\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')\n circle.style.stroke = '#000'\n circle.style.strokeWidth = '2px'\n circle.setAttribute('r', radius)\n circle.setAttribute('cx', `${width / 2}`)\n circle.setAttribute('cy', `${height / 2}`)\n circle.setAttribute('fill', 'none')\n circle.setAttribute('stroke-dasharray', length)\n circle.setAttribute('stroke-dashoffset', length)\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.style.width = width\n svg.style.height = height\n svg.style.overflow = 'visible'\n svg.style.position = 'absolute'\n svg.style.transform = 'rotate(-90deg)'\n svg.setAttribute('viewbox', `0 0 ${width} ${height}`)\n svg.appendChild(circle)\n\n this._container.appendChild(svg)\n this._svg = svg\n this._circle = circle\n }\n}\n\nexport default ProgressButton\n","import Rails from '@rails/ujs'\n\nclass PlayerLogger {\n /**\n *\n * @param {string} playKey\n * @param {string} extraKey\n * @param {string} ticketId\n */\n constructor(playKey, extraKey = undefined, ticketId = undefined) {\n this._playKey = playKey\n\n this._extraKey = extraKey\n\n /** @private {string} 空の場合、文字列で 'undefined' を渡す必要がある */\n this._ticketId = ticketId || 'undefined'\n\n this._previousLogUrl = null\n }\n\n createTime() {\n // 管理画面からの視聴の場合、ログの対象外\n if (PlayerLogger._isManager()) {\n return\n }\n\n if (this._extraKey) {\n Rails.ajax({\n url: '/extras/' + this._extraKey + '/create',\n type: 'POST',\n });\n\n return\n }\n\n const formData = new FormData()\n formData.append('play_key', this._playKey)\n formData.append('my_ticket', this._ticketId)\n\n Rails.ajax({\n url: '/play_logs',\n type: 'POST',\n data: formData,\n success: (response, status, xhr) => {\n this._previousLogUrl = xhr.getResponseHeader('Location')\n }\n })\n }\n\n updateTime(currentTime) {\n // 管理画面からの視聴の場合、ログの対象外\n if (PlayerLogger._isManager()) {\n return\n }\n\n if (this._extraKey) {\n Rails.ajax({\n url: '/extras/' + this._extraKey + '/update',\n type: 'PATCH'\n })\n\n return\n }\n\n if (this._previousLogUrl) {\n const formData = new FormData()\n // TODO: currentTime が Infinity になる可能性があるため、\n // その場合に last_view_point パラメータの値が \"Infinity\" にならないようにする。\n // 一応、\"Infinity\" が送られても、バックエンドでエラーしないようにはしている。\n formData.append('last_view_point', currentTime)\n Rails.ajax({\n url: this._previousLogUrl,\n data: formData,\n type: 'PATCH'\n })\n }\n }\n\n static _isManager() {\n const brandPath = new RegExp('brand/plays/\\\\d')\n return brandPath.test(location.pathname)\n }\n}\n\nexport default PlayerLogger\n","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*!\n * JavaScript Cookie v2.2.1\n * https://github.com/js-cookie/js-cookie\n *\n * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n * Released under the MIT license\n */\n;\n\n(function (factory) {\n var registeredInModuleLoader;\n\n if (typeof define === 'function' && define.amd) {\n define(factory);\n registeredInModuleLoader = true;\n }\n\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === 'object') {\n module.exports = factory();\n registeredInModuleLoader = true;\n }\n\n if (!registeredInModuleLoader) {\n var OldCookies = window.Cookies;\n var api = window.Cookies = factory();\n\n api.noConflict = function () {\n window.Cookies = OldCookies;\n return api;\n };\n }\n})(function () {\n function extend() {\n var i = 0;\n var result = {};\n\n for (; i < arguments.length; i++) {\n var attributes = arguments[i];\n\n for (var key in attributes) {\n result[key] = attributes[key];\n }\n }\n\n return result;\n }\n\n function decode(s) {\n return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);\n }\n\n function init(converter) {\n function api() {}\n\n function set(key, value, attributes) {\n if (typeof document === 'undefined') {\n return;\n }\n\n attributes = extend({\n path: '/'\n }, api.defaults, attributes);\n\n if (typeof attributes.expires === 'number') {\n attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);\n } // We're using \"expires\" because \"max-age\" is not supported by IE\n\n\n attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\n try {\n var result = JSON.stringify(value);\n\n if (/^[\\{\\[]/.test(result)) {\n value = result;\n }\n } catch (e) {}\n\n value = converter.write ? converter.write(value, key) : encodeURIComponent(String(value)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n key = encodeURIComponent(String(key)).replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent).replace(/[\\(\\)]/g, escape);\n var stringifiedAttributes = '';\n\n for (var attributeName in attributes) {\n if (!attributes[attributeName]) {\n continue;\n }\n\n stringifiedAttributes += '; ' + attributeName;\n\n if (attributes[attributeName] === true) {\n continue;\n } // Considers RFC 6265 section 5.2:\n // ...\n // 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n // character:\n // Consume the characters of the unparsed-attributes up to,\n // not including, the first %x3B (\";\") character.\n // ...\n\n\n stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n }\n\n return document.cookie = key + '=' + value + stringifiedAttributes;\n }\n\n function get(key, json) {\n if (typeof document === 'undefined') {\n return;\n }\n\n var jar = {}; // To prevent the for loop in the first place assign an empty array\n // in case there are no cookies at all.\n\n var cookies = document.cookie ? document.cookie.split('; ') : [];\n var i = 0;\n\n for (; i < cookies.length; i++) {\n var parts = cookies[i].split('=');\n var cookie = parts.slice(1).join('=');\n\n if (!json && cookie.charAt(0) === '\"') {\n cookie = cookie.slice(1, -1);\n }\n\n try {\n var name = decode(parts[0]);\n cookie = (converter.read || converter)(cookie, name) || decode(cookie);\n\n if (json) {\n try {\n cookie = JSON.parse(cookie);\n } catch (e) {}\n }\n\n jar[name] = cookie;\n\n if (key === name) {\n break;\n }\n } catch (e) {}\n }\n\n return key ? jar[key] : jar;\n }\n\n api.set = set;\n\n api.get = function (key) {\n return get(key, false\n /* read as raw */\n );\n };\n\n api.getJSON = function (key) {\n return get(key, true\n /* read as json */\n );\n };\n\n api.remove = function (key, attributes) {\n set(key, '', extend(attributes, {\n expires: -1\n }));\n };\n\n api.defaults = {};\n api.withConverter = init;\n return api;\n }\n\n return init(function () {});\n});","import EndScreenContainer from \"./end_screen_container\"\n\n/**\n * @extends {EndScreenContainer}\n * @export\n */\nclass RecommendationContainer extends EndScreenContainer {\n /**\n * @param {!RecommendationContainer.Renderer} renderer\n */\n constructor(renderer) {\n super(renderer)\n\n this.addEvent(\n RecommendationContainer.EventKeys.ClickPageControl,\n pageNumber => {\n renderer.selectedPageNumber = pageNumber\n this.reload()\n }\n )\n this.addEvent(\n RecommendationContainer.EventKeys.ClickRecommendPanel,\n url => window.open(url, '_brank')\n )\n }\n\n hasRecommendationContents() {\n const recommendationsData = this.rootElement.dataset.recommendations\n if (recommendationsData) {\n const recommendations = JSON.parse(recommendationsData)\n const filtered = recommendations.filter(recommendation => recommendation.url.length !== 0)\n return filtered.length !== 0\n }\n\n return false\n }\n}\n\n/**\n * @implements {EndScreenContainer.Renderer}\n */\nRecommendationContainer.Renderer = class extends EndScreenContainer.Renderer {\n constructor() {\n super()\n this.selectedPageNumber = 0\n\n this._numberOfRow = 2\n this._numberOfColumn = 2\n this._splitNumber = this._numberOfRow * this._numberOfColumn\n this._panelMarginRatio = 0.1\n this._luminanceForImage = {}\n }\n\n /**\n * @override\n */\n willInsertContainerElement(recommendationContainer) {\n const container = document.createElement('div')\n container.classList.add('recommendation-container')\n return container\n }\n\n /**\n * @override\n */\n render(recommendationContainer, data) {\n const recommendations = JSON.parse(data.recommendations)\n\n // url が設定されていない物を除外\n const filteredRecommendations = recommendations.filter(recommendation => {\n return recommendation.url.length !== 0\n })\n\n const recommendPanelContainer = document.createElement('div')\n recommendPanelContainer.classList.add('recommend-panel-container')\n recommendationContainer.container.appendChild(recommendPanelContainer)\n\n // Create RecommendPanel\n\n const containerWidth = recommendPanelContainer.clientWidth\n const containerHight = recommendPanelContainer.clientHeight\n const panelMargin = containerWidth * this._panelMarginRatio\n const panelWidth = (containerWidth - panelMargin) / this._numberOfColumn\n const panelHeight = (containerHight - panelMargin) / this._numberOfRow\n const startIndex = this.selectedPageNumber * this._splitNumber\n const endIndex = startIndex + this._splitNumber\n const displayRecommendations = filteredRecommendations.slice(startIndex, endIndex)\n displayRecommendations.forEach((recommendation, index) => {\n const panel = this._createRecommendPanel(\n recommendation.url,\n recommendation.link,\n recommendation.image_url\n )\n const column = index % this._numberOfColumn\n const row = parseInt(index / this._numberOfColumn)\n\n panel.style.width = `${panelWidth}px`\n panel.style.height = `${panelHeight}px`\n panel.style.left = `${panelMargin * 0.5 / this._numberOfColumn + (panelWidth + panelMargin / this._numberOfColumn) * column}px`\n panel.style.top = `${panelMargin / this._numberOfRow + (panelHeight + panelMargin / this._numberOfRow) * row}px`\n panel.addEventListener('click', (event) =>\n recommendationContainer.trigger(\n RecommendationContainer.EventKeys.ClickRecommendPanel,\n recommendation.url\n )\n )\n recommendPanelContainer.appendChild(panel)\n })\n\n // Create PageControls\n\n const pageNumbers = parseInt(Math.ceil(filteredRecommendations.length / this._splitNumber))\n if (pageNumbers > 1) {\n // 1ページで収まらない場合に限り PageControl を表示\n\n const pageControls = document.createElement('div')\n pageControls.classList.add('recommend-page-controls')\n for (const pageNumber of Array(pageNumbers).keys()) {\n const pageControl = this._createPageControl(pageNumber)\n pageControl.addEventListener('click', (event) =>\n recommendationContainer.trigger(\n RecommendationContainer.EventKeys.ClickPageControl,\n pageNumber\n )\n )\n pageControls.appendChild(pageControl)\n }\n recommendationContainer.container.append(pageControls)\n }\n }\n\n /**\n * @param {string} url\n * @param {string} linkText\n * @param {string} imageUrl\n * @returns {HTMLElement}\n * @private\n */\n _createRecommendPanel(url, linkText, imageUrl) {\n const image = document.createElement('img')\n image.src = imageUrl || ''\n\n const title = document.createElement('figcaption')\n title.innerHTML = linkText\n\n const panel = document.createElement('figure')\n panel.dataset.url = url\n panel.classList.add('recommend-panel')\n panel.appendChild(image)\n panel.appendChild(title)\n\n return panel\n }\n\n /**\n * @param {number} pageNumber\n * @returns {HTMLElement}\n */\n _createPageControl(pageNumber) {\n const pageControl = document.createElement('a')\n pageControl.dataset.pageNumber = pageNumber\n pageControl.classList.add('page-control')\n if (pageNumber === this.selectedPageNumber) {\n pageControl.classList.add('selected')\n }\n\n return pageControl\n }\n\n /**\n * @param {string} src\n * @returns {Promise}\n * @private\n */\n _loadImage(src) {\n return new Promise((resolve, reject) => {\n if (!src) resolve(null)\n\n const image = new Image();\n image.addEventListener('load', () => resolve(image), { once: true })\n image.addEventListener('error', (event) => reject(event), { once: true })\n image.src = src\n image.crossOrigin = 'Anonymous';\n })\n }\n\n /**\n * @async\n * @param {str} imageUrl\n * @returns {Promise}\n * @private\n */\n async _getLuminanceForImage(imageUrl) {\n const image = await this._loadImage(imageUrl).catch(event => console.log(event.type))\n if (image) {\n const canvas = document.createElement('canvas');\n canvas.width = image.width\n canvas.height = image.height\n\n const canvasContext = canvas.getContext('2d')\n canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height)\n const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height)\n const data = imageData.data\n const rgbaUnit = 4\n let total = 0\n for (let i = 0; i < data.length; i += rgbaUnit) {\n // 輝度値算出(ITU-R Rec BT.709)\n total += data[i] * 0.21 + data[i + 1] * 0.72 + data[i + 2] * 0.07\n }\n\n // 輝度値の平均を正規化して返す\n return new Number(total / (data.length / rgbaUnit) / 255)\n }\n\n return new Number(1.0)\n }\n}\n\nRecommendationContainer.EventKeys = {\n ClickPageControl: Symbol('clickPageControl'),\n ClickRecommendPanel: Symbol('clickRecommendPanel')\n}\n\nexport default RecommendationContainer\n","function _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*\nUnobtrusive JavaScript\nhttps://github.com/rails/rails/blob/master/actionview/app/assets/javascripts\nReleased under the MIT license\n */\n;\n(function () {\n var context = this;\n (function () {\n (function () {\n this.Rails = {\n linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',\n buttonClickSelector: {\n selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])',\n exclude: 'form button'\n },\n inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',\n formSubmitSelector: 'form',\n formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',\n formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',\n formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',\n fileInputSelector: 'input[name][type=file]:not([disabled])',\n linkDisableSelector: 'a[data-disable-with], a[data-disable]',\n buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]'\n };\n }).call(this);\n }).call(context);\n var Rails = context.Rails;\n (function () {\n (function () {\n var nonce;\n nonce = null;\n\n Rails.loadCSPNonce = function () {\n var ref;\n return nonce = (ref = document.querySelector(\"meta[name=csp-nonce]\")) != null ? ref.content : void 0;\n };\n\n Rails.cspNonce = function () {\n return nonce != null ? nonce : Rails.loadCSPNonce();\n };\n }).call(this);\n (function () {\n var expando, m;\n m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;\n\n Rails.matches = function (element, selector) {\n if (selector.exclude != null) {\n return m.call(element, selector.selector) && !m.call(element, selector.exclude);\n } else {\n return m.call(element, selector);\n }\n };\n\n expando = '_ujsData';\n\n Rails.getData = function (element, key) {\n var ref;\n return (ref = element[expando]) != null ? ref[key] : void 0;\n };\n\n Rails.setData = function (element, key, value) {\n if (element[expando] == null) {\n element[expando] = {};\n }\n\n return element[expando][key] = value;\n };\n\n Rails.$ = function (selector) {\n return Array.prototype.slice.call(document.querySelectorAll(selector));\n };\n }).call(this);\n (function () {\n var $, csrfParam, csrfToken;\n $ = Rails.$;\n\n csrfToken = Rails.csrfToken = function () {\n var meta;\n meta = document.querySelector('meta[name=csrf-token]');\n return meta && meta.content;\n };\n\n csrfParam = Rails.csrfParam = function () {\n var meta;\n meta = document.querySelector('meta[name=csrf-param]');\n return meta && meta.content;\n };\n\n Rails.CSRFProtection = function (xhr) {\n var token;\n token = csrfToken();\n\n if (token != null) {\n return xhr.setRequestHeader('X-CSRF-Token', token);\n }\n };\n\n Rails.refreshCSRFTokens = function () {\n var param, token;\n token = csrfToken();\n param = csrfParam();\n\n if (token != null && param != null) {\n return $('form input[name=\"' + param + '\"]').forEach(function (input) {\n return input.value = token;\n });\n }\n };\n }).call(this);\n (function () {\n var CustomEvent, fire, matches, preventDefault;\n matches = Rails.matches;\n CustomEvent = window.CustomEvent;\n\n if (typeof CustomEvent !== 'function') {\n CustomEvent = function CustomEvent(event, params) {\n var evt;\n evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n preventDefault = CustomEvent.prototype.preventDefault;\n\n CustomEvent.prototype.preventDefault = function () {\n var result;\n result = preventDefault.call(this);\n\n if (this.cancelable && !this.defaultPrevented) {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function get() {\n return true;\n }\n });\n }\n\n return result;\n };\n }\n\n fire = Rails.fire = function (obj, name, data) {\n var event;\n event = new CustomEvent(name, {\n bubbles: true,\n cancelable: true,\n detail: data\n });\n obj.dispatchEvent(event);\n return !event.defaultPrevented;\n };\n\n Rails.stopEverything = function (e) {\n fire(e.target, 'ujs:everythingStopped');\n e.preventDefault();\n e.stopPropagation();\n return e.stopImmediatePropagation();\n };\n\n Rails.delegate = function (element, selector, eventType, handler) {\n return element.addEventListener(eventType, function (e) {\n var target;\n target = e.target;\n\n while (!(!(target instanceof Element) || matches(target, selector))) {\n target = target.parentNode;\n }\n\n if (target instanceof Element && handler.call(target, e) === false) {\n e.preventDefault();\n return e.stopPropagation();\n }\n });\n };\n }).call(this);\n (function () {\n var AcceptHeaders, CSRFProtection, createXHR, cspNonce, fire, prepareOptions, processResponse;\n cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection, fire = Rails.fire;\n AcceptHeaders = {\n '*': '*/*',\n text: 'text/plain',\n html: 'text/html',\n xml: 'application/xml, text/xml',\n json: 'application/json, text/javascript',\n script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'\n };\n\n Rails.ajax = function (options) {\n var xhr;\n options = prepareOptions(options);\n xhr = createXHR(options, function () {\n var ref, response;\n response = processResponse((ref = xhr.response) != null ? ref : xhr.responseText, xhr.getResponseHeader('Content-Type'));\n\n if (Math.floor(xhr.status / 100) === 2) {\n if (typeof options.success === \"function\") {\n options.success(response, xhr.statusText, xhr);\n }\n } else {\n if (typeof options.error === \"function\") {\n options.error(response, xhr.statusText, xhr);\n }\n }\n\n return typeof options.complete === \"function\" ? options.complete(xhr, xhr.statusText) : void 0;\n });\n\n if (options.beforeSend != null && !options.beforeSend(xhr, options)) {\n return false;\n }\n\n if (xhr.readyState === XMLHttpRequest.OPENED) {\n return xhr.send(options.data);\n }\n };\n\n prepareOptions = function prepareOptions(options) {\n options.url = options.url || location.href;\n options.type = options.type.toUpperCase();\n\n if (options.type === 'GET' && options.data) {\n if (options.url.indexOf('?') < 0) {\n options.url += '?' + options.data;\n } else {\n options.url += '&' + options.data;\n }\n }\n\n if (AcceptHeaders[options.dataType] == null) {\n options.dataType = '*';\n }\n\n options.accept = AcceptHeaders[options.dataType];\n\n if (options.dataType !== '*') {\n options.accept += ', */*; q=0.01';\n }\n\n return options;\n };\n\n createXHR = function createXHR(options, done) {\n var xhr;\n xhr = new XMLHttpRequest();\n xhr.open(options.type, options.url, true);\n xhr.setRequestHeader('Accept', options.accept);\n\n if (typeof options.data === 'string') {\n xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');\n }\n\n if (!options.crossDomain) {\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n }\n\n CSRFProtection(xhr);\n xhr.withCredentials = !!options.withCredentials;\n\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n return done(xhr);\n }\n };\n\n return xhr;\n };\n\n processResponse = function processResponse(response, type) {\n var parser, script;\n\n if (typeof response === 'string' && typeof type === 'string') {\n if (type.match(/\\bjson\\b/)) {\n try {\n response = JSON.parse(response);\n } catch (error) {}\n } else if (type.match(/\\b(?:java|ecma)script\\b/)) {\n script = document.createElement('script');\n script.setAttribute('nonce', cspNonce());\n script.text = response;\n document.head.appendChild(script).parentNode.removeChild(script);\n } else if (type.match(/\\b(xml|html|svg)\\b/)) {\n parser = new DOMParser();\n type = type.replace(/;.+/, '');\n\n try {\n response = parser.parseFromString(response, type);\n } catch (error) {}\n }\n }\n\n return response;\n };\n\n Rails.href = function (element) {\n return element.href;\n };\n\n Rails.isCrossDomain = function (url) {\n var e, originAnchor, urlAnchor;\n originAnchor = document.createElement('a');\n originAnchor.href = location.href;\n urlAnchor = document.createElement('a');\n\n try {\n urlAnchor.href = url;\n return !((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host || originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host);\n } catch (error) {\n e = error;\n return true;\n }\n };\n }).call(this);\n (function () {\n var matches, toArray;\n matches = Rails.matches;\n\n toArray = function toArray(e) {\n return Array.prototype.slice.call(e);\n };\n\n Rails.serializeElement = function (element, additionalParam) {\n var inputs, params;\n inputs = [element];\n\n if (matches(element, 'form')) {\n inputs = toArray(element.elements);\n }\n\n params = [];\n inputs.forEach(function (input) {\n if (!input.name || input.disabled) {\n return;\n }\n\n if (matches(input, 'fieldset[disabled] *')) {\n return;\n }\n\n if (matches(input, 'select')) {\n return toArray(input.options).forEach(function (option) {\n if (option.selected) {\n return params.push({\n name: input.name,\n value: option.value\n });\n }\n });\n } else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) {\n return params.push({\n name: input.name,\n value: input.value\n });\n }\n });\n\n if (additionalParam) {\n params.push(additionalParam);\n }\n\n return params.map(function (param) {\n if (param.name != null) {\n return encodeURIComponent(param.name) + \"=\" + encodeURIComponent(param.value);\n } else {\n return param;\n }\n }).join('&');\n };\n\n Rails.formElements = function (form, selector) {\n if (matches(form, 'form')) {\n return toArray(form.elements).filter(function (el) {\n return matches(el, selector);\n });\n } else {\n return toArray(form.querySelectorAll(selector));\n }\n };\n }).call(this);\n (function () {\n var allowAction, fire, stopEverything;\n fire = Rails.fire, stopEverything = Rails.stopEverything;\n\n Rails.handleConfirm = function (e) {\n if (!allowAction(this)) {\n return stopEverything(e);\n }\n };\n\n Rails.confirm = function (message, element) {\n return confirm(message);\n };\n\n allowAction = function allowAction(element) {\n var answer, callback, message;\n message = element.getAttribute('data-confirm');\n\n if (!message) {\n return true;\n }\n\n answer = false;\n\n if (fire(element, 'confirm')) {\n try {\n answer = Rails.confirm(message, element);\n } catch (error) {}\n\n callback = fire(element, 'confirm:complete', [answer]);\n }\n\n return answer && callback;\n };\n }).call(this);\n (function () {\n var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;\n matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;\n\n Rails.handleDisabledElement = function (e) {\n var element;\n element = this;\n\n if (element.disabled) {\n return stopEverything(e);\n }\n };\n\n Rails.enableElement = function (e) {\n var element;\n\n if (e instanceof Event) {\n if (isXhrRedirect(e)) {\n return;\n }\n\n element = e.target;\n } else {\n element = e;\n }\n\n if (matches(element, Rails.linkDisableSelector)) {\n return enableLinkElement(element);\n } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {\n return enableFormElement(element);\n } else if (matches(element, Rails.formSubmitSelector)) {\n return enableFormElements(element);\n }\n };\n\n Rails.disableElement = function (e) {\n var element;\n element = e instanceof Event ? e.target : e;\n\n if (matches(element, Rails.linkDisableSelector)) {\n return disableLinkElement(element);\n } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {\n return disableFormElement(element);\n } else if (matches(element, Rails.formSubmitSelector)) {\n return disableFormElements(element);\n }\n };\n\n disableLinkElement = function disableLinkElement(element) {\n var replacement;\n\n if (getData(element, 'ujs:disabled')) {\n return;\n }\n\n replacement = element.getAttribute('data-disable-with');\n\n if (replacement != null) {\n setData(element, 'ujs:enable-with', element.innerHTML);\n element.innerHTML = replacement;\n }\n\n element.addEventListener('click', stopEverything);\n return setData(element, 'ujs:disabled', true);\n };\n\n enableLinkElement = function enableLinkElement(element) {\n var originalText;\n originalText = getData(element, 'ujs:enable-with');\n\n if (originalText != null) {\n element.innerHTML = originalText;\n setData(element, 'ujs:enable-with', null);\n }\n\n element.removeEventListener('click', stopEverything);\n return setData(element, 'ujs:disabled', null);\n };\n\n disableFormElements = function disableFormElements(form) {\n return formElements(form, Rails.formDisableSelector).forEach(disableFormElement);\n };\n\n disableFormElement = function disableFormElement(element) {\n var replacement;\n\n if (getData(element, 'ujs:disabled')) {\n return;\n }\n\n replacement = element.getAttribute('data-disable-with');\n\n if (replacement != null) {\n if (matches(element, 'button')) {\n setData(element, 'ujs:enable-with', element.innerHTML);\n element.innerHTML = replacement;\n } else {\n setData(element, 'ujs:enable-with', element.value);\n element.value = replacement;\n }\n }\n\n element.disabled = true;\n return setData(element, 'ujs:disabled', true);\n };\n\n enableFormElements = function enableFormElements(form) {\n return formElements(form, Rails.formEnableSelector).forEach(enableFormElement);\n };\n\n enableFormElement = function enableFormElement(element) {\n var originalText;\n originalText = getData(element, 'ujs:enable-with');\n\n if (originalText != null) {\n if (matches(element, 'button')) {\n element.innerHTML = originalText;\n } else {\n element.value = originalText;\n }\n\n setData(element, 'ujs:enable-with', null);\n }\n\n element.disabled = false;\n return setData(element, 'ujs:disabled', null);\n };\n\n isXhrRedirect = function isXhrRedirect(event) {\n var ref, xhr;\n xhr = (ref = event.detail) != null ? ref[0] : void 0;\n return (xhr != null ? xhr.getResponseHeader(\"X-Xhr-Redirect\") : void 0) != null;\n };\n }).call(this);\n (function () {\n var stopEverything;\n stopEverything = Rails.stopEverything;\n\n Rails.handleMethod = function (e) {\n var csrfParam, csrfToken, form, formContent, href, link, method;\n link = this;\n method = link.getAttribute('data-method');\n\n if (!method) {\n return;\n }\n\n href = Rails.href(link);\n csrfToken = Rails.csrfToken();\n csrfParam = Rails.csrfParam();\n form = document.createElement('form');\n formContent = \"\";\n\n if (csrfParam != null && csrfToken != null && !Rails.isCrossDomain(href)) {\n formContent += \"\";\n }\n\n formContent += '';\n form.method = 'post';\n form.action = href;\n form.target = link.target;\n form.innerHTML = formContent;\n form.style.display = 'none';\n document.body.appendChild(form);\n form.querySelector('[type=\"submit\"]').click();\n return stopEverything(e);\n };\n }).call(this);\n (function () {\n var ajax,\n fire,\n getData,\n isCrossDomain,\n isRemote,\n matches,\n serializeElement,\n setData,\n stopEverything,\n slice = [].slice;\n matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;\n\n isRemote = function isRemote(element) {\n var value;\n value = element.getAttribute('data-remote');\n return value != null && value !== 'false';\n };\n\n Rails.handleRemote = function (e) {\n var button, data, dataType, element, method, url, withCredentials;\n element = this;\n\n if (!isRemote(element)) {\n return true;\n }\n\n if (!fire(element, 'ajax:before')) {\n fire(element, 'ajax:stopped');\n return false;\n }\n\n withCredentials = element.getAttribute('data-with-credentials');\n dataType = element.getAttribute('data-type') || 'script';\n\n if (matches(element, Rails.formSubmitSelector)) {\n button = getData(element, 'ujs:submit-button');\n method = getData(element, 'ujs:submit-button-formmethod') || element.method;\n url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href;\n\n if (method.toUpperCase() === 'GET') {\n url = url.replace(/\\?.*$/, '');\n }\n\n if (element.enctype === 'multipart/form-data') {\n data = new FormData(element);\n\n if (button != null) {\n data.append(button.name, button.value);\n }\n } else {\n data = serializeElement(element, button);\n }\n\n setData(element, 'ujs:submit-button', null);\n setData(element, 'ujs:submit-button-formmethod', null);\n setData(element, 'ujs:submit-button-formaction', null);\n } else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) {\n method = element.getAttribute('data-method');\n url = element.getAttribute('data-url');\n data = serializeElement(element, element.getAttribute('data-params'));\n } else {\n method = element.getAttribute('data-method');\n url = Rails.href(element);\n data = element.getAttribute('data-params');\n }\n\n ajax({\n type: method || 'GET',\n url: url,\n data: data,\n dataType: dataType,\n beforeSend: function beforeSend(xhr, options) {\n if (fire(element, 'ajax:beforeSend', [xhr, options])) {\n return fire(element, 'ajax:send', [xhr]);\n } else {\n fire(element, 'ajax:stopped');\n return false;\n }\n },\n success: function success() {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:success', args);\n },\n error: function error() {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:error', args);\n },\n complete: function complete() {\n var args;\n args = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n return fire(element, 'ajax:complete', args);\n },\n crossDomain: isCrossDomain(url),\n withCredentials: withCredentials != null && withCredentials !== 'false'\n });\n return stopEverything(e);\n };\n\n Rails.formSubmitButtonClick = function (e) {\n var button, form;\n button = this;\n form = button.form;\n\n if (!form) {\n return;\n }\n\n if (button.name) {\n setData(form, 'ujs:submit-button', {\n name: button.name,\n value: button.value\n });\n }\n\n setData(form, 'ujs:formnovalidate-button', button.formNoValidate);\n setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction'));\n return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod'));\n };\n\n Rails.preventInsignificantClick = function (e) {\n var data, insignificantMetaClick, link, metaClick, method, nonPrimaryMouseClick;\n link = this;\n method = (link.getAttribute('data-method') || 'GET').toUpperCase();\n data = link.getAttribute('data-params');\n metaClick = e.metaKey || e.ctrlKey;\n insignificantMetaClick = metaClick && method === 'GET' && !data;\n nonPrimaryMouseClick = e.button != null && e.button !== 0;\n\n if (nonPrimaryMouseClick || insignificantMetaClick) {\n return e.stopImmediatePropagation();\n }\n };\n }).call(this);\n (function () {\n var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMethod, handleRemote, loadCSPNonce, preventInsignificantClick, refreshCSRFTokens;\n fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, loadCSPNonce = Rails.loadCSPNonce, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, preventInsignificantClick = Rails.preventInsignificantClick, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMethod = Rails.handleMethod;\n\n if (typeof jQuery !== \"undefined\" && jQuery !== null && jQuery.ajax != null) {\n if (jQuery.rails) {\n throw new Error('If you load both jquery_ujs and rails-ujs, use rails-ujs only.');\n }\n\n jQuery.rails = Rails;\n jQuery.ajaxPrefilter(function (options, originalOptions, xhr) {\n if (!options.crossDomain) {\n return CSRFProtection(xhr);\n }\n });\n }\n\n Rails.start = function () {\n if (window._rails_loaded) {\n throw new Error('rails-ujs has already been loaded!');\n }\n\n window.addEventListener('pageshow', function () {\n $(Rails.formEnableSelector).forEach(function (el) {\n if (getData(el, 'ujs:disabled')) {\n return enableElement(el);\n }\n });\n return $(Rails.linkDisableSelector).forEach(function (el) {\n if (getData(el, 'ujs:disabled')) {\n return enableElement(el);\n }\n });\n });\n delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement);\n delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement);\n delegate(document, Rails.linkClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.linkClickSelector, 'click', handleConfirm);\n delegate(document, Rails.linkClickSelector, 'click', disableElement);\n delegate(document, Rails.linkClickSelector, 'click', handleRemote);\n delegate(document, Rails.linkClickSelector, 'click', handleMethod);\n delegate(document, Rails.buttonClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.buttonClickSelector, 'click', handleConfirm);\n delegate(document, Rails.buttonClickSelector, 'click', disableElement);\n delegate(document, Rails.buttonClickSelector, 'click', handleRemote);\n delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement);\n delegate(document, Rails.inputChangeSelector, 'change', handleConfirm);\n delegate(document, Rails.inputChangeSelector, 'change', handleRemote);\n delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement);\n delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm);\n delegate(document, Rails.formSubmitSelector, 'submit', handleRemote);\n delegate(document, Rails.formSubmitSelector, 'submit', function (e) {\n return setTimeout(function () {\n return disableElement(e);\n }, 13);\n });\n delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement);\n delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement);\n delegate(document, Rails.formInputClickSelector, 'click', preventInsignificantClick);\n delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement);\n delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);\n delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);\n document.addEventListener('DOMContentLoaded', refreshCSRFTokens);\n document.addEventListener('DOMContentLoaded', loadCSPNonce);\n return window._rails_loaded = true;\n };\n\n if (window.Rails === Rails && fire(document, 'rails:attachBindings')) {\n Rails.start();\n }\n }).call(this);\n }).call(this);\n\n if ((typeof module === \"undefined\" ? \"undefined\" : _typeof(module)) === \"object\" && module.exports) {\n module.exports = Rails;\n } else if (typeof define === \"function\" && define.amd) {\n define(Rails);\n }\n}).call(this);","/**\n * @export\n */\nclass EventEmitter {\n constructor() {\n this._eventHandlers = {}\n }\n\n /**\n * @param {string} eventName\n * @param {Function} handler\n */\n addEvent(eventName, handler) {\n if (!this._eventHandlers[eventName]) {\n this._eventHandlers[eventName] = []\n }\n this._eventHandlers[eventName].push(handler)\n }\n\n /**\n * @param {string} eventName\n * @param {Function} handler\n */\n deleteEvent(eventName, handler) {\n const handlers = this._eventHandlers && this._eventHandlers[eventName]\n if (handlers) {\n const filteredHandlers = handlers.filter(eventHandler => eventHandler == handler)\n this._eventHandlers[eventName] = filteredHandlers;\n }\n }\n\n /**\n * 登録されているイベントの一括削除\n */\n deleteAllEvents() {\n this._eventHandlers = {}\n }\n\n /**\n * @param {string} eventName\n * @param {...any} args\n */\n trigger(eventName, ...args) {\n const handlers = this._eventHandlers && this._eventHandlers[eventName]\n if (handlers) {\n handlers.forEach(handler => handler.apply(this, args))\n }\n }\n}\n\nexport default EventEmitter\n","class SchedulePlayer {\n /**\n * @param {NekoPlayer} player\n * @param {string} archiveUrl アーカイブ配信用の URL\n */\n constructor(player, archiveUrl) {\n this._player = player\n this._archiveUrl = archiveUrl\n this._timerTag = new SchedulePlayer.TimerTag(player.container)\n }\n\n /**\n * @param {string} now 現在時刻(ISO 8601 形式)\n * @param {string} startAt 上映会配信開始時刻(ISO 8601 形式)\n * @param {string} endAt 上映会配信終了時刻(ISO 8601 形式)\n * @param {number} duration 映像の長さ\n */\n start(now, startAt, endAt, duration) {\n const formattedStartAt = new Date(startAt).toLocaleString(undefined, { timeZoneName: 'short' })\n this._timerTag.text = `${formattedStartAt} 配信開始`\n this._player.hideControls()\n\n const timerStateByFunctions = {\n [SchedulePlayer.TimerStatus.Opening]: (timer, elapsedTime) => {\n const remainingTime = elapsedTime * -1\n const minStr = String(Math.floor(remainingTime / 60)).padStart(2, '0')\n const secStr = String((remainingTime % 60)).padStart(2, '0')\n this._timerTag.text = `あと ${minStr}:${secStr} で配信がはじまります`\n },\n [SchedulePlayer.TimerStatus.Start]: (timer, elapsedTime) => {\n (async () => {\n await this._player.reloadData()\n await this._player.load(elapsedTime)\n if (this._player.assetUri) {\n this._player.muted = true\n this._player.start()\n this._timerTag.hidden = true\n } else {\n this._timerTag.text = `${formattedStartAt} より配信中`\n }\n })()\n },\n [SchedulePlayer.TimerStatus.Finished]: (timer, elapsedTime) => {\n timer.stop()\n\n this._timerTag.hidden = false\n this._timerTag.text = '配信は終了しました' + (this._archiveUrl ? '。アーカイブは' : '')\n this._timerTag.setArchiveLink(this._archiveUrl, 'こちら')\n\n this._player.showPosterImage()\n this._player.deleteAllEvents()\n this._player.hideControls()\n this._player.finishPlayback()\n }\n }\n\n const scheduleTimer = new SchedulePlayer.Timer(now, startAt, endAt, duration)\n scheduleTimer.start((timer, state, elapsedTime) => {\n if (timerStateByFunctions.hasOwnProperty(state)) {\n timerStateByFunctions[state](timer, elapsedTime)\n }\n })\n }\n}\n\nSchedulePlayer.Constants = {\n TIMER_INTERVAL: 1000, // 更新間隔(1秒毎に表示も含め更新)\n REMINDER_THRESHOLD: -300, // 5分前\n\n // 「動画を最後まで再生した」と判断されてから配信終了するまでの時間。単位は秒。\n //\n // 動画の長さと経過時間を見て「動画を最後まで再生したか」の判断をしているため、\n // 途中で一時停止をしなくても、実際に最後まで再生しきる直前に「最後まで再生した」と判断されてしまうことがある。\n // そこで、「最後まで再生した」と判断されてから配信終了するまでの時間に少し余裕をもたせる。\n MARGIN_TIME: 5\n}\n\nSchedulePlayer.TimerStatus = {\n Idling: Symbol('idling'),\n Opening: Symbol('opening'),\n Start: Symbol('start'),\n Playing: Symbol('playing'),\n Finished: Symbol('finished'),\n Unknown: Symbol('unknown')\n}\n\nSchedulePlayer.Timer = class {\n /**\n * @param {string} now 現在時刻(ISO 8601 形式)\n * @param {string} startAt 上映会配信開始時刻(ISO 8601 形式)\n * @param {string} endAt 上映会配信終了時刻(ISO 8601 形式)\n * @param {number} duration 映像の長さ\n */\n constructor(now, startAt, endAt, duration) {\n this._now = new Date(now)\n this._startAt = new Date(startAt)\n this._endAt = new Date(endAt)\n this._movieDuration = duration\n this._intervalTimer = null\n this._count = 0\n this._started = false\n }\n\n /**\n * @callback TimerCallback\n * @param {SchedulePlayer.Timer} timer\n * @param {SchedulePlayer.TimerStatus} state\n * @param {Number} elapsedTime\n */\n\n /**\n * @param {TimerCallback} callback\n */\n start(callback) {\n this.stop()\n this._intervalTimer = setInterval(\n () => this._countdown(callback),\n SchedulePlayer.Constants.TIMER_INTERVAL\n )\n // タイマー開始までのラグがあるため初回は即時呼ぶ\n this._countdown(callback)\n }\n\n stop() {\n this._stopCountdown()\n }\n\n /**\n * @param {TimerCallback} callback\n * @private\n */\n _countdown(callback) {\n const remainingTime = (this._startAt - this._now) / 1000\n const missedTime = -remainingTime\n const playDuration = (this._endAt - this._startAt) / 1000\n const elapsedTime = this._count - remainingTime\n\n let timerState = SchedulePlayer.TimerStatus.Unknown\n if (elapsedTime > playDuration || elapsedTime > this._movieDuration + SchedulePlayer.Constants.MARGIN_TIME) {\n // 上映会の配信終了時刻を過ぎた場合、または動画を最後まで再生し終わった場合\n\n timerState = SchedulePlayer.TimerStatus.Finished\n } else if (elapsedTime > 0) {\n // 既に配信が開始されている場合\n\n if (!this._started) {\n // 一度 TimerStatus.Start を返す\n this._started = true;\n callback(this, SchedulePlayer.TimerStatus.Start, missedTime)\n }\n timerState = SchedulePlayer.TimerStatus.Playing\n } else {\n if (elapsedTime >= 0) {\n // 配信開始時刻を経過した場合\n this._started = true\n timerState = SchedulePlayer.TimerStatus.Start\n } else if (elapsedTime >= SchedulePlayer.Constants.REMINDER_THRESHOLD) {\n // 配信開始 n 分前\n timerState = SchedulePlayer.TimerStatus.Opening\n } else {\n // 配信開始前\n timerState = SchedulePlayer.TimerStatus.Idling\n }\n }\n\n callback(this, timerState, elapsedTime)\n this._count++\n }\n\n /**\n * @private\n */\n _stopCountdown() {\n this._count = 0\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer)\n this._intervalTimer = null\n }\n }\n}\n\n/**\n *
\n * \n * text link text \n * \n *
\n */\nSchedulePlayer.TimerTag = class {\n\n /**\n * @param {HTMLElement} parentElement\n */\n constructor(parentElement) {\n const tagElement = document.createElement('div')\n tagElement.id = 'schedule-timer-tag'\n tagElement.classList.add('tag', 'is-medium', 'is-rounded', 'is-light')\n\n const textElement = document.createElement('span')\n const archiveLinkElement = document.createElement('a')\n\n tagElement.appendChild(textElement)\n tagElement.appendChild(archiveLinkElement)\n parentElement.appendChild(tagElement)\n\n this._tagElement = tagElement\n this._textElement = textElement\n this._archiveLinkElement = archiveLinkElement\n }\n\n get htmlElement() { return this._tagElement }\n\n /**\n * @param {string} value アーカイブ配信用 URL\n */\n set archiveLinkUrl(value) {\n this._archiveLinkElement.href = value\n this._archiveLinkElement.style.display = value ? 'inline' : 'none'\n }\n\n /**\n * @param {string} value アーカイブ配信用リンクテキスト\n */\n set archiveLinkText(value) {\n this._archiveLinkElement.textContent = value\n }\n\n /**\n * @param {string} value タイマータグ表示用のテキスト\n */\n set text(value) {\n this._textElement.textContent = value\n }\n\n /**\n * @param {Boolean} enable タイマータグの表示/非表示\n */\n set hidden(enable) {\n this._tagElement.style.display = enable ? 'none' : 'block'\n }\n\n /**\n * アーカイブ配信用の URL とリンクテキストを設定\n * @param {string} url\n * @param {string} linkText\n */\n setArchiveLink(url, linkText) {\n this.archiveLinkText = linkText\n this.archiveLinkUrl = url\n }\n}\n\nexport default SchedulePlayer\n","import EventEmitter from \"./event_emitter\"\n\n/**\n * @extends {EventEmitter}\n */\nclass EndScreenContainer extends EventEmitter {\n /**\n * @param {!EndScreenContainer.Renderer} renderer\n * @param {string} rootElementId\n */\n constructor(renderer, rootElementId = 'player-container') {\n super()\n\n /** @private {!EndScreenContainer.Renderer} */\n this._renderer = renderer ? renderer : new EndScreenContainer.Renderer()\n\n /** @private {!HTMLElement} */\n this._rootElement = document.getElementById(rootElementId)\n\n /** @private {HTMLElement} */\n this._container = null\n\n /** @private {boolean} */\n this._isHidden = false\n\n window.addEventListener('resize', () => this.reload())\n }\n\n get rootElement() {\n return this._rootElement\n }\n\n get container() {\n return this._container\n }\n\n get isHidden() {\n return this._isHidden\n }\n\n load() {\n this._container = this._renderer.willInsertContainerElement(this)\n this._rootElement.appendChild(this._container)\n this._renderer.didInsertContainerElement(this)\n this._renderer.render(this, this._rootElement.dataset)\n }\n\n reload() {\n if (!this._isHidden && this._container) {\n this._container.remove()\n this._container = null\n this.load()\n }\n }\n\n show() {\n if (this._container) {\n this._isHidden = false\n this._container.classList.remove('is-hidden')\n this.reload();\n }\n }\n\n hidden() {\n if (this._container) {\n this._isHidden = true\n this._container.classList.add('is-hidden')\n }\n }\n}\n\nEndScreenContainer.Renderer = class {\n constructor() {\n }\n\n /**\n * @param {EndScreenContainer} endScreenContainer\n * @returns {HTMLElement}\n */\n willInsertContainerElement(endScreenContainer) {\n // override this\n return document.createElement('div')\n }\n\n /**\n * @param {EndScreenContainer} endScreenContainer\n */\n didInsertContainerElement(endScreenContainer) {\n // override this\n }\n\n /**\n * @param {EndScreenContainer} endScreenContainer\n * @param {Object} data\n */\n render(endScreenContainer, data) {\n // override this\n }\n}\n\nexport default EndScreenContainer\n","import Shaka from 'shaka-player/dist/shaka-player.ui'\n\nclass NekoSeekBar extends Shaka.ui.SeekBar {\n /**\n * @param {!HTMLElement} parent\n * @param {!Shaka.ui.Controls} controls\n */\n constructor(parent, controls) {\n super(parent, controls)\n\n const timeTip = document.createElement('label')\n timeTip.setAttribute('style',\n `display: none; position: absolute; background: #262626;\n font-family: Varela; font-size: 11px; bottom: 1rem;\n color: #fff; letter-spacing: 1.1px; padding: 2px 5px;\n transition: left 0.1s ease;`\n )\n\n const thumbnailTip = document.createElement('img')\n thumbnailTip.setAttribute('style',\n `display: none; position: absolute; bottom: 1rem;`\n )\n\n this.container.appendChild(timeTip)\n this.container.appendChild(thumbnailTip)\n\n this._timeTip = timeTip\n this._thumbnailTip = thumbnailTip\n\n this.eventManager.listen(this.container, 'mousemove', (event) => {\n this._timeTip.style.display = 'block'\n this._updateTip(event.offsetX)\n })\n this.eventManager.listen(this.container, 'mouseleave', (event) => {\n this._timeTip.style.display = 'none'\n })\n }\n\n /**\n * @override\n */\n release() {\n this._timeTip.remove()\n this._timeTip = null\n\n super.release()\n }\n\n /**\n * @param {Number} positionX\n * @private\n */\n _updateTip(positionX) {\n const seekRange = this.player.seekRange()\n const seekRangeSize = seekRange.end - seekRange.start\n const normalizeX = positionX / this.container.getBoundingClientRect().width\n const currentTime = seekRangeSize * normalizeX\n\n this._updateTimeTip(positionX, currentTime)\n }\n\n /**\n * @param {Number} positionX\n * @param {Number} currentTime\n * @private\n */\n _updateTimeTip(positionX, currentTime) {\n const hours = Math.floor(currentTime / 3600)\n const minutes = Math.floor((currentTime - (hours * 3600)) / 60)\n const seconds = Math.floor(currentTime - (hours * 3600) - (minutes * 60))\n const hoursStr = String(hours).padStart(2, '0') + ':'\n const minutesStr = String(minutes).padStart(2, '0') + ':'\n const secondsStr = String(seconds).padStart(2, '0')\n\n this._timeTip.innerText = ((hours === 0) ? '' : hoursStr) + minutesStr + secondsStr\n this._timeTip.style.left = `${positionX - (this._timeTip.clientWidth / 2)}px`\n }\n\n /**\n * 未使用\n * [NOTE]\n * サムネイルは別途トラックが必要になるため、パッケージング時に\n * ImageTrack の追加が必要になる\n * @private\n */\n _updatteThumbnailTip(currentTime) {\n const tracks = this.player.getImageTracks()\n const activeTrack = tracks.find(track => track.active)\n if (activeTrack) {\n this.player.getThumbnails(activeTrack.id, currentTime)\n .then(thumbnail => console.log(thumbnail))\n .catch(error => console.error(error))\n }\n }\n}\n\nNekoSeekBar.Factory = class {\n create(rootElement, controls) {\n return new NekoSeekBar(rootElement, controls)\n }\n}\n\nexport default NekoSeekBar\n"],"sourceRoot":""}