diff options
394 files changed, 37095 insertions, 3360 deletions
diff --git a/.gitignore b/.gitignore index d65eb08d45..39ef1aa169 100644 --- a/.gitignore +++ b/.gitignore @@ -309,6 +309,7 @@ lib/cpluff/stamp-h1 #/tools/depends /tools/depends/native/*/*native/ +/tools/depends/target/*/aarch64-linux-gnu/ /tools/depends/native/JsonSchemaBuilder/bin/ /tools/depends/native/TexturePacker/bin/ /tools/depends/target/ffmpeg/.ffmpeg-installed diff --git a/CMakeLists.txt b/CMakeLists.txt index 87550ed2e5..cf04bc1738 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -193,7 +193,7 @@ endif() if(NOT WIN32) core_optional_dep(OpenGl) - if(OPENGL_FOUND) + if(OPENGL_FOUND AND NOT APPLE) if(ENABLE_MIR) core_require_dep(Mir ENABLE_MIR) core_optional_dep(LibDRM ENABLE_MIR) diff --git a/addons/kodi.game/addon.xml b/addons/kodi.game/addon.xml index e50d0395dc..5132ad9038 100644 --- a/addons/kodi.game/addon.xml +++ b/addons/kodi.game/addon.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="kodi.game" version="1.0.28" provider-name="Team-Kodi"> - <backwards-compatibility abi="1.0.28"/> +<addon id="kodi.game" version="1.0.29" provider-name="Team-Kodi"> + <backwards-compatibility abi="1.0.29"/> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/addons/kodi.imagedecoder/addon.xml b/addons/kodi.imagedecoder/addon.xml new file mode 100644 index 0000000000..aa0af75ad1 --- /dev/null +++ b/addons/kodi.imagedecoder/addon.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<addon id="kodi.imagedecoder" version="1.0.0" provider-name="Team Kodi"> + <backwards-compatibility abi="1.0.0"/> + <requires> + <import addon="xbmc.core" version="0.1.0"/> + </requires> +</addon> diff --git a/addons/kodi.peripheral/addon.xml b/addons/kodi.peripheral/addon.xml index 97680ca5fa..8b804b83ae 100644 --- a/addons/kodi.peripheral/addon.xml +++ b/addons/kodi.peripheral/addon.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="kodi.peripheral" version="1.2.1" provider-name="Team-Kodi"> - <backwards-compatibility abi="1.2.0"/> +<addon id="kodi.peripheral" version="1.3.0" provider-name="Team-Kodi"> + <backwards-compatibility abi="1.3.0"/> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/addons/metadata.demo.artists/demo.py b/addons/metadata.demo.artists/demo.py index 819528cda2..98f071ba80 100644 --- a/addons/metadata.demo.artists/demo.py +++ b/addons/metadata.demo.artists/demo.py @@ -46,6 +46,9 @@ if action == 'find': liz.setProperty('artist.genre', 'classical / jazz') liz.setProperty('artist.born', '2012') xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url="/path/to/artist2", listitem=liz, isFolder=True) +elif action == 'resolveid': + liz=xbmcgui.ListItem(path='/path/to/artist2', offscreen=True) + xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=liz) elif action == 'getdetails': url=urllib.unquote_plus(params["url"]) print 'Artist with url %s' %(url) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 9afb799cfa..016aa88a09 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -23,33 +23,33 @@ msgstr "" #: xbmc/addons/Addon.cpp #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#0" msgid "Programs" msgstr "" -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Custom_1103_SourcesDialog.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Custom_1103_SourcesDialog.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#1" msgid "Pictures" msgstr "" -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/Custom_1103_SourcesDialog.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/Custom_1103_SourcesDialog.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#2" msgid "Music" msgstr "" #: system/settings/settings.xml #: xbmc/media/MediaTypes.cpp -#: addons/skin.estuary/1080i/Custom_1103_SourcesDialog.xml -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Custom_1103_SourcesDialog.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#3" msgid "Videos" msgstr "" @@ -59,7 +59,7 @@ msgid "TV guide" msgstr "" #: xbmc/windows/GUIWindowFileManager.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#5" msgid "Settings" msgstr "" @@ -77,9 +77,9 @@ msgctxt "#7" msgid "File manager" msgstr "" -#: addons/skin.estuary/1080i/Includes.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Includes.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#8" msgid "Weather" msgstr "" @@ -429,7 +429,7 @@ msgctxt "#111" msgid "Shortcuts" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#112" msgid "Paused" msgstr "" @@ -516,8 +516,8 @@ msgstr "" #: xbmc/addons/guidialogaddonsettings.cpp #: system/settings/settings.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/SettingsProfile.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/SettingsProfile.xml msgctxt "#128" msgid "General" msgstr "" @@ -551,7 +551,7 @@ msgstr "" #: xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#133" msgid "Artists" msgstr "" @@ -578,13 +578,13 @@ msgid "Playlists" msgstr "" #: xbmc/addons/GUIViewStateAddonBrowser.cpp -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#137" msgid "Search" msgstr "" -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#138" msgid "System information" msgstr "" @@ -609,7 +609,7 @@ msgctxt "#143" msgid "Current:" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#144" msgid "Build:" msgstr "" @@ -665,7 +665,7 @@ msgid "Free" msgstr "" #: xbmc/settings/dialogs/GUIDialogAudioDSPSettings.cpp -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#157" msgid "Video" msgstr "" @@ -683,7 +683,7 @@ msgctxt "#160" msgid "Free" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#161" msgid "Unavailable" msgstr "" @@ -722,7 +722,7 @@ msgid "%s- %s" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#169" msgid "Resolution" msgstr "" @@ -747,13 +747,13 @@ msgctxt "#173" msgid "Display 4:3 videos as" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#174" msgid "Compiled:" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#175" msgid "Moods" msgstr "" @@ -784,9 +784,9 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/playlists/SmartPlaylist.cpp #: xbmc/xbmc/pvr/windows/GUIViewStatePVR.cpp -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/View_51_Poster.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/View_51_Poster.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#180" msgid "Duration" msgstr "" @@ -816,7 +816,7 @@ msgstr "" #: xbmc/addons/GUIViewStateAddonBrowser.cpp #: xbmc/dialogs/GUIDialogSelect.cpp -#: addons/skin.estuary/1080i/DialogPVRGroupManager.xml +#: addons/skin.estuary/xml/DialogPVRGroupManager.xml msgctxt "#186" msgid "OK" msgstr "" @@ -916,24 +916,24 @@ msgctxt "#205" msgid "Votes" msgstr "" -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml -#: addons/skin.estuary/1080i/DialogPVRInfo.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml msgctxt "#206" msgid "Cast" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml -#: addons/skin.estuary/1080i/DialogPVRInfo.xml -#: addons/skin.estuary/1080i/Includes_PVR.xml -#: addons/skin.estuary/1080i/MyVideoNav.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml +#: addons/skin.estuary/xml/Includes_PVR.xml +#: addons/skin.estuary/xml/MyVideoNav.xml msgctxt "#207" msgid "Plot" msgstr "" #. generic "play" (some sort of media) label used in different places -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml #: xbmc/dialogs/GUIDialogPlayEject.cpp #: xbmc/games/windows/GUIWindowGames.cpp #: xbmc/video/ContextMenus.cpp @@ -944,7 +944,7 @@ msgid "Play" msgstr "" #. used as label for an action/button to play or navigate to the next item -#: addons/skin.estuary/1080i/VideoOSD.xml +#: addons/skin.estuary/xml/VideoOSD.xml msgctxt "#209" msgid "Next" msgstr "" @@ -1017,7 +1017,7 @@ msgctxt "#221" msgid "Network is not connected" msgstr "" -#: addons/skin.estuary/1080i/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml msgctxt "#222" msgid "Cancel" msgstr "" @@ -1117,7 +1117,7 @@ msgctxt "#243" msgid "Refresh rate" msgstr "" -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#244" msgid "Full screen" msgstr "" @@ -1147,7 +1147,7 @@ msgid "Music" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Custom_1105_MusicOSDSettings.xml +#: addons/skin.estuary/xml/Custom_1105_MusicOSDSettings.xml msgctxt "#250" msgid "Visualisation" msgstr "" @@ -1216,7 +1216,7 @@ msgstr "" #: xbmc/music/windows/GUIWindowMusicBase.cpp #: xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp #: xbmc/pvr/PVRContextMenus.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#264" msgid "Record" msgstr "" @@ -1328,7 +1328,7 @@ msgid "Font" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#289" msgid "Size" msgstr "" @@ -1365,8 +1365,8 @@ msgctxt "#297" msgid "Audio offset" msgstr "" -#: addons/skin.estuary/1080i/VideoOSD.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/VideoOSD.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#298" msgid "Bookmarks" msgstr "" @@ -1566,8 +1566,8 @@ msgid "Play disc" msgstr "" #: xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/SkinSettings.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/SkinSettings.xml msgctxt "#342" msgid "Movies" msgstr "" @@ -1583,7 +1583,7 @@ msgctxt "#344" msgid "Actors" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#345" msgid "Year" msgstr "" @@ -1859,7 +1859,7 @@ msgid "Temp" msgstr "" #: xbmc/windows/GUIWindowWeather.cpp -#: addons/skin.estuary/1080i/MyWeather.xml +#: addons/skin.estuary/xml/MyWeather.xml msgctxt "#402" msgid "Feels like" msgstr "" @@ -1916,7 +1916,7 @@ msgid "Downloading thumbnail..." msgstr "" #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml msgctxt "#416" msgid "Not available" msgstr "" @@ -2088,7 +2088,7 @@ msgctxt "#455" msgid "Rows" msgstr "" -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#456" msgid "Mode" msgstr "" @@ -2137,7 +2137,7 @@ msgctxt "#466" msgid "Gamma" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#467" msgid "Type" msgstr "" @@ -2185,7 +2185,7 @@ msgid "Skin & language" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#480" msgid "Appearance" msgstr "" @@ -2204,8 +2204,8 @@ msgctxt "#485" msgid "Delete album" msgstr "" -#: addons/skin.estuary/1080i/PlayerControls.xml -#: addons/skin.estuary/1080i/MusicOSD.xml +#: addons/skin.estuary/xml/PlayerControls.xml +#: addons/skin.estuary/xml/MusicOSD.xml msgctxt "#486" msgid "Repeat" msgstr "" @@ -2319,13 +2319,13 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/MyPVRRecordings.xml -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/DialogPVRInfo.xml -#: addons/skin.estuary/1080i/MyPVRGuide.xml -#: addons/skin.estuary/1080i/View_51_Poster.xml -#: addons/skin.estuary/1080i/Includes_PVR.xml -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/MyPVRRecordings.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml +#: addons/skin.estuary/xml/MyPVRGuide.xml +#: addons/skin.estuary/xml/View_51_Poster.xml +#: addons/skin.estuary/xml/Includes_PVR.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#515" msgid "Genre" msgstr "" @@ -2406,8 +2406,8 @@ msgctxt "#534" msgid "View: %s" msgstr "" -#: addons/skin.estuary/1080i/View_50_List.xml -#: addons/skin.estuary/1080i/EventLog.xml +#: addons/skin.estuary/xml/View_50_List.xml +#: addons/skin.estuary/xml/EventLog.xml msgctxt "#535" msgid "List" msgstr "" @@ -2487,7 +2487,7 @@ msgid "Name" msgstr "" #. generic "date" label used in different places -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml #: xbmc/xbmc/pvr/windows/GUIViewStatePVR.cpp msgctxt "#552" msgid "Date" @@ -2510,7 +2510,7 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#556" msgid "Title" msgstr "" @@ -2519,7 +2519,7 @@ msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#557" msgid "Artist" msgstr "" @@ -2528,7 +2528,7 @@ msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#558" msgid "Album" msgstr "" @@ -2558,8 +2558,8 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/playlists/SmartPlaylist.cpp #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp -#: addons/skin.estuary/1080i/DialogVideoInfo.xml -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml msgctxt "#563" msgid "Rating" msgstr "" @@ -2580,7 +2580,7 @@ msgid "Album artist" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#567" msgid "Play count" msgstr "" @@ -2594,7 +2594,7 @@ msgid "Last played" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#569" msgid "Comment" msgstr "" @@ -2665,13 +2665,13 @@ msgid "Remember views for different folders" msgstr "" #: xbmc/view/GUIViewState.cpp -#: addons/skin.estuary/1080i/EventLog.xml +#: addons/skin.estuary/xml/EventLog.xml msgctxt "#584" msgid "Ascending" msgstr "" #: xbmc/view/GUIViewState.cpp -#: addons/skin.estuary/1080i/EventLog.xml +#: addons/skin.estuary/xml/EventLog.xml msgctxt "#585" msgid "Descending" msgstr "" @@ -2680,7 +2680,7 @@ msgctxt "#586" msgid "Edit playlist" msgstr "" -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#587" msgid "Filter" msgstr "" @@ -2689,15 +2689,15 @@ msgctxt "#588" msgid "Cancel party mode" msgstr "" -#: addons/skin.estuary/1080i/MyVideoNav.xml -#: addons/skin.estuary/1080i/MyMusicNav.xml +#: addons/skin.estuary/xml/MyVideoNav.xml +#: addons/skin.estuary/xml/MyMusicNav.xml msgctxt "#589" msgid "Party mode" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/PlayerControls.xml -#: addons/skin.estuary/1080i/MusicOSD.xml +#: addons/skin.estuary/xml/PlayerControls.xml +#: addons/skin.estuary/xml/MusicOSD.xml msgctxt "#590" msgid "Random" msgstr "" @@ -2785,13 +2785,13 @@ msgctxt "#611" msgid "Enter number" msgstr "" -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#612" msgid "Bits/sample" msgstr "" #: xbmc/settings/dialogs/GUIDialogAudioDSPSettings.cpp -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#613" msgid "Sample rate" msgstr "" @@ -2819,7 +2819,7 @@ msgid "Quality" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#623" msgid "Bitrate" msgstr "" @@ -2957,8 +2957,8 @@ msgctxt "#652" msgid "Years" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/MyVideoNav.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/MyVideoNav.xml msgctxt "#653" msgid "Update library" msgstr "" @@ -3228,7 +3228,7 @@ msgid "Character set" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#736" msgid "Style" msgstr "" @@ -3365,7 +3365,7 @@ msgctxt "#772" msgid "Audio" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#773" msgid "Seeking" msgstr "" @@ -3788,7 +3788,7 @@ msgctxt "#1007" msgid "Add network location" msgstr "" -#: addons/skin.estuary/1080i/DialogNetworkSetup.xml +#: addons/skin.estuary/xml/DialogNetworkSetup.xml msgctxt "#1008" msgid "Protocol" msgstr "" @@ -3813,12 +3813,12 @@ msgctxt "#1012" msgid "Shared folder" msgstr "" -#: addons/skin.estuary/1080i/DialogNetworkSetup.xml +#: addons/skin.estuary/xml/DialogNetworkSetup.xml msgctxt "#1013" msgid "Port" msgstr "" -#: addons/skin.estuary/1080i/DialogNetworkSetup.xml +#: addons/skin.estuary/xml/DialogNetworkSetup.xml msgctxt "#1014" msgid "Username" msgstr "" @@ -3851,13 +3851,13 @@ msgstr "" #empty string with id 1020 #: xbmc/dialogs/GUIDialogMediaSource.cpp -#: addons/skin.estuary/1080i/DialogMediaSource.xml +#: addons/skin.estuary/xml/DialogMediaSource.xml msgctxt "#1021" msgid "Enter the paths or browse for the media locations." msgstr "" #: xbmc/dialogs/GUIDialogMediaSource.cpp -#: addons/skin.estuary/1080i/DialogMediaSource.xml +#: addons/skin.estuary/xml/DialogMediaSource.xml msgctxt "#1022" msgid "Enter a name for this media source." msgstr "" @@ -3867,8 +3867,8 @@ msgctxt "#1023" msgid "Browse for new share" msgstr "" -#: addons/skin.estuary/1080i/DialogNetworkSetup.xml -#: addons/skin.estuary/1080i/SmartPlaylistRule.xml +#: addons/skin.estuary/xml/DialogNetworkSetup.xml +#: addons/skin.estuary/xml/SmartPlaylistRule.xml msgctxt "#1024" msgid "Browse" msgstr "" @@ -3929,19 +3929,19 @@ msgid "Favourites" msgstr "" #: xbmc/addons/Addon.cpp -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#1037" msgid "Video add-ons" msgstr "" #: xbmc/addons/Addon.cpp -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#1038" msgid "Music add-ons" msgstr "" #: xbmc/addons/Addon.cpp -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#1039" msgid "Picture add-ons" msgstr "" @@ -4687,7 +4687,7 @@ msgstr "" #: xbmc/addons/GUIDialogAddonSettings.cpp #: xbmc/guilib/WindowIDs.h -#: addons/skin.estuary/1080i/AddonBrowser.xml +#: addons/skin.estuary/xml/AddonBrowser.xml #: xbmc/settings/dialogs/GUIDialogContentSettings.cpp msgctxt "#10004" msgid "Settings" @@ -4990,7 +4990,7 @@ msgctxt "#10139" msgid "Pictures / Info" msgstr "" -#: addons/skin.estuary/1080i/MyGames.xml +#: addons/skin.estuary/xml/MyGames.xml #: xbmc/guilib/WindowIDs.h msgctxt "#10140" msgid "Add-on settings" @@ -5203,61 +5203,61 @@ msgstr "" #empty strings from id 12024 to 12309 -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12310" msgid "0" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12311" msgid "1" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12312" msgid "2" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12313" msgid "3" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12314" msgid "4" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12315" msgid "5" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12316" msgid "6" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12317" msgid "7" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12318" msgid "8" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogNumeric.xml #: addons/skin.estouchy/xml/DialogNumeric.xml msgctxt "#12319" msgid "9" @@ -5522,7 +5522,7 @@ msgid "System uptime" msgstr "" #: xbmc/utils/SystemInfo.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#12391" msgid "Minutes" msgstr "" @@ -5570,7 +5570,7 @@ msgstr "" #string id 12902 to 12905 match in WindowIDs.h #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#13000" msgid "System" msgstr "" @@ -5614,25 +5614,25 @@ msgid "Quit" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13010" msgid "Hibernate" msgstr "" #: system/settings/settings.xml #: system/peripherals.xml -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13011" msgid "Suspend" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml #: addons/skin.estouchy/xml/Home.xml msgctxt "#13012" msgid "Exit" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13013" msgid "Reboot" msgstr "" @@ -5647,17 +5647,17 @@ msgctxt "#13015" msgid "Power button action" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13016" msgid "Power off system" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13017" msgid "Inhibit idle shutdown" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#13018" msgid "Allow idle shutdown" msgstr "" @@ -5919,7 +5919,7 @@ msgstr "" #empty strings from id 13163 to 13169 -#: addons/skin.estuary/1080i/SettingsProfile.xml +#: addons/skin.estuary/xml/SettingsProfile.xml msgctxt "#13170" msgid "Never" msgstr "" @@ -5949,8 +5949,8 @@ msgstr "" #: addons/skin.estouchy/xml/SettingsProfile.xml #: xbmc/profiles/ProfilesManager.cpp #: xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp -#: addons/skin.estuary/1080i/SettingsProfile.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/SettingsProfile.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#13200" msgid "Profiles" msgstr "" @@ -6060,7 +6060,7 @@ msgid "Hardware:" msgstr "" #: xbmc/windows/GUIWindowSystemInfo.cpp -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#13271" msgid "System CPU usage:" msgstr "" @@ -6079,7 +6079,7 @@ msgctxt "#13276" msgid "DVD-ROM" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#13277" msgid "Storage" msgstr "" @@ -6088,17 +6088,17 @@ msgctxt "#13278" msgid "Default" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#13279" msgid "Network" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#13280" msgid "Video" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#13281" msgid "Hardware" msgstr "" @@ -6229,18 +6229,18 @@ msgctxt "#13316" msgid "Recursive thumbnails" msgstr "" -#: addons/skin.estuary/1080i/MyPics.xml +#: addons/skin.estuary/xml/MyPics.xml msgctxt "#13317" msgid "View slideshow" msgstr "" -#: addons/skin.estuary/1080i/MyPics.xml +#: addons/skin.estuary/xml/MyPics.xml msgctxt "#13318" msgid "Recursive slideshow" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/MyPics.xml +#: addons/skin.estuary/xml/MyPics.xml msgctxt "#13319" msgid "Randomise" msgstr "" @@ -6370,8 +6370,8 @@ msgctxt "#13352" msgid "Scan item to library" msgstr "" -#: addons/skin.estuary/1080i/MyVideoNav.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/MyVideoNav.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#13353" msgid "Stop scanning" msgstr "" @@ -6464,7 +6464,7 @@ msgctxt "#13387" msgid "Track naming template - right" msgstr "" -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#13388" msgid "Preset" msgstr "" @@ -6499,15 +6499,15 @@ msgid "Calculating folder size" msgstr "" #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/Custom_1106_VideoOSDSettings.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/Custom_1106_VideoOSDSettings.xml msgctxt "#13395" msgid "Video settings" msgstr "" #: xbmc/video/dialogs/GUIDialogAudioSubtitleSettings.cpp -#: addons/skin.estuary/1080i/Custom_1106_VideoOSDSettings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Custom_1106_VideoOSDSettings.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#13396" msgid "Audio and subtitle settings" msgstr "" @@ -7036,7 +7036,7 @@ msgctxt "#14017" msgid "Percentage of thumbs" msgstr "" -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#14018" msgid "View options" msgstr "" @@ -7118,7 +7118,7 @@ msgid "Local network" msgstr "" #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#14036" msgid "Services" msgstr "" @@ -7941,8 +7941,8 @@ msgctxt "#15019" msgid "Add" msgstr "" -#: addons/skin.estuary/1080i/Custom_1106_VideoOSDSettings.xml -#: addons/skin.estuary/1080i/Custom_1105_MusicOSDSettings.xml +#: addons/skin.estuary/xml/Custom_1106_VideoOSDSettings.xml +#: addons/skin.estuary/xml/Custom_1105_MusicOSDSettings.xml msgctxt "#15020" msgid "Audio DSP manager" msgstr "" @@ -8046,7 +8046,7 @@ msgctxt "#15041" msgid "Unknown mode name" msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPSettings.xml +#: addons/skin.estuary/xml/DialogAudioDSPSettings.xml msgctxt "#15042" msgid "Content:" msgstr "" @@ -8056,7 +8056,7 @@ msgstr "" #. Label for a context menu entry and dialog button to open audio DSP settings dialog #: xbmc/pvr/PVRContextMenus.cpp #: xbmc/music/windows/GUIWindowMusicBase.cpp -#: addons/skin.estuary/1080i/Custom_1105_MusicOSDSettings.xml +#: addons/skin.estuary/xml/Custom_1105_MusicOSDSettings.xml msgctxt "#15047" msgid "Audio DSP settings" msgstr "" @@ -8073,7 +8073,7 @@ msgctxt "#15051" msgid "Active modes" msgstr "" -#: addons/skin.estuary/1080i/DialogNetworkSetup.xml +#: addons/skin.estuary/xml/DialogNetworkSetup.xml msgctxt "#15052" msgid "Password" msgstr "" @@ -8081,31 +8081,31 @@ msgstr "" #empty strings from id 15053 to 15056 #. Chain select button name -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15057" msgid "Input resampling" msgstr "" #. Chain select button name -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15058" msgid "Pre-processing" msgstr "" #. Chain select button name -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15059" msgid "Master processing" msgstr "" #. Chain select button name -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15060" msgid "Post-processing" msgstr "" #. Chain select button name -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15061" msgid "Output resampling" msgstr "" @@ -8123,7 +8123,7 @@ msgid "No description available" msgstr "" #. DSP manager boolean enable/disable value text -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15064" msgid "Apply changes directly" msgstr "" @@ -8305,27 +8305,27 @@ msgctxt "#15112" msgid "Default theme" msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15113" msgid "Here you can configure pre-processing modes. This processing stage only change the input data stream." msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15114" msgid "Here you can configure an input resampling process. Notice: Only one active mode is allowed!" msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15115" msgid "Here you can configure master processing modes. Notice: On playback only one active mode can be selected!" msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15116" msgid "Here you can configure a output resampling process. Notice: Only one active mode is allowed!" msgstr "" -#: addons/skin.estuary/1080i/DialogAudioDSPManager.xml +#: addons/skin.estuary/xml/DialogAudioDSPManager.xml msgctxt "#15117" msgid "Here you can configure post-processing modes. This processing stage can be used for equalizing and volume correction..." msgstr "" @@ -8592,7 +8592,7 @@ msgctxt "#16101" msgid "Unwatched" msgstr "" -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#16102" msgid "Watched" msgstr "" @@ -8893,12 +8893,12 @@ msgctxt "#19000" msgid "Switch to channel" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19001" msgid "Separate the search words by using AND, OR and / or NOT." msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19002" msgid "or use phrases to find an exact match, like \"The wizard of Oz\"." msgstr "" @@ -8921,37 +8921,37 @@ msgid "PVR stream information" msgstr "" #. label for 'tuner name' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19006" msgid "Receiving device" msgstr "" #. label for 'device status' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19007" msgid "Device status" msgstr "" #. label for 'signal quality' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19008" msgid "Signal quality" msgstr "" #. label for 'signal noise ratio' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19009" msgid "SNR" msgstr "" #. label for 'bit error ratio' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19010" msgid "BER" msgstr "" #. label for 'number of uncorrected errors' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19011" msgid "UNC" msgstr "" @@ -8975,7 +8975,7 @@ msgid "Fixed" msgstr "" #. label for 'channel encryption' in pvr player information dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19015" msgid "Encryption" msgstr "" @@ -8986,8 +8986,8 @@ msgid "PVR backend %i - %s" msgstr "" #. generic label for pvr recordings used in different places -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/Variables.xml #: xbmc/dialogs/GUIDialogMediaSource.cpp #: xbmc/filesystem/PVRDirectory.cpp msgctxt "#19017" @@ -9001,20 +9001,20 @@ msgid "Folder with channel icons" msgstr "" #. label for PVR backend number of channels in system information's PVR section -#: addons/skin.estuary/1080i/DialogPVRGuideOSD.xml -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml -#: addons/skin.estuary/1080i/DialogPVRChannelsOSD.xml -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/DialogPVRGuideOSD.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelsOSD.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/Home.xml #: xbmc/windows/GUIWindowSystemInfo.cpp msgctxt "#19019" msgid "Channels" msgstr "" #. generic label for 'Live TV' used in different places -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/SkinSettings.xml: -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/SkinSettings.xml: +#: addons/skin.estuary/xml/Variables.xml #: xbmc/pvr/channels/PVRChannelGroupsContainer.cpp #: xbmc/pvr/PVRManager.cpp msgctxt "#19020" @@ -9022,9 +9022,9 @@ msgid "TV" msgstr "" #. generic label for pvr-provided 'Radio' used in different places -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Variables.xml #: xbmc/pvr/channels/PVRChannelGroupsContainer.cpp #: xbmc/pvr/PVRManager.cpp msgctxt "#19021" @@ -9040,16 +9040,16 @@ msgstr "" #. generic label for 'Live TV channels' used in different places #: xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19023" msgid "TV channels" msgstr "" #. generic label for pvr-provided 'Radio channels' used in different places #: xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#19024" msgid "Radio channels" msgstr "" @@ -9079,7 +9079,7 @@ msgid "No guide entries" msgstr "" #. generic 'channel' label used in different places -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml #: xbmc/filesystem/PluginDirectory.cpp #: xbmc/pvr/channels/PVRChannel.cpp #: xbmc/pvr/PVRGUIActions.cpp @@ -9089,24 +9089,24 @@ msgid "Channel" msgstr "" #. generic 'now' label used in different places -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml -#: addons/skin.estuary/1080i/MyWeather.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/MyWeather.xml #: xbmc/pvr/windows/GUIWindowPVRGuide.cpp msgctxt "#19030" msgid "Now" msgstr "" #. generic 'next' label used in different places in pvr context -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml -#: addons/skin.estuary/1080i/MyPVRChannels.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/MyPVRChannels.xml #: xbmc/pvr/windows/GUIWindowPVRGuide.cpp msgctxt "#19031" msgid "Next" msgstr "" #. 'timeline' label used in pvr guide window -#: addons/skin.estuary/1080i/MyPVRGuide.xml +#: addons/skin.estuary/xml/MyPVRGuide.xml #. xbmc/pvr/windows/GUIWindowPVRGuide.cpp msgctxt "#19032" msgid "Timeline" @@ -9124,7 +9124,7 @@ msgstr "" #: xbmc/pvr/PVRGUIActions.cpp #: xbmc/pvr/PVRManager.cpp #: xbmc/video/windows/GUIWindowVideoBase.cpp -#: addons/skin.estuary/1080i/VideoOSD.xml +#: addons/skin.estuary/xml/VideoOSD.xml msgctxt "#19033" msgid "Information" msgstr "" @@ -9167,7 +9167,7 @@ msgctxt "#19039" msgid "Are you sure you want to hide this channel?" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#19040" msgid "Timers" msgstr "" @@ -9229,7 +9229,7 @@ msgctxt "#19050" msgid "Show visible channels" msgstr "" -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#19051" msgid "Show hidden channels" msgstr "" @@ -9252,14 +9252,14 @@ msgid "Hide channel" msgstr "" #. generic text used in several places to state that there is no information available -#: addons/skin.estuary/1080i/DialogMusicInfo.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml -#: addons/skin.estuary/1080i/Includes_PVR.xml -#: addons/skin.estuary/1080i/MyGames.xml -#: addons/skin.estuary/1080i/MyMusicNav.xml -#: addons/skin.estuary/1080i/MyPics.xml -#: addons/skin.estuary/1080i/MyVideoNav.xml -#: addons/skin.estuary/1080i/View_50_List.xml +#: addons/skin.estuary/xml/DialogMusicInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml +#: addons/skin.estuary/xml/Includes_PVR.xml +#: addons/skin.estuary/xml/MyGames.xml +#: addons/skin.estuary/xml/MyMusicNav.xml +#: addons/skin.estuary/xml/MyPics.xml +#: addons/skin.estuary/xml/MyVideoNav.xml +#: addons/skin.estuary/xml/View_50_List.xml #: xbmc/epg/EpgInfoTag.cpp #: xbmc/FileItem.cpp #: xbmc/GUIInfoManager.cpp @@ -9304,7 +9304,7 @@ msgstr "" #. Label for a context menu entry to open the timer settings dialog #: xbmc/pvr/PVRContextMenus.cpp -#: addons/skin.estuary/1080i/DialogPVRInfo.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml msgctxt "#19061" msgid "Add timer" msgstr "" @@ -9352,7 +9352,7 @@ msgid "This recording couldn't be deleted. Check the log for more information ab msgstr "" #. Electronic program guide -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#19069" msgid "Guide" msgstr "" @@ -9381,7 +9381,7 @@ msgctxt "#19073" msgid "Delay channel switch" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19074" msgid "Active" msgstr "" @@ -9398,7 +9398,7 @@ msgctxt "#19076" msgid "Folder" msgstr "" -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#19077" msgid "Hide disabled" msgstr "" @@ -9530,19 +9530,19 @@ msgid "Warning!" msgstr "" #. service label in pvr info dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19099" msgid "Service" msgstr "" #. mux label in pvr info dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19100" msgid "Mux" msgstr "" #. provider label in pvr info dialog -#: addons/skin.estuary/1080i/DialogPlayerProcessInfo.xml +#: addons/skin.estuary/xml/DialogPlayerProcessInfo.xml msgctxt "#19101" msgid "Provider" msgstr "" @@ -9664,7 +9664,7 @@ msgctxt "#19120" msgid "Client number" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19121" msgid "Avoid repeats" msgstr "" @@ -9675,75 +9675,75 @@ msgctxt "#19122" msgid "This timer is still recording. Are you sure you want to delete this timer?" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19123" msgid "Free to air channels only" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19124" msgid "Ignore present timers" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19125" msgid "Ignore present recordings" msgstr "" #. Label of "Start time" spinner in PVR timer settings dialog #: xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19126" msgid "Start time" msgstr "" #. Label of "End time" edit field in PVR timer settings dialog #: xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19127" msgid "End time" msgstr "" #. Label of "Start date" spinner field in PVR timer settings dialog #: xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19128" msgid "Start date" msgstr "" #. Label of "End date" edit field in PVR timer settings dialog #: xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19129" msgid "End date" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19130" msgid "Minimum duration" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19131" msgid "Maximum duration" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19132" msgid "Include unknown genres" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19133" msgid "Search string" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19134" msgid "Include description" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19135" msgid "Case sensitive" msgstr "" @@ -9760,7 +9760,7 @@ msgid "No groups defined. Please create a group first" msgstr "" #. Label of timer rules tv/radio home submenu item -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#19138" msgid "Timer rules" msgstr "" @@ -9778,19 +9778,19 @@ msgid "Search..." msgstr "" #. part of PVR window's active channel group label (e.g. "Group: HD Sports Channels") -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml #: xbmc/pvr/windows/GUIWindowPVRBase.cpp msgctxt "#19141" msgid "Group" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19142" msgid "Search guide" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRGroupManager.xml +#: addons/skin.estuary/xml/DialogPVRGroupManager.xml msgctxt "#19143" msgid "Group management" msgstr "" @@ -9805,7 +9805,7 @@ msgctxt "#19145" msgid "Grouped" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelsOSD.xml +#: addons/skin.estuary/xml/DialogPVRChannelsOSD.xml msgctxt "#19146" msgid "Groups" msgstr "" @@ -9816,8 +9816,8 @@ msgctxt "#19147" msgid "The PVR backend does not support this action. Check the log for more information about this message." msgstr "" -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml -#: addons/skin.estuary/1080i/DialogPVRGuideSearch.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml msgctxt "#19148" msgid "Channel" msgstr "" @@ -9869,12 +9869,12 @@ msgctxt "#19156" msgid "from" msgstr "" -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#19157" msgid "Next recording" msgstr "" -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#19158" msgid "Currently recording" msgstr "" @@ -9915,7 +9915,7 @@ msgctxt "#19164" msgid "Can't start recording. Check the log for more information about this message." msgstr "" -#: addons/skin.estuary/1080i/DialogPVRInfo.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml msgctxt "#19165" msgid "Switch" msgstr "" @@ -10028,7 +10028,7 @@ msgid "Radio channels" msgstr "" #. label for "deleted recordings" data source in media source window -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml #: xbmc/dialogs/GUIDialogMediaSource.cpp msgctxt "#19184" msgid "Deleted recordings" @@ -10070,7 +10070,7 @@ msgctxt "#19190" msgid "Background" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#19191" msgid "PVR service" msgstr "" @@ -10118,22 +10118,22 @@ msgstr "" #. pvr settings "channel manager" action button label #: system/settings/settings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#19199" msgid "Channel manager" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19200" msgid "Guide source:" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19201" msgid "Channel name:" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19202" msgid "Channel icon:" msgstr "" @@ -10144,18 +10144,18 @@ msgid "Edit channel" msgstr "" #. initial name for new channels, used in pvr channel manager dialog -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml #: xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp msgctxt "#19204" msgid "New channel" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19205" msgid "Group management" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19206" msgid "Activate guide:" msgstr "" @@ -10177,7 +10177,7 @@ msgid "Kodi virtual backend" msgstr "" #. pvr channel manager "epg source" selector value -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml #: xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp msgctxt "#19210" msgid "Client" @@ -10513,7 +10513,7 @@ msgctxt "#19266" msgid "Parental locked" msgstr "" -#: addons/skin.estuary/1080i/DialogPVRChannelManager.xml +#: addons/skin.estuary/xml/DialogPVRChannelManager.xml msgctxt "#19267" msgid "Parental locked:" msgstr "" @@ -10527,7 +10527,7 @@ msgstr "" # empty string with id 19269 #. Label of the option to switch between a grouped recordings list and a non-grouped recordings list in pvr recordings window. -#: addons/skin.estuary/1080i/Includes_MediaMenu.xml +#: addons/skin.estuary/xml/Includes_MediaMenu.xml msgctxt "#19270" msgid "Group Items" msgstr "" @@ -10619,13 +10619,13 @@ msgctxt "#19285" msgid "Browse for icon" msgstr "" -#. unused? +#. Label for channel icon search progress dialog +#: xbmc/pvr/channels/PVRChannelGroup.cpp msgctxt "#19286" msgid "Searching for channel icons" msgstr "" #. Label for the default pvr channel group -#: xbmc/pvr/channels/PVRChannelGroup.cpp #: xbmc/pvr/channels/PVRChannelGroupInternal.cpp msgctxt "#19287" msgid "All channels" @@ -10638,7 +10638,7 @@ msgid "Foreground" msgstr "" #. Label for button to hide a group in the group manager -#: addons/skin.estuary/1080i/DialogPVRGroupManager.xml +#: addons/skin.estuary/xml/DialogPVRGroupManager.xml msgctxt "#19289" msgid "Hide group" msgstr "" @@ -11422,14 +11422,14 @@ msgstr "" #. Name of an artwork type #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp -#: addons/skin.estuary/1080i/View_501_Banner.xml +#: addons/skin.estuary/xml/View_501_Banner.xml msgctxt "#20020" msgid "Banner" msgstr "" #. Name of an artwork type #: xbmc/video/dialogs/GUIDialogVideoInfo.cpp -#: addons/skin.estuary/1080i/View_51_Poster.xml +#: addons/skin.estuary/xml/View_51_Poster.xml msgctxt "#20021" msgid "Poster" msgstr "" @@ -11468,7 +11468,7 @@ msgctxt "#20036" msgid "%s (%s)" msgstr "" -#: addons/skin.estuary/1080i/SettingsSystemInfo.xml +#: addons/skin.estuary/xml/SettingsSystemInfo.xml msgctxt "#20037" msgid "Summary" msgstr "" @@ -11501,12 +11501,12 @@ msgctxt "#20044" msgid "Start fresh" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#20045" msgid "Enter master mode" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#20046" msgid "Leave master mode" msgstr "" @@ -11563,7 +11563,7 @@ msgctxt "#20059" msgid "Query info for all albums" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20060" msgid "Media info" msgstr "" @@ -11608,7 +11608,7 @@ msgid "Couldn't create folder" msgstr "" #: xbmc/windows/GUIWindowFileManager.cpp -#: addons/skin.estuary/1080i/ProfileSettings.xml +#: addons/skin.estuary/xml/ProfileSettings.xml msgctxt "#20070" msgid "Profile directory" msgstr "" @@ -11704,12 +11704,12 @@ msgctxt "#20092" msgid "Load profile" msgstr "" -#: addons/skin.estuary/1080i/ProfileSettings.xml +#: addons/skin.estuary/xml/ProfileSettings.xml msgctxt "#20093" msgid "Profile name" msgstr "" -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#20094" msgid "Media sources" msgstr "" @@ -11842,7 +11842,7 @@ msgctxt "#20125" msgid "Logged on as" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#20126" msgid "Log off" msgstr "" @@ -11939,12 +11939,12 @@ msgctxt "#20149" msgid "Shutdown in 120 minutes" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#20150" msgid "Custom shutdown timer" msgstr "" -#: addons/skin.estuary/1080i/DialogButtonMenu.xml +#: addons/skin.estuary/xml/DialogButtonMenu.xml msgctxt "#20151" msgid "Cancel shutdown timer" msgstr "" @@ -12012,7 +12012,7 @@ msgctxt "#20165" msgid "Not locked" msgstr "" -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#20166" msgid "Locked" msgstr "" @@ -12058,18 +12058,18 @@ msgctxt "#20176" msgid "Show video information" msgstr "" -#: addons/skin.estuary/1080i/DialogNumeric.xml -#: addons/skin.estuary/1080i/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml msgctxt "#20177" msgid "Done" msgstr "" -#: addons/skin.estuary/1080i/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml msgctxt "#20178" msgid "Shift" msgstr "" -#: addons/skin.estuary/1080i/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml msgctxt "#20179" msgid "Caps Lock" msgstr "" @@ -12078,13 +12078,13 @@ msgctxt "#20180" msgid "Symbols" msgstr "" -#: addons/skin.estuary/1080i/DialogKeyboard.xml -#: addons/skin.estuary/1080i/DialogNumeric.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogNumeric.xml msgctxt "#20181" msgid "Backspace" msgstr "" -#: addons/skin.estuary/1080i/DialogKeyboard.xml +#: addons/skin.estuary/xml/DialogKeyboard.xml msgctxt "#20182" msgid "Space" msgstr "" @@ -12114,7 +12114,7 @@ msgctxt "#20188" msgid "Announce library updates" msgstr "" -#: addons/skin.estuary/1080i/SkinSettings.xml +#: addons/skin.estuary/xml/SkinSettings.xml msgctxt "#20189" msgid "Enable auto scrolling for plot & review" msgstr "" @@ -12208,7 +12208,7 @@ msgctxt "#20243" msgid "Android photos" msgstr "" -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#20244" msgid "Android apps" msgstr "" @@ -12395,7 +12395,7 @@ msgctxt "#20335" msgid "Look for content recursively?" msgstr "" -#: addons/skin.estuary/1080i/MyVideoNav.xml +#: addons/skin.estuary/xml/MyVideoNav.xml msgctxt "#20336" msgid "Unlock sources" msgstr "" @@ -12415,10 +12415,10 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogPVRInfo.xml -#: addons/skin.estuary/1080i/View_51_Poster.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml +#: addons/skin.estuary/xml/View_51_Poster.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20339" msgid "Director" msgstr "" @@ -12436,7 +12436,7 @@ msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/media/MediaTypes.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20342" msgid "Movies" msgstr "" @@ -12444,14 +12444,14 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp #: xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp -#: addons/skin.estuary/1080i/Home.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Home.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20343" msgid "TV shows" msgstr "" -#: addons/skin.estuary/1080i/DialogContentSettings.xml +#: addons/skin.estuary/xml/DialogContentSettings.xml msgctxt "#20344" msgid "This directory contains" msgstr "" @@ -12525,8 +12525,8 @@ msgstr "" #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20359" msgid "Episode" msgstr "" @@ -12536,8 +12536,8 @@ msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/View_51_Poster.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/View_51_Poster.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20360" msgid "Episodes" msgstr "" @@ -12569,7 +12569,7 @@ msgctxt "#20366" msgid "* All seasons" msgstr "" -#: addons/skin.estuary/1080i/MyVideoNav.xml +#: addons/skin.estuary/xml/MyVideoNav.xml msgctxt "#20367" msgid "Hide watched" msgstr "" @@ -12597,8 +12597,8 @@ msgstr "" #: xbmc/media/MediaTypes.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20373" msgid "Season" msgstr "" @@ -12638,7 +12638,10 @@ msgctxt "#20381" msgid "Specials" msgstr "" -#empty string with id 20382 +#: xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp +msgctxt "#20382" +msgid "Recently added" +msgstr "" msgctxt "#20383" msgid "Selected folder contains a single video" @@ -12675,7 +12678,7 @@ msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp #: xbmc/media/MediaTypes.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20389" msgid "Music videos" msgstr "" @@ -12795,17 +12798,17 @@ msgstr "" #: xbmc/dialogs/GUIDialogMediaFilter.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Variables.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/Variables.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#20416" msgid "First aired" msgstr "" #: xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/DialogVideoInfo.xml -#: addons/skin.estuary/1080i/DialogPVRInfo.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogPVRInfo.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#20417" msgid "Writer" msgstr "" @@ -12940,7 +12943,7 @@ msgid "Add to library" msgstr "" #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: addons/skin.estuary/1080i/View_502_FanArt.xml +#: addons/skin.estuary/xml/View_502_FanArt.xml msgctxt "#20445" msgid "Fanart" msgstr "" @@ -12979,7 +12982,7 @@ msgctxt "#20452" msgid "episode" msgstr "" -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#20453" msgid "episodes" msgstr "" @@ -13299,8 +13302,8 @@ msgctxt "#21395" msgid "Unable to cache files bigger than 4GB" msgstr "" -#: addons/skin.estuary/1080i/DialogSeekBar.xml -#: addons/skin.estuary/1080i/DialogFullScreenInfo.xml +#: addons/skin.estuary/xml/DialogSeekBar.xml +#: addons/skin.estuary/xml/DialogFullScreenInfo.xml msgctxt "#21396" msgid "Chapter" msgstr "" @@ -13421,7 +13424,7 @@ msgctxt "#21421" msgid "Smart playlist rule" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistRule.xml +#: addons/skin.estuary/xml/SmartPlaylistRule.xml msgctxt "#21422" msgid "Match items where" msgstr "" @@ -13431,7 +13434,7 @@ msgctxt "#21423" msgid "New rule..." msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21424" msgid "Items must match" msgstr "" @@ -13446,7 +13449,7 @@ msgctxt "#21426" msgid "one or more of the rules" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21427" msgid "Limit to" msgstr "" @@ -13456,17 +13459,17 @@ msgctxt "#21428" msgid "No limit" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21429" msgid "Order by" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21430" msgid "ascending" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21431" msgid "descending" msgstr "" @@ -13475,7 +13478,7 @@ msgctxt "#21432" msgid "Edit smart playlist" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21433" msgid "Playlist name" msgstr "" @@ -13523,7 +13526,7 @@ msgid "Video resolution" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#21444" msgid "Audio channels" msgstr "" @@ -13534,7 +13537,7 @@ msgid "Video codec" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/MusicVisualisation.xml +#: addons/skin.estuary/xml/MusicVisualisation.xml msgctxt "#21446" msgid "Audio codec" msgstr "" @@ -13567,12 +13570,12 @@ msgstr "" #: xbmc/addons/GUIViewStateAddonBrowser.cpp #: xbmc/filesystem/AddonsDirectory.cpp -#: addons/skin.estuary/1080i/MyPrograms.xml -#: addons/skin.estuary/1080i/Includes.xml -#: addons/skin.estuary/1080i/MyVideoNav.xml -#: addons/skin.estuary/1080i/MyPics.xml -#: addons/skin.estuary/1080i/MyMusicNav.xml -#: addons/skin.estuary/1080i/MyGames.xml +#: addons/skin.estuary/xml/MyPrograms.xml +#: addons/skin.estuary/xml/Includes.xml +#: addons/skin.estuary/xml/MyVideoNav.xml +#: addons/skin.estuary/xml/MyPics.xml +#: addons/skin.estuary/xml/MyMusicNav.xml +#: addons/skin.estuary/xml/MyGames.xml msgctxt "#21452" msgid "Get more..." msgstr "" @@ -13599,12 +13602,12 @@ msgctxt "#21457" msgid "Watched episode count" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21458" msgid "Group by" msgstr "" -#: addons/skin.estuary/1080i/SmartPlaylistEditor.xml +#: addons/skin.estuary/xml/SmartPlaylistEditor.xml msgctxt "#21459" msgid "mixed" msgstr "" @@ -13795,7 +13798,7 @@ msgctxt "#21822" msgid "Camera make" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21823" msgid "Camera model" msgstr "" @@ -13808,12 +13811,12 @@ msgctxt "#21825" msgid "Firmware" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21826" msgid "Aperture" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21827" msgid "Focal length" msgstr "" @@ -13826,7 +13829,7 @@ msgctxt "#21829" msgid "Exposure" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21830" msgid "Exposure time" msgstr "" @@ -13967,7 +13970,7 @@ msgctxt "#21874" msgid "State" msgstr "" -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#21875" msgid "Country" msgstr "" @@ -14021,13 +14024,13 @@ msgstr "" #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21887" msgid "Biography" msgstr "" #: xbmc/music/dialogs/GUIDialogMusicInfo.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21888" msgid "Discography" msgstr "" @@ -14077,13 +14080,13 @@ msgctxt "#21897" msgid "Died" msgstr "" -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21898" msgid "Years active" msgstr "" #: xbmc/playlists/SmartPlaylist.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#21899" msgid "Label" msgstr "" @@ -14310,9 +14313,9 @@ msgid "Add-on" msgstr "" #: xbmc/filesystem/AddonsDirectory.cpp -#: addons/skin.estuary/1080i/Includes.xml -#: addons/skin.estuary/1080i/SkinSettings.xml -#: addons/skin.estuary/1080i/Home.xml +#: addons/skin.estuary/xml/Includes.xml +#: addons/skin.estuary/xml/SkinSettings.xml +#: addons/skin.estuary/xml/Home.xml msgctxt "#24001" msgid "Add-ons" msgstr "" @@ -14370,7 +14373,7 @@ msgid "Add-on repository" msgstr "" #: xbmc/addons/Addon.cpp -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#24012" msgid "Subtitles" msgstr "" @@ -14401,7 +14404,7 @@ msgid "Artist information" msgstr "" #: xbmc/addons/Addon.cpp -#: addons/skin.estuary/1080i/DialogSubtitles.xml +#: addons/skin.estuary/xml/DialogSubtitles.xml msgctxt "#24018" msgid "Services" msgstr "" @@ -14479,7 +14482,7 @@ msgctxt "#24033" msgid "Install from repository" msgstr "" -#: addons/skin.estuary/1080i/AddonBrowser.xml +#: addons/skin.estuary/xml/AddonBrowser.xml #: xbmc/addons/ContextMenus.h #: xbmc/addons/GUIViewStateAddonBrowser.cpp msgctxt "#24034" @@ -14567,7 +14570,7 @@ msgctxt "#24051" msgid "Version:" msgstr "" -#: addons/skin.estuary/1080i/DialogAddonInfo.xml +#: addons/skin.estuary/xml/DialogAddonInfo.xml #: addons/skin.estouchy/xml/DialogAddonInfo.xml msgctxt "#24052" msgid "Disclaimer" @@ -14578,7 +14581,7 @@ msgctxt "#24053" msgid "License:" msgstr "" -#: addons/skin.estuary/1080i/DialogAddonInfo.xml +#: addons/skin.estuary/xml/DialogAddonInfo.xml msgctxt "#24054" msgid "What's new" msgstr "" @@ -14783,17 +14786,19 @@ msgctxt "#24093" msgid "Checking %s..." msgstr "" -#empty string with id 24094 +#: xbmc/addons/AddonInstaller.cpp +msgctxt "#24094" +msgid "Add-on disabled due to being marked broken in repository." +msgstr "" #: xbmc/addons/GUIDialogAddonInfo.cpp msgctxt "#24095" msgid "Local package cache" msgstr "" -#: xbmc/addons/Repository.cpp -#: addons/skin.estuary/1080i/DialogAddonInfo.xml +#: addons/skin.estuary/xml/DialogAddonInfo.xml msgctxt "#24096" -msgid "Add-on is incompatible or has been marked broken in repository." +msgid "Add-on has been marked broken in repository." msgstr "" #: xbmc/addons/Repository.cpp @@ -15141,7 +15146,7 @@ msgid "My add-ons" msgstr "" #. Used in add-on browser -#: addons/skin.estuary/1080i/AddonBrowser.xml +#: addons/skin.estuary/xml/AddonBrowser.xml msgctxt "#24999" msgid "Hide incompatible" msgstr "" @@ -15152,7 +15157,7 @@ msgid "Notifications" msgstr "" #. Used in add-on browser -#: addons/skin.estuary/1080i/AddonBrowser.xml +#: addons/skin.estuary/xml/AddonBrowser.xml msgctxt "#25001" msgid "Hide foreign" msgstr "" @@ -15238,94 +15243,94 @@ msgid "Radiotext Plus info" msgstr "" #. Music band name which make the song (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29901" msgid "Band" msgstr "" #. Style of the current playing radio -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29902" msgid "Style" msgstr "" #. Concert composer of the music (if present) #: Label of ListItem.Property(Role.Composer) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29903" msgid "Composer" msgstr "" #. Artists which sing the music (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29904" msgid "Artist" msgstr "" #. Conductor of the classic music (if present) #: Label of ListItem.Property(Role.Conductor) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29905" msgid "Conductor" msgstr "" #. Moderator currently on radio (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29906" msgid "Moderator" msgstr "" #. List of editoral staff (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29907" msgid "Editorial Staff" msgstr "" #. Current playing program name -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29908" msgid "Program" msgstr "" #. Studio name (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#29909" msgid "Studio" msgstr "" #. Phone number (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29910" msgid "Phone" msgstr "" #. EMail address (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29911" msgid "EMail" msgstr "" #. SMS message number (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29912" msgid "SMS" msgstr "" #. Hotline phone (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29913" msgid "Hotline" msgstr "" #. Website address (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29914" msgid "Website" msgstr "" #. General information news, in list selector (if present) -#: addons/skin.estuary/1080i/DialogPVRRadioRDSInfo.xml +#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml msgctxt "#29915" msgid "Info" msgstr "" @@ -15899,12 +15904,12 @@ msgctxt "#33034" msgid "36-hour" msgstr "" -#: addons/skin.estuary/1080i/MyWeather.xml +#: addons/skin.estuary/xml/MyWeather.xml msgctxt "#33035" msgid "Maps" msgstr "" -#: addons/skin.estuary/1080i/MyWeather.xml +#: addons/skin.estuary/xml/MyWeather.xml msgctxt "#33036" msgid "Hourly" msgstr "" @@ -15953,7 +15958,7 @@ msgstr "" #: xbmc/filesystem/VideoDatabaseDirectory.cpp #: xbmc/media/MediaTypes.cpp -#: addons/skin.estuary/1080i/View_51_Poster.xml +#: addons/skin.estuary/xml/View_51_Poster.xml msgctxt "#33054" msgid "Seasons" msgstr "" @@ -15998,7 +16003,7 @@ msgctxt "#33062" msgid "Play the" msgstr "" -#: addons/skin.estuary/1080i/Includes.xml +#: addons/skin.estuary/xml/Includes.xml msgctxt "#33063" msgid "Options" msgstr "" @@ -16462,23 +16467,22 @@ msgctxt "#35012" msgid "A new controller has been detected. Configuration can be done at any time in \"Settings -> System Settings -> Input\". Would you like to configure it now?" msgstr "" -#. Label of the button to fix the bug where buttons are skipped in the controller dialog -#: addons/skin.estuary/1080i/DialogGameControllers.xml -msgctxt "#35013" -msgid "Fix skipping" -msgstr "" +#empty string with id 35013 #. Help text of the button to fix the bug where buttons are skipped in the controller dialog. %s - list of disabled buttons and axes +#: xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp msgctxt "#35014" msgid "Some controllers have buttons and axes that interfere with mapping. Press these now to disable them:[CR]%s" msgstr "" -#. Name of a controller button, e.g. Button 1. %d - button index +#. Name of a controller button, e.g. "Button 1". %d - button index +#: xbmc/input/joysticks/JoystickTranslator.cpp msgctxt "#35015" msgid "Button %d" msgstr "" -#. Name of a controller axis, e.g. Axis 2. %d - axis index +#. Name of a controller axis, e.g. "Axis 2". %d - axis index +#: xbmc/input/joysticks/JoystickTranslator.cpp msgctxt "#35016" msgid "Axis %d" msgstr "" @@ -16495,7 +16499,20 @@ msgctxt "#35018" msgid "Controller configuration depends on a disabled add-on. Would you like to enable it?" msgstr "" -#empty strings from id 35019 to 35048 +#. Label of the button to fix the bug where buttons are skipped in the controller dialog +#: addons/skin.estuary/xml/DialogGameControllers.xml +#: xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp +msgctxt "#35019" +msgid "Ignore input" +msgstr "" + +#. Help text of the dialog to detect analog buttons on controllers. %s - list of detected axes +#: xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp +msgctxt "#35020" +msgid "Press all analog buttons now to detect them:[CR][CR]%s" +msgstr "" + +#empty strings from id 35021 to 35048 #. Name of game add-ons category #: xbmc/addons/Addon.cpp @@ -16505,7 +16522,7 @@ msgid "Game add-ons" msgstr "" #. Name of controller add-ons -#: addons/skin.estuary/1080i/DialogGameControllers.xml +#: addons/skin.estuary/xml/DialogGameControllers.xml #: xbmc/addons/Addon.cpp #: xbmc/games/controllers/windows/GUIControllerWindow.cpp msgctxt "#35050" @@ -16535,13 +16552,13 @@ msgstr "" #empty strings from id 35056 to 35057 #. Title of controller configuration window -#: addons/skin.estuary/1080i/DialogGameControllers.xml +#: addons/skin.estuary/xml/DialogGameControllers.xml msgctxt "#35058" msgid "Controller Configuration" msgstr "" #. Heading for controller buttons list in controller configuration window -#: addons/skin.estuary/1080i/DialogGameControllers.xml +#: addons/skin.estuary/xml/DialogGameControllers.xml msgctxt "#35059" msgid "Buttons" msgstr "" @@ -17196,7 +17213,7 @@ msgstr "" #. Name of an action to perform on a specific event, like changing the CEC source away from Kodi #: xbmc/peripherals/devices/PeripheralCecAdapter.cpp #: system/peripherals.xml -#: addons/skin.estuary/1080i/Variables.xml +#: addons/skin.estuary/xml/Variables.xml msgctxt "#36044" msgid "Stop Playback" msgstr "" @@ -19745,7 +19762,7 @@ msgid "season" msgstr "" #: xbmc/media/MediaType.cpp -#: addons/skin.estuary/1080i/DialogVideoInfo.xml +#: addons/skin.estuary/xml/DialogVideoInfo.xml msgctxt "#36905" msgid "seasons" msgstr "" @@ -20251,7 +20268,13 @@ msgctxt "#38061" msgid "Fetch additional information for albums and artists? This could take some time so you may prefer to do this later" msgstr "" -#empty strings from id 38062 to 38099 +#. Full tag scanning question on library update (by default tags are only scanned when the file has changed since last time) +#: xbmc/Application.cpp +msgctxt "#38062" +msgid "Do full tag scan even when music files are unchanged?" +msgstr "" + +#empty strings from id 38063 to 38099 #. Description of section #14200 "Player"" #: system/settings/settings.xml @@ -20325,7 +20348,21 @@ msgctxt "#38111" msgid "This category contains other settings for the GUI interface" msgstr "" -#empty strings from id 38112 to 38999 +#empty strings from id 38112 to 38206 + +#. Description of setting "Pictures -> Show EXIF picture information" with label #38207 +#: system/settings/settings.xml +msgctxt "#38207" +msgid "Show EXIF picture information" +msgstr "" + +#. Help text of setting "Pictures -> Show EXIF picture information" with label #38208 +#: system/settings/settings.xml +msgctxt "#38208" +msgid "If EXIF information exists (date, time, camera used, etc.), it will be displayed." +msgstr "" + +#empty strings from id 38209 to 38999 #: system/settings/settings.xml msgctxt "#39000" @@ -20408,14 +20445,7 @@ msgctxt "#39014" msgid "Would you also like to remove all related data (e.g. settings) of this add-on?" msgstr "" -#. Description of setting "Pictures -> Show EXIF picture information" with label #38207 -#: system/settings/settings.xml -msgctxt "#38207" -msgid "Show EXIF picture information" -msgstr "" - -#. Help text of setting "Pictures -> Show EXIF picture information" with label #38208 -#: system/settings/settings.xml -msgctxt "#38208" -msgid "If EXIF information exists (date, time, camera used, etc.), it will be displayed." +#: /xbmc/addons/Addon.cpp +msgctxt "#39015" +msgid "Image decoder" msgstr "" diff --git a/addons/skin.estouchy/xml/SlideShow.xml b/addons/skin.estouchy/xml/SlideShow.xml index bfe6d61c65..e27f40ac2d 100644 --- a/addons/skin.estouchy/xml/SlideShow.xml +++ b/addons/skin.estouchy/xml/SlideShow.xml @@ -1,3 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <window> + <controls> + <control type="image"> + <centerleft>50%</centerleft> + <centertop>50%</centertop> + <width>283</width> + <height>283</height> + <texture>icon_settings_player.png</texture> + <visible>SlideShow.IsVideo + [![Player.Playing + Player.HasVideo] | SlideShow.IsPaused]</visible> + </control> + </controls> </window> diff --git a/addons/skin.estuary/xml/AddonBrowser.xml b/addons/skin.estuary/xml/AddonBrowser.xml index f3ee214b28..dd211bcc78 100644 --- a/addons/skin.estuary/xml/AddonBrowser.xml +++ b/addons/skin.estuary/xml/AddonBrowser.xml @@ -63,7 +63,7 @@ <control type="group"> <height>78</height> <bottom>0</bottom> - <visible>$EXP[sidebar_focused]</visible> + <visible>$EXP[sidebar_visible]</visible> <animation effect="fade" time="300">VisibleChange</animation> <include content="LeftAlignedInfo"> <param name="main_label" value="$INFO[Window(AddonBrowser).Property(Updated)]" /> diff --git a/addons/skin.estuary/xml/Constants_1920.xml b/addons/skin.estuary/xml/Constants_1920.xml index d85f2d53d2..f9b714beff 100644 --- a/addons/skin.estuary/xml/Constants_1920.xml +++ b/addons/skin.estuary/xml/Constants_1920.xml @@ -7,5 +7,5 @@ <constant name="tvrecordings_width">1060</constant> <constant name="eventloglist_width">1430</constant> <constant name="playlisteditorlist_width">770</constant> - <constant name="playlistlist_width">904</constant> + <constant name="playlistlist_width">896</constant> </includes> diff --git a/addons/skin.estuary/xml/Constants_2560.xml b/addons/skin.estuary/xml/Constants_2560.xml index fea8fc5886..ba83217abd 100644 --- a/addons/skin.estuary/xml/Constants_2560.xml +++ b/addons/skin.estuary/xml/Constants_2560.xml @@ -7,5 +7,5 @@ <constant name="tvrecordings_width">1700</constant> <constant name="eventloglist_width">2070</constant> <constant name="playlisteditorlist_width">1410</constant> - <constant name="playlistlist_width">1544</constant> + <constant name="playlistlist_width">1536</constant> </includes> diff --git a/addons/skin.estuary/xml/DialogGameControllers.xml b/addons/skin.estuary/xml/DialogGameControllers.xml index 18cb7892b9..0b9128aa18 100644 --- a/addons/skin.estuary/xml/DialogGameControllers.xml +++ b/addons/skin.estuary/xml/DialogGameControllers.xml @@ -162,7 +162,7 @@ <include content="DefaultDialogButton"> <param name="width" value="350" /> <param name="id" value="21" /> - <param name="label" value="$LOCALIZE[35013]" /> + <param name="label" value="$LOCALIZE[35019]" /> </include> </control> </control> diff --git a/addons/skin.estuary/xml/DialogMusicInfo.xml b/addons/skin.estuary/xml/DialogMusicInfo.xml index 4f895ab4e2..08940cc059 100644 --- a/addons/skin.estuary/xml/DialogMusicInfo.xml +++ b/addons/skin.estuary/xml/DialogMusicInfo.xml @@ -31,7 +31,7 @@ <height>567</height> <aspectratio aligny="top">scale</aspectratio> <fadetime>300</fadetime> - <texture background="true" fallback="DefaultAudio.png">$INFO[ListItem.Art(thumb)]</texture> + <texture background="true">$VAR[MusicInfoThumbVar]</texture> </control> </control> <control type="group"> diff --git a/addons/skin.estuary/xml/Includes.xml b/addons/skin.estuary/xml/Includes.xml index b3f7993305..205e0ea551 100644 --- a/addons/skin.estuary/xml/Includes.xml +++ b/addons/skin.estuary/xml/Includes.xml @@ -34,7 +34,7 @@ <constant name="list_y_offset">0</constant> <constant name="list_item_height">80</constant> <expression name="infodialog_active">Window.IsActive(musicinformation) | Window.IsActive(songinformation) | Window.IsActive(movieinformation) | Window.IsActive(addoninformation) | Window.IsActive(pvrguideinfo) | Window.IsActive(pvrrecordinginfo) | Window.IsActive(pictureinfo) | Window.IsVisible(script-script.extendedinfo-DialogVideoInfo.xml) | Window.IsVisible(script-script.extendedinfo-DialogInfo.xml) | Window.IsVisible(script-script.extendedinfo-VideoList.xml)</expression> - <expression name="sidebar_focused">ControlGroup(9000).HasFocus | Control.HasFocus(6130)</expression> + <expression name="sidebar_visible">ControlGroup(9000).HasFocus | Control.HasFocus(6130) | Window.IsActive(MyPlaylist.xml)</expression> <include name="CommonScrollbars"> <control type="group"> <animation effect="fade" start="100" end="0" time="150">WindowClose</animation> @@ -320,6 +320,7 @@ <font>$PARAM[font]</font> <aligny>center</aligny> <label>$INFO[ListItem.Label]</label> + <scroll>true</scroll> </control> </focusedlayout> </definition> diff --git a/addons/skin.estuary/xml/Includes_MediaMenu.xml b/addons/skin.estuary/xml/Includes_MediaMenu.xml index 89cb087b65..9a3c103748 100644 --- a/addons/skin.estuary/xml/Includes_MediaMenu.xml +++ b/addons/skin.estuary/xml/Includes_MediaMenu.xml @@ -198,7 +198,7 @@ <onleft>14100</onleft> <onup>8</onup> <ondown>6056</ondown> - <visible>Player.HasMedia + [$EXP[sidebar_focused]]</visible> + <visible>Player.HasMedia + [$EXP[sidebar_visible]]</visible> <visible>!System.HasActiveModalDialog</visible> <include content="BottomMainMenuToggleItem"> <param name="control_id" value="14101" /> @@ -241,7 +241,7 @@ <include>OpenClose_Left</include> <depth>DepthSideBlade</depth> <left>-520</left> - <animation type="Conditional" condition="$EXP[sidebar_focused]" reversible="true"> + <animation type="Conditional" condition="$EXP[sidebar_visible]" reversible="true"> <effect type="slide" start="0" end="520" time="400" tween="cubic" easing="out" /> </animation> <control type="image"> @@ -249,7 +249,7 @@ <height>100%</height> <aspectratio>scale</aspectratio> <texture colordiffuse="80FFFFFF">colors/black.png</texture> - <visible>$EXP[sidebar_focused] + !System.HasActiveModalDialog</visible> + <visible>$EXP[sidebar_visible] + !System.HasActiveModalDialog</visible> <animation effect="fade" time="200">VisibleChange</animation> </control> <control type="image"> @@ -269,41 +269,45 @@ </control> </include> <include name="MediaMenuNowPlaying"> - <control type="grouplist" id="14100"> - <animation effect="fade" start="0" end="100" time="400">WindowOpen</animation> - <animation effect="fade" start="100" end="0" time="300">WindowClose</animation> - <animation effect="fade" time="300">VisibleChange</animation> - <orientation>horizontal</orientation> - <itemgap>-17</itemgap> - <left>5</left> - <onleft>14100</onleft> - <width>450</width> - <visible>Player.HasMedia + [$EXP[sidebar_focused]]</visible> - <visible>!System.HasActiveModalDialog</visible> - <include content="BottomMainMenuToggleItem"> - <param name="control_id" value="14101" /> - <param name="onclick" value="PlayerControl(Play)" /> - <param name="icon_on" value="icons/now-playing/play.png" /> - <param name="icon_off" value="icons/now-playing/pause.png" /> - <param name="selected" value="Player.Paused" /> - </include> - <include content="IconButton"> - <param name="control_id" value="14102" /> - <param name="onclick" value="Stop" /> - <param name="onclick_2" value="SetFocus(50)" /> - <param name="icon" value="icons/now-playing/stop.png" /> - </include> - <include content="IconButton"> - <param name="control_id" value="14104" /> - <param name="onclick" value="PlayerControl(Next)" /> - <param name="icon" value="icons/now-playing/next.png" /> - </include> - <include content="IconButton"> - <param name="control_id" value="14105" /> - <param name="onclick" value="Fullscreen" /> - <param name="icon" value="icons/now-playing/fullscreen.png" /> - </include> - </control> + <param name="left">5</param> + <definition> + <control type="grouplist" id="14100"> + <animation effect="fade" start="0" end="100" time="400">WindowOpen</animation> + <animation effect="fade" start="100" end="0" time="300">WindowClose</animation> + <animation effect="fade" time="300">VisibleChange</animation> + <animation effect="slide" end="-10,0" time="0" condition ="Window.IsActive(MyPlaylist.xml)">Conditional</animation> + <orientation>horizontal</orientation> + <itemgap>-17</itemgap> + <left>$PARAM[left]</left> + <onleft>14100</onleft> + <width>450</width> + <visible>Player.HasMedia + [$EXP[sidebar_visible]]</visible> + <visible>!System.HasActiveModalDialog</visible> + <include content="BottomMainMenuToggleItem"> + <param name="control_id" value="14101" /> + <param name="onclick" value="PlayerControl(Play)" /> + <param name="icon_on" value="icons/now-playing/play.png" /> + <param name="icon_off" value="icons/now-playing/pause.png" /> + <param name="selected" value="Player.Paused" /> + </include> + <include content="IconButton"> + <param name="control_id" value="14102" /> + <param name="onclick" value="Stop" /> + <param name="onclick_2" value="SetFocus(50)" /> + <param name="icon" value="icons/now-playing/stop.png" /> + </include> + <include content="IconButton"> + <param name="control_id" value="14104" /> + <param name="onclick" value="PlayerControl(Next)" /> + <param name="icon" value="icons/now-playing/next.png" /> + </include> + <include content="IconButton"> + <param name="control_id" value="14105" /> + <param name="onclick" value="Fullscreen" /> + <param name="icon" value="icons/now-playing/fullscreen.png" /> + </include> + </control> + </definition> </include> <include name="MediaMenuListCommon"> <definition> @@ -343,7 +347,6 @@ </control> <control type="button" id="19"> <visible>Container.CanFilter + !Container.CanFilterAdvanced</visible> - <visible>!Container.Content()</visible> <include>MediaMenuItemsCommon</include> <label>$LOCALIZE[137]</label> </control> diff --git a/addons/skin.estuary/xml/MyPlaylist.xml b/addons/skin.estuary/xml/MyPlaylist.xml index 51361f04c8..f66dc10734 100644 --- a/addons/skin.estuary/xml/MyPlaylist.xml +++ b/addons/skin.estuary/xml/MyPlaylist.xml @@ -10,9 +10,9 @@ <control type="group"> <include>OpenClose_Left</include> <control type="fixedlist" id="50"> - <left>402</left> + <left>410</left> <top>list_y_offset</top> - <right>594</right> + <right>586</right> <bottom>list_y_offset</bottom> <scrolltime tween="cubic" easing="out">500</scrolltime> <orientation>vertical</orientation> @@ -79,7 +79,7 @@ <control type="group"> <depth>DepthContentPanel</depth> <include content="ContentPanel"> - <param name="width" value="462" /> + <param name="width" value="470" /> </include> <control type="grouplist" id="700"> <orientation>vertical</orientation> @@ -90,9 +90,9 @@ <ondown>700</ondown> <onleft>50</onleft> <onright>50</onright> - <width>402</width> + <width>410</width> <control type="radiobutton" id="20"> - <width>402</width> + <width>410</width> <height>110</height> <align>left</align> <aligny>top</aligny> @@ -115,6 +115,9 @@ <param name="control_id" value="22" /> <param name="label" value="$LOCALIZE[192]" /> </include> + <include content="MediaMenuNowPlaying"> + <param name="left" value="-5" /> + </include> </control> </control> </control> diff --git a/addons/skin.estuary/xml/MyVideoNav.xml b/addons/skin.estuary/xml/MyVideoNav.xml index 8b2b8f8da3..ea67f8e956 100644 --- a/addons/skin.estuary/xml/MyVideoNav.xml +++ b/addons/skin.estuary/xml/MyVideoNav.xml @@ -138,7 +138,7 @@ <include>MediaMenuItemsCommon</include> <label>$LOCALIZE[31056]</label> <onclick>ActivateWindow(videoplaylist)</onclick> - <visible>IntegerGreaterThan(Playlist.Length(video),0)</visible> + <visible>Integer.IsGreater(Playlist.Length(video),0)</visible> </control> <control type="button" id="621"> <description>Get more</description> diff --git a/addons/skin.estuary/xml/SlideShow.xml b/addons/skin.estuary/xml/SlideShow.xml index bfe6d61c65..666f38cbfb 100644 --- a/addons/skin.estuary/xml/SlideShow.xml +++ b/addons/skin.estuary/xml/SlideShow.xml @@ -1,3 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <window> + <controls> + <control type="image"> + <centerleft>50%</centerleft> + <centertop>50%</centertop> + <width>256</width> + <height>256</height> + <texture>icons/settings/player.png</texture> + <visible>SlideShow.IsVideo + [![Player.Playing + Player.HasVideo] | SlideShow.IsPaused]</visible> + </control> + </controls> </window> diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml index 35407add0b..007ed12300 100644 --- a/addons/skin.estuary/xml/Variables.xml +++ b/addons/skin.estuary/xml/Variables.xml @@ -65,6 +65,12 @@ <value condition="ListItem.IsFolder + String.IsEmpty(ListItem.Thumb)">DefaultFolderSquare.png</value> <value>$INFO[ListItem.Thumb]</value> </variable> + <variable name="MusicInfoThumbVar"> + <value condition="!String.IsEmpty(Listitem.Art(thumb))">$INFO[Listitem.Art(thumb)]</value> + <value condition="String.IsEqual(listitem.dbtype,artist)">DefaultArtist.png</value> + <value condition="String.IsEqual(listitem.dbtype,album)">DefaultAlbumCover.png</value> + <value>DefaultAudio.png</value> + </variable> <variable name="InfoWallThumbVar"> <value condition="!String.IsEmpty(Listitem.Art(poster))">$INFO[Listitem.Art(poster)]</value> <value>$INFO[ListItem.Icon]</value> diff --git a/addons/skin.estuary/xml/View_51_Poster.xml b/addons/skin.estuary/xml/View_51_Poster.xml index 2d3b96de61..ff91cb130d 100644 --- a/addons/skin.estuary/xml/View_51_Poster.xml +++ b/addons/skin.estuary/xml/View_51_Poster.xml @@ -190,6 +190,7 @@ <autoscroll time="3000" delay="7000" repeat="5000">!System.HasActiveModalDialog + Skin.HasSetting(AutoScroll)</autoscroll> <label>$INFO[ListItem.Plot]</label> <shadowcolor>text_shadow</shadowcolor> + <visible>!ListItem.IsCollection</visible> </control> </control> </control> diff --git a/addons/skin.estuary/xml/View_55_WideList.xml b/addons/skin.estuary/xml/View_55_WideList.xml index 6652a00893..7ce10ede2e 100644 --- a/addons/skin.estuary/xml/View_55_WideList.xml +++ b/addons/skin.estuary/xml/View_55_WideList.xml @@ -37,7 +37,7 @@ <aligny>center</aligny> <label>$INFO[ListItem.Year]</label> <shadowcolor>text_shadow</shadowcolor> - <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies)</visible> + <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies) + !Container.Content(videos)</visible> </control> <control type="image"> <left>35</left> @@ -45,7 +45,7 @@ <width>32</width> <height>32</height> <texture>$VAR[ListWatchedIconVar]</texture> - <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | String.IsEmpty(ListItem.Year)</visible> + <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | Container.Content(videos) | String.IsEmpty(ListItem.Year)</visible> </control> <control type="label"> <left>105</left> @@ -78,7 +78,7 @@ <label>$INFO[ListItem.Year]</label> <textcolor>button_focus</textcolor> <shadowcolor>text_shadow</shadowcolor> - <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies)</visible> + <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies) + !Container.Content(videos)</visible> </control> <control type="image"> <left>35</left> @@ -86,7 +86,7 @@ <width>32</width> <height>32</height> <texture colordiffuse="grey">$VAR[ListWatchedIconVar]</texture> - <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | String.IsEmpty(ListItem.Year)</visible> + <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | Container.Content(videos) | String.IsEmpty(ListItem.Year)</visible> </control> <control type="label"> <left>105</left> diff --git a/addons/webinterface.default/addon.xml b/addons/webinterface.default/addon.xml index 92d927bd33..00fdda01c8 100644 --- a/addons/webinterface.default/addon.xml +++ b/addons/webinterface.default/addon.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <addon id="webinterface.default" - version="2.4.1" + version="2.4.2" name="Kodi web interface - Chorus2" provider-name="jez500, Team Kodi"> <requires> diff --git a/addons/webinterface.default/js/kodi-webinterface.js b/addons/webinterface.default/js/kodi-webinterface.js index cdf530f38e..96b78b2df9 100644 --- a/addons/webinterface.default/js/kodi-webinterface.js +++ b/addons/webinterface.default/js/kodi-webinterface.js @@ -1,21 +1,21 @@ -/*! Chorus 2 - A web interface for Kodi. Created by Jeremy Graham - built on 15-01-2017 */ +/*! Chorus 2 - A web interface for Kodi. Created by Jeremy Graham - built on 28-01-2017 */ !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=ea.type(a);return"function"===c||ea.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(ea.isFunction(b))return ea.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return ea.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(ma.test(b))return ea.filter(b,a,c);b=ea.filter(b,a)}return ea.grep(a,function(a){return ea.inArray(a,b)>=0!==c})}function e(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}function f(a){var b=ua[a]={};return ea.each(a.match(ta)||[],function(a,c){b[c]=!0}),b}function g(){oa.addEventListener?(oa.removeEventListener("DOMContentLoaded",h,!1),a.removeEventListener("load",h,!1)):(oa.detachEvent("onreadystatechange",h),a.detachEvent("onload",h))}function h(){(oa.addEventListener||"load"===event.type||"complete"===oa.readyState)&&(g(),ea.ready())}function i(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(za,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:ya.test(c)?ea.parseJSON(c):c}catch(e){}ea.data(a,b,c)}else c=void 0}return c}function j(a){var b;for(b in a)if(("data"!==b||!ea.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function k(a,b,c,d){if(ea.acceptData(a)){var e,f,g=ea.expando,h=a.nodeType,i=h?ea.cache:a,j=h?a[g]:a[g]&&g;if(j&&i[j]&&(d||i[j].data)||void 0!==c||"string"!=typeof b)return j||(j=h?a[g]=W.pop()||ea.guid++:g),i[j]||(i[j]=h?{}:{toJSON:ea.noop}),("object"==typeof b||"function"==typeof b)&&(d?i[j]=ea.extend(i[j],b):i[j].data=ea.extend(i[j].data,b)),f=i[j],d||(f.data||(f.data={}),f=f.data),void 0!==c&&(f[ea.camelCase(b)]=c),"string"==typeof b?(e=f[b],null==e&&(e=f[ea.camelCase(b)])):e=f,e}}function l(a,b,c){if(ea.acceptData(a)){var d,e,f=a.nodeType,g=f?ea.cache:a,h=f?a[ea.expando]:ea.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){ea.isArray(b)?b=b.concat(ea.map(b,ea.camelCase)):b in d?b=[b]:(b=ea.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;for(;e--;)delete d[b[e]];if(c?!j(d):!ea.isEmptyObject(d))return}(c||(delete g[h].data,j(g[h])))&&(f?ea.cleanData([a],!0):ca.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}function m(){return!0}function n(){return!1}function o(){try{return oa.activeElement}catch(a){}}function p(a){var b=Ka.split("|"),c=a.createDocumentFragment();if(c.createElement)for(;b.length;)c.createElement(b.pop());return c}function q(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==xa?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==xa?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||ea.nodeName(d,b)?f.push(d):ea.merge(f,q(d,b));return void 0===b||b&&ea.nodeName(a,b)?ea.merge([a],f):f}function r(a){Ea.test(a.type)&&(a.defaultChecked=a.checked)}function s(a,b){return ea.nodeName(a,"table")&&ea.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function t(a){return a.type=(null!==ea.find.attr(a,"type"))+"/"+a.type,a}function u(a){var b=Va.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function v(a,b){for(var c,d=0;null!=(c=a[d]);d++)ea._data(c,"globalEval",!b||ea._data(b[d],"globalEval"))}function w(a,b){if(1===b.nodeType&&ea.hasData(a)){var c,d,e,f=ea._data(a),g=ea._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)ea.event.add(b,c,h[c][d])}g.data&&(g.data=ea.extend({},g.data))}}function x(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!ca.noCloneEvent&&b[ea.expando]){e=ea._data(b);for(d in e.events)ea.removeEvent(b,d,e.handle);b.removeAttribute(ea.expando)}"script"===c&&b.text!==a.text?(t(b).text=a.text,u(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),ca.html5Clone&&a.innerHTML&&!ea.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Ea.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function y(b,c){var d,e=ea(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:ea.css(e[0],"display");return e.detach(),f}function z(a){var b=oa,c=_a[a];return c||(c=y(a,b),"none"!==c&&c||($a=($a||ea("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=($a[0].contentWindow||$a[0].contentDocument).document,b.write(),b.close(),c=y(a,b),$a.detach()),_a[a]=c),c}function A(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}function B(a,b){if(b in a)return b;for(var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=mb.length;e--;)if(b=mb[e]+c,b in a)return b;return d}function C(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=ea._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&Ca(d)&&(f[g]=ea._data(d,"olddisplay",z(d.nodeName)))):(e=Ca(d),(c&&"none"!==c||!e)&&ea._data(d,"olddisplay",e?c:ea.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function D(a,b,c){var d=ib.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function E(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=ea.css(a,c+Ba[f],!0,e)),d?("content"===c&&(g-=ea.css(a,"padding"+Ba[f],!0,e)),"margin"!==c&&(g-=ea.css(a,"border"+Ba[f]+"Width",!0,e))):(g+=ea.css(a,"padding"+Ba[f],!0,e),"padding"!==c&&(g+=ea.css(a,"border"+Ba[f]+"Width",!0,e)));return g}function F(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=ab(a),g=ca.boxSizing&&"border-box"===ea.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=bb(a,b,f),(0>e||null==e)&&(e=a.style[b]),db.test(e))return e;d=g&&(ca.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+E(a,b,c||(g?"border":"content"),d,f)+"px"}function G(a,b,c,d,e){return new G.prototype.init(a,b,c,d,e)}function H(){return setTimeout(function(){nb=void 0}),nb=ea.now()}function I(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=Ba[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function J(a,b,c){for(var d,e=(tb[b]||[]).concat(tb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function K(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},n=a.style,o=a.nodeType&&Ca(a),p=ea._data(a,"fxshow");c.queue||(h=ea._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,ea.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[n.overflow,n.overflowX,n.overflowY],j=ea.css(a,"display"),k="none"===j?ea._data(a,"olddisplay")||z(a.nodeName):j,"inline"===k&&"none"===ea.css(a,"float")&&(ca.inlineBlockNeedsLayout&&"inline"!==z(a.nodeName)?n.zoom=1:n.display="inline-block")),c.overflow&&(n.overflow="hidden",ca.shrinkWrapBlocks()||l.always(function(){n.overflow=c.overflow[0],n.overflowX=c.overflow[1],n.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],pb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(o?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;o=!0}m[d]=p&&p[d]||ea.style(a,d)}else j=void 0;if(ea.isEmptyObject(m))"inline"===("none"===j?z(a.nodeName):j)&&(n.display=j);else{p?"hidden"in p&&(o=p.hidden):p=ea._data(a,"fxshow",{}),f&&(p.hidden=!o),o?ea(a).show():l.done(function(){ea(a).hide()}),l.done(function(){var b;ea._removeData(a,"fxshow");for(b in m)ea.style(a,b,m[b])});for(d in m)g=J(o?p[d]:0,d,l),d in p||(p[d]=g.start,o&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function L(a,b){var c,d,e,f,g;for(c in a)if(d=ea.camelCase(c),e=b[d],f=a[c],ea.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=ea.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function M(a,b,c){var d,e,f=0,g=sb.length,h=ea.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=nb||H(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:ea.extend({},b),opts:ea.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:nb||H(),duration:c.duration,tweens:[],createTween:function(b,c){var d=ea.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(L(k,j.opts.specialEasing);g>f;f++)if(d=sb[f].call(j,a,k,j.opts))return d;return ea.map(k,J,j),ea.isFunction(j.opts.start)&&j.opts.start.call(a,j),ea.fx.timer(ea.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function N(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(ta)||[];if(ea.isFunction(c))for(;d=f[e++];)"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function O(a,b,c,d){function e(h){var i;return f[h]=!0,ea.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||g||f[j]?g?!(i=j):void 0:(b.dataTypes.unshift(j),e(j),!1)}),i}var f={},g=a===Rb;return e(b.dataTypes[0])||!f["*"]&&e("*")}function P(a,b){var c,d,e=ea.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&ea.extend(!0,a,c),a}function Q(a,b,c){for(var d,e,f,g,h=a.contents,i=a.dataTypes;"*"===i[0];)i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function R(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];for(f=k.shift();f;)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}function S(a,b,c,d){var e;if(ea.isArray(b))ea.each(b,function(b,e){c||Vb.test(a)?d(a,e):S(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==ea.type(b))d(a,b);else for(e in b)S(a+"["+e+"]",b[e],c,d)}function T(){try{return new a.XMLHttpRequest}catch(b){}}function U(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function V(a){return ea.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}var W=[],X=W.slice,Y=W.concat,Z=W.push,$=W.indexOf,_={},aa=_.toString,ba=_.hasOwnProperty,ca={},da="1.11.1",ea=function(a,b){return new ea.fn.init(a,b)},fa=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,ga=/^-ms-/,ha=/-([\da-z])/gi,ia=function(a,b){return b.toUpperCase()};ea.fn=ea.prototype={jquery:da,constructor:ea,selector:"",length:0,toArray:function(){return X.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:X.call(this)},pushStack:function(a){var b=ea.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return ea.each(this,a,b)},map:function(a){return this.pushStack(ea.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(X.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:Z,sort:W.sort,splice:W.splice},ea.extend=ea.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||ea.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(ea.isPlainObject(c)||(b=ea.isArray(c)))?(b?(b=!1,f=a&&ea.isArray(a)?a:[]):f=a&&ea.isPlainObject(a)?a:{},g[d]=ea.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},ea.extend({expando:"jQuery"+(da+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===ea.type(a)},isArray:Array.isArray||function(a){return"array"===ea.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!ea.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==ea.type(a)||a.nodeType||ea.isWindow(a))return!1;try{if(a.constructor&&!ba.call(a,"constructor")&&!ba.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(ca.ownLast)for(b in a)return ba.call(a,b);for(b in a);return void 0===b||ba.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?_[aa.call(a)]||"object":typeof a},globalEval:function(b){b&&ea.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(ga,"ms-").replace(ha,ia)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,d){var e,f=0,g=a.length,h=c(a);if(d){if(h)for(;g>f&&(e=b.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=b.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=b.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=b.call(a[f],f,a[f]),e===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(fa,"")},makeArray:function(a,b){var d=b||[];return null!=a&&(c(Object(a))?ea.merge(d,"string"==typeof a?[a]:a):Z.call(d,a)),d},inArray:function(a,b,c){var d;if(b){if($)return $.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;)a[e++]=b[d++];if(c!==c)for(;void 0!==b[d];)a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,d){var e,f=0,g=a.length,h=c(a),i=[];if(h)for(;g>f;f++)e=b(a[f],f,d),null!=e&&i.push(e);else for(f in a)e=b(a[f],f,d),null!=e&&i.push(e);return Y.apply([],i)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(e=a[b],b=a,a=e),ea.isFunction(a)?(c=X.call(arguments,2),d=function(){return a.apply(b||this,c.concat(X.call(arguments)))},d.guid=a.guid=a.guid||ea.guid++,d):void 0},now:function(){return+new Date},support:ca}),ea.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){_["[object "+b+"]"]=b.toLowerCase()});var ja=function(a){function b(a,b,c,d){var e,f,g,h,i,j,l,n,o,p;if((b?b.ownerDocument||b:O)!==G&&F(b),b=b||G,c=c||[],!a||"string"!=typeof a)return c;if(1!==(h=b.nodeType)&&9!==h)return[];if(I&&!d){if(e=sa.exec(a))if(g=e[1]){if(9===h){if(f=b.getElementById(g),!f||!f.parentNode)return c;if(f.id===g)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(g))&&M(b,f)&&f.id===g)return c.push(f),c}else{if(e[2])return _.apply(c,b.getElementsByTagName(a)),c;if((g=e[3])&&v.getElementsByClassName&&b.getElementsByClassName)return _.apply(c,b.getElementsByClassName(g)),c}if(v.qsa&&(!J||!J.test(a))){if(n=l=N,o=b,p=9===h&&a,1===h&&"object"!==b.nodeName.toLowerCase()){for(j=z(a),(l=b.getAttribute("id"))?n=l.replace(ua,"\\$&"):b.setAttribute("id",n),n="[id='"+n+"'] ",i=j.length;i--;)j[i]=n+m(j[i]);o=ta.test(a)&&k(b.parentNode)||b,p=j.join(",")}if(p)try{return _.apply(c,o.querySelectorAll(p)),c}catch(q){}finally{l||b.removeAttribute("id")}}}return B(a.replace(ia,"$1"),b,c,d)}function c(){function a(c,d){return b.push(c+" ")>w.cacheLength&&delete a[b.shift()],a[c+" "]=d}var b=[];return a}function d(a){return a[N]=!0,a}function e(a){var b=G.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function f(a,b){for(var c=a.split("|"),d=a.length;d--;)w.attrHandle[c[d]]=b}function g(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||W)-(~a.sourceIndex||W);if(d)return d;if(c)for(;c=c.nextSibling;)if(c===b)return-1;return a?1:-1}function h(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function i(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function j(a){return d(function(b){return b=+b,d(function(c,d){for(var e,f=a([],c.length,b),g=f.length;g--;)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function k(a){return a&&typeof a.getElementsByTagName!==V&&a}function l(){}function m(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function n(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=Q++;return b.first?function(b,c,f){for(;b=b[d];)if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[P,f];if(g){for(;b=b[d];)if((1===b.nodeType||e)&&a(b,c,g))return!0}else for(;b=b[d];)if(1===b.nodeType||e){if(i=b[N]||(b[N]={}),(h=i[d])&&h[0]===P&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function o(a){return a.length>1?function(b,c,d){for(var e=a.length;e--;)if(!a[e](b,c,d))return!1;return!0}:a[0]}function p(a,c,d){for(var e=0,f=c.length;f>e;e++)b(a,c[e],d);return d}function q(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function r(a,b,c,e,f,g){return e&&!e[N]&&(e=r(e)),f&&!f[N]&&(f=r(f,g)),d(function(d,g,h,i){var j,k,l,m=[],n=[],o=g.length,r=d||p(b||"*",h.nodeType?[h]:h,[]),s=!a||!d&&b?r:q(r,m,a,h,i),t=c?f||(d?a:o||e)?[]:g:s;if(c&&c(s,t,h,i),e)for(j=q(t,n),e(j,[],h,i),k=j.length;k--;)(l=j[k])&&(t[n[k]]=!(s[n[k]]=l));if(d){if(f||a){if(f){for(j=[],k=t.length;k--;)(l=t[k])&&j.push(s[k]=l);f(null,t=[],j,i)}for(k=t.length;k--;)(l=t[k])&&(j=f?ba.call(d,l):m[k])>-1&&(d[j]=!(g[j]=l))}}else t=q(t===g?t.splice(o,t.length):t),f?f(null,g,t,i):_.apply(g,t)})}function s(a){for(var b,c,d,e=a.length,f=w.relative[a[0].type],g=f||w.relative[" "],h=f?1:0,i=n(function(a){return a===b},g,!0),j=n(function(a){return ba.call(b,a)>-1},g,!0),k=[function(a,c,d){return!f&&(d||c!==C)||((b=c).nodeType?i(a,c,d):j(a,c,d))}];e>h;h++)if(c=w.relative[a[h].type])k=[n(o(k),c)];else{if(c=w.filter[a[h].type].apply(null,a[h].matches),c[N]){for(d=++h;e>d&&!w.relative[a[d].type];d++);return r(h>1&&o(k),h>1&&m(a.slice(0,h-1).concat({value:" "===a[h-2].type?"*":""})).replace(ia,"$1"),c,d>h&&s(a.slice(h,d)),e>d&&s(a=a.slice(d)),e>d&&m(a))}k.push(c)}return o(k)}function t(a,c){var e=c.length>0,f=a.length>0,g=function(d,g,h,i,j){var k,l,m,n=0,o="0",p=d&&[],r=[],s=C,t=d||f&&w.find.TAG("*",j),u=P+=null==s?1:Math.random()||.1,v=t.length;for(j&&(C=g!==G&&g);o!==v&&null!=(k=t[o]);o++){if(f&&k){for(l=0;m=a[l++];)if(m(k,g,h)){i.push(k);break}j&&(P=u)}e&&((k=!m&&k)&&n--,d&&p.push(k))}if(n+=o,e&&o!==n){for(l=0;m=c[l++];)m(p,r,g,h);if(d){if(n>0)for(;o--;)p[o]||r[o]||(r[o]=Z.call(i));r=q(r)}_.apply(i,r),j&&!d&&r.length>0&&n+c.length>1&&b.uniqueSort(i)}return j&&(P=u,C=s),p};return e?d(g):g}var u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N="sizzle"+-new Date,O=a.document,P=0,Q=0,R=c(),S=c(),T=c(),U=function(a,b){return a===b&&(E=!0),0},V="undefined",W=1<<31,X={}.hasOwnProperty,Y=[],Z=Y.pop,$=Y.push,_=Y.push,aa=Y.slice,ba=Y.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},ca="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",da="[\\x20\\t\\r\\n\\f]",ea="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",fa=ea.replace("w","w#"),ga="\\["+da+"*("+ea+")(?:"+da+"*([*^$|!~]?=)"+da+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+fa+"))|)"+da+"*\\]",ha=":("+ea+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+ga+")*)|.*)\\)|)",ia=new RegExp("^"+da+"+|((?:^|[^\\\\])(?:\\\\.)*)"+da+"+$","g"),ja=new RegExp("^"+da+"*,"+da+"*"),ka=new RegExp("^"+da+"*([>+~]|"+da+")"+da+"*"),la=new RegExp("="+da+"*([^\\]'\"]*?)"+da+"*\\]","g"),ma=new RegExp(ha),na=new RegExp("^"+fa+"$"),oa={ID:new RegExp("^#("+ea+")"),CLASS:new RegExp("^\\.("+ea+")"),TAG:new RegExp("^("+ea.replace("w","w*")+")"),ATTR:new RegExp("^"+ga),PSEUDO:new RegExp("^"+ha),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+da+"*(even|odd|(([+-]|)(\\d*)n|)"+da+"*(?:([+-]|)"+da+"*(\\d+)|))"+da+"*\\)|)","i"),bool:new RegExp("^(?:"+ca+")$","i"),needsContext:new RegExp("^"+da+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+da+"*((?:-\\d)?\\d*)"+da+"*\\)|)(?=[^-]|$)","i")},pa=/^(?:input|select|textarea|button)$/i,qa=/^h\d$/i,ra=/^[^{]+\{\s*\[native \w/,sa=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ta=/[+~]/,ua=/'|\\/g,va=new RegExp("\\\\([\\da-f]{1,6}"+da+"?|("+da+")|.)","ig"),wa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{_.apply(Y=aa.call(O.childNodes),O.childNodes),Y[O.childNodes.length].nodeType}catch(xa){_={apply:Y.length?function(a,b){$.apply(a,aa.call(b))}:function(a,b){for(var c=a.length,d=0;a[c++]=b[d++];);a.length=c-1}}}v=b.support={},y=b.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},F=b.setDocument=function(a){var b,c=a?a.ownerDocument||a:O,d=c.defaultView;return c!==G&&9===c.nodeType&&c.documentElement?(G=c,H=c.documentElement,I=!y(c),d&&d!==d.top&&(d.addEventListener?d.addEventListener("unload",function(){F()},!1):d.attachEvent&&d.attachEvent("onunload",function(){F()})),v.attributes=e(function(a){return a.className="i",!a.getAttribute("className")}),v.getElementsByTagName=e(function(a){return a.appendChild(c.createComment("")),!a.getElementsByTagName("*").length}),v.getElementsByClassName=ra.test(c.getElementsByClassName)&&e(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),v.getById=e(function(a){return H.appendChild(a).id=N,!c.getElementsByName||!c.getElementsByName(N).length}),v.getById?(w.find.ID=function(a,b){if(typeof b.getElementById!==V&&I){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},w.filter.ID=function(a){var b=a.replace(va,wa);return function(a){return a.getAttribute("id")===b}}):(delete w.find.ID,w.filter.ID=function(a){var b=a.replace(va,wa);return function(a){var c=typeof a.getAttributeNode!==V&&a.getAttributeNode("id");return c&&c.value===b}}),w.find.TAG=v.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==V?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){for(;c=f[e++];)1===c.nodeType&&d.push(c);return d}return f},w.find.CLASS=v.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==V&&I?b.getElementsByClassName(a):void 0},K=[],J=[],(v.qsa=ra.test(c.querySelectorAll))&&(e(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&J.push("[*^$]="+da+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||J.push("\\["+da+"*(?:value|"+ca+")"),a.querySelectorAll(":checked").length||J.push(":checked")}),e(function(a){var b=c.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&J.push("name"+da+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||J.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),J.push(",.*:")})),(v.matchesSelector=ra.test(L=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&e(function(a){v.disconnectedMatch=L.call(a,"div"),L.call(a,"[s!='']:x"),K.push("!=",ha)}),J=J.length&&new RegExp(J.join("|")),K=K.length&&new RegExp(K.join("|")),b=ra.test(H.compareDocumentPosition),M=b||ra.test(H.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b=b.parentNode;)if(b===a)return!0;return!1},U=b?function(a,b){if(a===b)return E=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!v.sortDetached&&b.compareDocumentPosition(a)===d?a===c||a.ownerDocument===O&&M(O,a)?-1:b===c||b.ownerDocument===O&&M(O,b)?1:D?ba.call(D,a)-ba.call(D,b):0:4&d?-1:1)}:function(a,b){if(a===b)return E=!0,0;var d,e=0,f=a.parentNode,h=b.parentNode,i=[a],j=[b];if(!f||!h)return a===c?-1:b===c?1:f?-1:h?1:D?ba.call(D,a)-ba.call(D,b):0;if(f===h)return g(a,b);for(d=a;d=d.parentNode;)i.unshift(d);for(d=b;d=d.parentNode;)j.unshift(d);for(;i[e]===j[e];)e++;return e?g(i[e],j[e]):i[e]===O?-1:j[e]===O?1:0},c):G},b.matches=function(a,c){return b(a,null,null,c)},b.matchesSelector=function(a,c){if((a.ownerDocument||a)!==G&&F(a),c=c.replace(la,"='$1']"),v.matchesSelector&&I&&(!K||!K.test(c))&&(!J||!J.test(c)))try{var d=L.call(a,c);if(d||v.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return b(c,G,null,[a]).length>0},b.contains=function(a,b){return(a.ownerDocument||a)!==G&&F(a),M(a,b)},b.attr=function(a,b){(a.ownerDocument||a)!==G&&F(a);var c=w.attrHandle[b.toLowerCase()],d=c&&X.call(w.attrHandle,b.toLowerCase())?c(a,b,!I):void 0;return void 0!==d?d:v.attributes||!I?a.getAttribute(b):(d=a.getAttributeNode(b))&&d.specified?d.value:null},b.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},b.uniqueSort=function(a){var b,c=[],d=0,e=0;if(E=!v.detectDuplicates,D=!v.sortStable&&a.slice(0),a.sort(U),E){for(;b=a[e++];)b===a[e]&&(d=c.push(e));for(;d--;)a.splice(c[d],1)}return D=null,a},x=b.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(1===e||9===e||11===e){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=x(a)}else if(3===e||4===e)return a.nodeValue}else for(;b=a[d++];)c+=x(b);return c},w=b.selectors={cacheLength:50,createPseudo:d,match:oa,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(va,wa),a[3]=(a[3]||a[4]||a[5]||"").replace(va,wa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||b.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&b.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return oa.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&ma.test(c)&&(b=z(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(va,wa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=R[a+" "];return b||(b=new RegExp("(^|"+da+")"+a+"("+da+"|$)"))&&R(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==V&&a.getAttribute("class")||"")})},ATTR:function(a,c,d){return function(e){var f=b.attr(e,a);return null==f?"!="===c:c?(f+="","="===c?f===d:"!="===c?f!==d:"^="===c?d&&0===f.indexOf(d):"*="===c?d&&f.indexOf(d)>-1:"$="===c?d&&f.slice(-d.length)===d:"~="===c?(" "+f+" ").indexOf(d)>-1:"|="===c?f===d||f.slice(0,d.length+1)===d+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){for(;p;){for(l=b;l=l[p];)if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){for(k=q[N]||(q[N]={}),j=k[a]||[],n=j[0]===P&&j[1],m=j[0]===P&&j[2],l=n&&q.childNodes[n];l=++n&&l&&l[p]||(m=n=0)||o.pop();)if(1===l.nodeType&&++m&&l===b){k[a]=[P,n,m];break}}else if(s&&(j=(b[N]||(b[N]={}))[a])&&j[0]===P)m=j[1];else for(;(l=++n&&l&&l[p]||(m=n=0)||o.pop())&&((h?l.nodeName.toLowerCase()!==r:1!==l.nodeType)||!++m||(s&&((l[N]||(l[N]={}))[a]=[P,m]),l!==b)););return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,c){var e,f=w.pseudos[a]||w.setFilters[a.toLowerCase()]||b.error("unsupported pseudo: "+a);return f[N]?f(c):f.length>1?(e=[a,a,"",c],w.setFilters.hasOwnProperty(a.toLowerCase())?d(function(a,b){for(var d,e=f(a,c),g=e.length;g--;)d=ba.call(a,e[g]),a[d]=!(b[d]=e[g])}):function(a){return f(a,0,e)}):f}},pseudos:{not:d(function(a){var b=[],c=[],e=A(a.replace(ia,"$1"));return e[N]?d(function(a,b,c,d){for(var f,g=e(a,null,d,[]),h=a.length;h--;)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,d,f){return b[0]=a,e(b,null,f,c),!c.pop()}}),has:d(function(a){return function(c){return b(a,c).length>0}}),contains:d(function(a){return function(b){return(b.textContent||b.innerText||x(b)).indexOf(a)>-1}}),lang:d(function(a){return na.test(a||"")||b.error("unsupported lang: "+a),a=a.replace(va,wa).toLowerCase(),function(b){var c;do if(c=I?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===H},focus:function(a){return a===G.activeElement&&(!G.hasFocus||G.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!w.pseudos.empty(a)},header:function(a){return qa.test(a.nodeName)},input:function(a){return pa.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:j(function(){return[0]}),last:j(function(a,b){return[b-1]}),eq:j(function(a,b,c){return[0>c?c+b:c]}),even:j(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:j(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:j(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:j(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},w.pseudos.nth=w.pseudos.eq;for(u in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})w.pseudos[u]=h(u);for(u in{submit:!0,reset:!0})w.pseudos[u]=i(u);return l.prototype=w.filters=w.pseudos,w.setFilters=new l,z=b.tokenize=function(a,c){var d,e,f,g,h,i,j,k=S[a+" "];if(k)return c?0:k.slice(0);for(h=a,i=[],j=w.preFilter;h;){(!d||(e=ja.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),d=!1,(e=ka.exec(h))&&(d=e.shift(),f.push({value:d,type:e[0].replace(ia," ")}),h=h.slice(d.length));for(g in w.filter)!(e=oa[g].exec(h))||j[g]&&!(e=j[g](e))||(d=e.shift(),f.push({value:d,type:g,matches:e }),h=h.slice(d.length));if(!d)break}return c?h.length:h?b.error(a):S(a,i).slice(0)},A=b.compile=function(a,b){var c,d=[],e=[],f=T[a+" "];if(!f){for(b||(b=z(a)),c=b.length;c--;)f=s(b[c]),f[N]?d.push(f):e.push(f);f=T(a,t(e,d)),f.selector=a}return f},B=b.select=function(a,b,c,d){var e,f,g,h,i,j="function"==typeof a&&a,l=!d&&z(a=j.selector||a);if(c=c||[],1===l.length){if(f=l[0]=l[0].slice(0),f.length>2&&"ID"===(g=f[0]).type&&v.getById&&9===b.nodeType&&I&&w.relative[f[1].type]){if(b=(w.find.ID(g.matches[0].replace(va,wa),b)||[])[0],!b)return c;j&&(b=b.parentNode),a=a.slice(f.shift().value.length)}for(e=oa.needsContext.test(a)?0:f.length;e--&&(g=f[e],!w.relative[h=g.type]);)if((i=w.find[h])&&(d=i(g.matches[0].replace(va,wa),ta.test(f[0].type)&&k(b.parentNode)||b))){if(f.splice(e,1),a=d.length&&m(f),!a)return _.apply(c,d),c;break}}return(j||A(a,l))(d,b,!I,c,ta.test(a)&&k(b.parentNode)||b),c},v.sortStable=N.split("").sort(U).join("")===N,v.detectDuplicates=!!E,F(),v.sortDetached=e(function(a){return 1&a.compareDocumentPosition(G.createElement("div"))}),e(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||f("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),v.attributes&&e(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||f("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),e(function(a){return null==a.getAttribute("disabled")})||f(ca,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),b}(a);ea.find=ja,ea.expr=ja.selectors,ea.expr[":"]=ea.expr.pseudos,ea.unique=ja.uniqueSort,ea.text=ja.getText,ea.isXMLDoc=ja.isXML,ea.contains=ja.contains;var ka=ea.expr.match.needsContext,la=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ma=/^.[^:#\[\.,]*$/;ea.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?ea.find.matchesSelector(d,a)?[d]:[]:ea.find.matches(a,ea.grep(b,function(a){return 1===a.nodeType}))},ea.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(ea(a).filter(function(){for(b=0;e>b;b++)if(ea.contains(d[b],this))return!0}));for(b=0;e>b;b++)ea.find(a,d[b],c);return c=this.pushStack(e>1?ea.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(d(this,a||[],!1))},not:function(a){return this.pushStack(d(this,a||[],!0))},is:function(a){return!!d(this,"string"==typeof a&&ka.test(a)?ea(a):a||[],!1).length}});var na,oa=a.document,pa=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,qa=ea.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:pa.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||na).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof ea?b[0]:b,ea.merge(this,ea.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:oa,!0)),la.test(c[1])&&ea.isPlainObject(b))for(c in b)ea.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=oa.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return na.find(a);this.length=1,this[0]=d}return this.context=oa,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):ea.isFunction(a)?"undefined"!=typeof na.ready?na.ready(a):a(ea):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),ea.makeArray(a,this))};qa.prototype=ea.fn,na=ea(oa);var ra=/^(?:parents|prev(?:Until|All))/,sa={children:!0,contents:!0,next:!0,prev:!0};ea.extend({dir:function(a,b,c){for(var d=[],e=a[b];e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!ea(e).is(c));)1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),ea.fn.extend({has:function(a){var b,c=ea(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(ea.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=ka.test(a)||"string"!=typeof a?ea(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&ea.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?ea.unique(f):f)},index:function(a){return a?"string"==typeof a?ea.inArray(this[0],ea(a)):ea.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(ea.unique(ea.merge(this.get(),ea(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}}),ea.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return ea.dir(a,"parentNode")},parentsUntil:function(a,b,c){return ea.dir(a,"parentNode",c)},next:function(a){return e(a,"nextSibling")},prev:function(a){return e(a,"previousSibling")},nextAll:function(a){return ea.dir(a,"nextSibling")},prevAll:function(a){return ea.dir(a,"previousSibling")},nextUntil:function(a,b,c){return ea.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return ea.dir(a,"previousSibling",c)},siblings:function(a){return ea.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return ea.sibling(a.firstChild)},contents:function(a){return ea.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:ea.merge([],a.childNodes)}},function(a,b){ea.fn[a]=function(c,d){var e=ea.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=ea.filter(d,e)),this.length>1&&(sa[a]||(e=ea.unique(e)),ra.test(a)&&(e=e.reverse())),this.pushStack(e)}});var ta=/\S+/g,ua={};ea.Callbacks=function(a){a="string"==typeof a?ua[a]||f(a):ea.extend({},a);var b,c,d,e,g,h,i=[],j=!a.once&&[],k=function(f){for(c=a.memory&&f,d=!0,g=h||0,h=0,e=i.length,b=!0;i&&e>g;g++)if(i[g].apply(f[0],f[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var d=i.length;!function f(b){ea.each(b,function(b,c){var d=ea.type(c);"function"===d?a.unique&&l.has(c)||i.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=i.length:c&&(h=d,k(c))}return this},remove:function(){return i&&ea.each(arguments,function(a,c){for(var d;(d=ea.inArray(c,i,d))>-1;)i.splice(d,1),b&&(e>=d&&e--,g>=d&&g--)}),this},has:function(a){return a?ea.inArray(a,i)>-1:!(!i||!i.length)},empty:function(){return i=[],e=0,this},disable:function(){return i=j=c=void 0,this},disabled:function(){return!i},lock:function(){return j=void 0,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,c){return!i||d&&!j||(c=c||[],c=[a,c.slice?c.slice():c],b?j.push(c):k(c)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},ea.extend({Deferred:function(a){var b=[["resolve","done",ea.Callbacks("once memory"),"resolved"],["reject","fail",ea.Callbacks("once memory"),"rejected"],["notify","progress",ea.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return ea.Deferred(function(c){ea.each(b,function(b,f){var g=ea.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&ea.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?ea.extend(a,d):d}},e={};return d.pipe=d.then,ea.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b,c,d,e=0,f=X.call(arguments),g=f.length,h=1!==g||a&&ea.isFunction(a.promise)?g:0,i=1===h?a:ea.Deferred(),j=function(a,c,d){return function(e){c[a]=this,d[a]=arguments.length>1?X.call(arguments):e,d===b?i.notifyWith(c,d):--h||i.resolveWith(c,d)}};if(g>1)for(b=new Array(g),c=new Array(g),d=new Array(g);g>e;e++)f[e]&&ea.isFunction(f[e].promise)?f[e].promise().done(j(e,d,f)).fail(i.reject).progress(j(e,c,b)):--h;return h||i.resolveWith(d,f),i.promise()}});var va;ea.fn.ready=function(a){return ea.ready.promise().done(a),this},ea.extend({isReady:!1,readyWait:1,holdReady:function(a){a?ea.readyWait++:ea.ready(!0)},ready:function(a){if(a===!0?!--ea.readyWait:!ea.isReady){if(!oa.body)return setTimeout(ea.ready);ea.isReady=!0,a!==!0&&--ea.readyWait>0||(va.resolveWith(oa,[ea]),ea.fn.triggerHandler&&(ea(oa).triggerHandler("ready"),ea(oa).off("ready")))}}}),ea.ready.promise=function(b){if(!va)if(va=ea.Deferred(),"complete"===oa.readyState)setTimeout(ea.ready);else if(oa.addEventListener)oa.addEventListener("DOMContentLoaded",h,!1),a.addEventListener("load",h,!1);else{oa.attachEvent("onreadystatechange",h),a.attachEvent("onload",h);var c=!1;try{c=null==a.frameElement&&oa.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!ea.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}g(),ea.ready()}}()}return va.promise(b)};var wa,xa="undefined";for(wa in ea(ca))break;ca.ownLast="0"!==wa,ca.inlineBlockNeedsLayout=!1,ea(function(){var a,b,c,d;c=oa.getElementsByTagName("body")[0],c&&c.style&&(b=oa.createElement("div"),d=oa.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==xa&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",ca.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=oa.createElement("div");if(null==ca.deleteExpando){ca.deleteExpando=!0;try{delete a.test}catch(b){ca.deleteExpando=!1}}a=null}(),ea.acceptData=function(a){var b=ea.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var ya=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,za=/([A-Z])/g;ea.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?ea.cache[a[ea.expando]]:a[ea.expando],!!a&&!j(a)},data:function(a,b,c){return k(a,b,c)},removeData:function(a,b){return l(a,b)},_data:function(a,b,c){return k(a,b,c,!0)},_removeData:function(a,b){return l(a,b,!0)}}),ea.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=ea.data(f),1===f.nodeType&&!ea._data(f,"parsedAttrs"))){for(c=g.length;c--;)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=ea.camelCase(d.slice(5)),i(f,d,e[d])));ea._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){ea.data(this,a)}):arguments.length>1?this.each(function(){ea.data(this,a,b)}):f?i(f,a,ea.data(f,a)):void 0},removeData:function(a){return this.each(function(){ea.removeData(this,a)})}}),ea.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=ea._data(a,b),c&&(!d||ea.isArray(c)?d=ea._data(a,b,ea.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=ea.queue(a,b),d=c.length,e=c.shift(),f=ea._queueHooks(a,b),g=function(){ea.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return ea._data(a,c)||ea._data(a,c,{empty:ea.Callbacks("once memory").add(function(){ea._removeData(a,b+"queue"),ea._removeData(a,c)})})}}),ea.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?ea.queue(this[0],a):void 0===b?this:this.each(function(){var c=ea.queue(this,a,b);ea._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&ea.dequeue(this,a)})},dequeue:function(a){return this.each(function(){ea.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=ea.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};for("string"!=typeof a&&(b=a,a=void 0),a=a||"fx";g--;)c=ea._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,Ba=["Top","Right","Bottom","Left"],Ca=function(a,b){return a=b||a,"none"===ea.css(a,"display")||!ea.contains(a.ownerDocument,a)},Da=ea.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===ea.type(c)){e=!0;for(h in c)ea.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,ea.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(ea(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Ea=/^(?:checkbox|radio)$/i;!function(){var a=oa.createElement("input"),b=oa.createElement("div"),c=oa.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",ca.leadingWhitespace=3===b.firstChild.nodeType,ca.tbody=!b.getElementsByTagName("tbody").length,ca.htmlSerialize=!!b.getElementsByTagName("link").length,ca.html5Clone="<:nav></:nav>"!==oa.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),ca.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",ca.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",ca.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,ca.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){ca.noCloneEvent=!1}),b.cloneNode(!0).click()),null==ca.deleteExpando){ca.deleteExpando=!0;try{delete b.test}catch(d){ca.deleteExpando=!1}}}(),function(){var b,c,d=oa.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(ca[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),ca[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Fa=/^(?:input|select|textarea)$/i,Ga=/^key/,Ha=/^(?:mouse|pointer|contextmenu)|click/,Ia=/^(?:focusinfocus|focusoutblur)$/,Ja=/^([^.]*)(?:\.(.+)|)$/;ea.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=ea._data(a);if(q){for(c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=ea.guid++),(g=q.events)||(g=q.events={}),(k=q.handle)||(k=q.handle=function(a){return typeof ea===xa||a&&ea.event.triggered===a.type?void 0:ea.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(ta)||[""],h=b.length;h--;)f=Ja.exec(b[h])||[],n=p=f[1],o=(f[2]||"").split(".").sort(),n&&(j=ea.event.special[n]||{},n=(e?j.delegateType:j.bindType)||n,j=ea.event.special[n]||{},l=ea.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&ea.expr.match.needsContext.test(e),namespace:o.join(".")},i),(m=g[n])||(m=g[n]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,o,k)!==!1||(a.addEventListener?a.addEventListener(n,k,!1):a.attachEvent&&a.attachEvent("on"+n,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),ea.event.global[n]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=ea.hasData(a)&&ea._data(a);if(q&&(k=q.events)){for(b=(b||"").match(ta)||[""],j=b.length;j--;)if(h=Ja.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){for(l=ea.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=k[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;f--;)g=m[f],!e&&p!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||ea.removeEvent(a,n,q.handle),delete k[n])}else for(n in k)ea.event.remove(a,n+b[j],c,d,!0);ea.isEmptyObject(k)&&(delete q.handle,ea._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,j,k,l,m=[d||oa],n=ba.call(b,"type")?b.type:b,o=ba.call(b,"namespace")?b.namespace.split("."):[];if(h=k=d=d||oa,3!==d.nodeType&&8!==d.nodeType&&!Ia.test(n+ea.event.triggered)&&(n.indexOf(".")>=0&&(o=n.split("."),n=o.shift(),o.sort()),g=n.indexOf(":")<0&&"on"+n,b=b[ea.expando]?b:new ea.Event(n,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=o.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:ea.makeArray(c,[b]),j=ea.event.special[n]||{},e||!j.trigger||j.trigger.apply(d,c)!==!1)){if(!e&&!j.noBubble&&!ea.isWindow(d)){for(i=j.delegateType||n,Ia.test(i+n)||(h=h.parentNode);h;h=h.parentNode)m.push(h),k=h;k===(d.ownerDocument||oa)&&m.push(k.defaultView||k.parentWindow||a)}for(l=0;(h=m[l++])&&!b.isPropagationStopped();)b.type=l>1?i:j.bindType||n,f=(ea._data(h,"events")||{})[b.type]&&ea._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&ea.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=n,!e&&!b.isDefaultPrevented()&&(!j._default||j._default.apply(m.pop(),c)===!1)&&ea.acceptData(d)&&g&&d[n]&&!ea.isWindow(d)){k=d[g],k&&(d[g]=null),ea.event.triggered=n;try{d[n]()}catch(p){}ea.event.triggered=void 0,k&&(d[g]=k)}return b.result}},dispatch:function(a){a=ea.event.fix(a);var b,c,d,e,f,g=[],h=X.call(arguments),i=(ea._data(this,"events")||{})[a.type]||[],j=ea.event.special[a.type]||{};if(h[0]=a,a.delegateTarget=this,!j.preDispatch||j.preDispatch.call(this,a)!==!1){for(g=ea.event.handlers.call(this,a,i),b=0;(e=g[b++])&&!a.isPropagationStopped();)for(a.currentTarget=e.elem,f=0;(d=e.handlers[f++])&&!a.isImmediatePropagationStopped();)(!a.namespace_re||a.namespace_re.test(d.namespace))&&(a.handleObj=d,a.data=d.data,c=((ea.event.special[d.origType]||{}).handle||d.handler).apply(e.elem,h),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()));return j.postDispatch&&j.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?ea(c,this).index(i)>=0:ea.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[ea.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];for(g||(this.fixHooks[e]=g=Ha.test(e)?this.mouseHooks:Ga.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new ea.Event(f),b=d.length;b--;)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||oa),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||oa,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==o()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===o()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return ea.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return ea.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=ea.extend(new ea.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?ea.event.trigger(e,null,b):ea.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},ea.removeEvent=oa.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===xa&&(a[d]=null),a.detachEvent(d,c))},ea.Event=function(a,b){return this instanceof ea.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?m:n):this.type=a,b&&ea.extend(this,b),this.timeStamp=a&&a.timeStamp||ea.now(),void(this[ea.expando]=!0)):new ea.Event(a,b)},ea.Event.prototype={isDefaultPrevented:n,isPropagationStopped:n,isImmediatePropagationStopped:n,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=m,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=m,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=m,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},ea.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){ea.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!ea.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),ca.submitBubbles||(ea.event.special.submit={setup:function(){return ea.nodeName(this,"form")?!1:void ea.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=ea.nodeName(b,"input")||ea.nodeName(b,"button")?b.form:void 0;c&&!ea._data(c,"submitBubbles")&&(ea.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),ea._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&ea.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return ea.nodeName(this,"form")?!1:void ea.event.remove(this,"._submit")}}),ca.changeBubbles||(ea.event.special.change={setup:function(){return Fa.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(ea.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),ea.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),ea.event.simulate("change",this,a,!0)})),!1):void ea.event.add(this,"beforeactivate._change",function(a){var b=a.target;Fa.test(b.nodeName)&&!ea._data(b,"changeBubbles")&&(ea.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||ea.event.simulate("change",this.parentNode,a,!0)}),ea._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return ea.event.remove(this,"._change"),!Fa.test(this.nodeName)}}),ca.focusinBubbles||ea.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){ea.event.simulate(b,a.target,ea.event.fix(a),!0)};ea.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=ea._data(d,b);e||d.addEventListener(a,c,!0),ea._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=ea._data(d,b)-1;e?ea._data(d,b,e):(d.removeEventListener(a,c,!0),ea._removeData(d,b))}}}),ea.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=n;else if(!d)return this;return 1===e&&(g=d,d=function(a){return ea().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=ea.guid++)),this.each(function(){ea.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,ea(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=n),this.each(function(){ea.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){ea.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?ea.event.trigger(a,b,c,!0):void 0}});var Ka="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",La=/ jQuery\d+="(?:null|\d+)"/g,Ma=new RegExp("<(?:"+Ka+")[\\s/>]","i"),Na=/^\s+/,Oa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Pa=/<([\w:]+)/,Qa=/<tbody/i,Ra=/<|&#?\w+;/,Sa=/<(?:script|style|link)/i,Ta=/checked\s*(?:[^=]|=\s*.checked.)/i,Ua=/^$|\/(?:java|ecma)script/i,Va=/^true\/(.*)/,Wa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Xa={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:ca.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},Ya=p(oa),Za=Ya.appendChild(oa.createElement("div"));Xa.optgroup=Xa.option,Xa.tbody=Xa.tfoot=Xa.colgroup=Xa.caption=Xa.thead,Xa.th=Xa.td,ea.extend({clone:function(a,b,c){var d,e,f,g,h,i=ea.contains(a.ownerDocument,a);if(ca.html5Clone||ea.isXMLDoc(a)||!Ma.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Za.innerHTML=a.outerHTML,Za.removeChild(f=Za.firstChild)),!(ca.noCloneEvent&&ca.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||ea.isXMLDoc(a)))for(d=q(f),h=q(a),g=0;null!=(e=h[g]);++g)d[g]&&x(e,d[g]);if(b)if(c)for(h=h||q(a),d=d||q(f),g=0;null!=(e=h[g]);g++)w(e,d[g]);else w(a,f);return d=q(f,"script"),d.length>0&&v(d,!i&&q(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,l=a.length,m=p(b),n=[],o=0;l>o;o++)if(f=a[o],f||0===f)if("object"===ea.type(f))ea.merge(n,f.nodeType?[f]:f);else if(Ra.test(f)){for(h=h||m.appendChild(b.createElement("div")),i=(Pa.exec(f)||["",""])[1].toLowerCase(),k=Xa[i]||Xa._default,h.innerHTML=k[1]+f.replace(Oa,"<$1></$2>")+k[2],e=k[0];e--;)h=h.lastChild;if(!ca.leadingWhitespace&&Na.test(f)&&n.push(b.createTextNode(Na.exec(f)[0])),!ca.tbody)for(f="table"!==i||Qa.test(f)?"<table>"!==k[1]||Qa.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;e--;)ea.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j);for(ea.merge(n,h.childNodes),h.textContent="";h.firstChild;)h.removeChild(h.firstChild);h=m.lastChild}else n.push(b.createTextNode(f));for(h&&m.removeChild(h),ca.appendChecked||ea.grep(q(n,"input"),r),o=0;f=n[o++];)if((!d||-1===ea.inArray(f,d))&&(g=ea.contains(f.ownerDocument,f),h=q(m.appendChild(f),"script"),g&&v(h),c))for(e=0;f=h[e++];)Ua.test(f.type||"")&&c.push(f);return h=null,m},cleanData:function(a,b){for(var c,d,e,f,g=0,h=ea.expando,i=ea.cache,j=ca.deleteExpando,k=ea.event.special;null!=(c=a[g]);g++)if((b||ea.acceptData(c))&&(e=c[h],f=e&&i[e])){if(f.events)for(d in f.events)k[d]?ea.event.remove(c,d):ea.removeEvent(c,d,f.handle);i[e]&&(delete i[e],j?delete c[h]:typeof c.removeAttribute!==xa?c.removeAttribute(h):c[h]=null,W.push(e))}}}),ea.fn.extend({text:function(a){return Da(this,function(a){return void 0===a?ea.text(this):this.empty().append((this[0]&&this[0].ownerDocument||oa).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=s(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=s(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?ea.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||ea.cleanData(q(c)),c.parentNode&&(b&&ea.contains(c.ownerDocument,c)&&v(q(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){for(1===a.nodeType&&ea.cleanData(q(a,!1));a.firstChild;)a.removeChild(a.firstChild);a.options&&ea.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return ea.clone(this,a,b)})},html:function(a){return Da(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(La,""):void 0;if("string"==typeof a&&!Sa.test(a)&&(ca.htmlSerialize||!Ma.test(a))&&(ca.leadingWhitespace||!Na.test(a))&&!Xa[(Pa.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Oa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(ea.cleanData(q(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,ea.cleanData(q(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=Y.apply([],a);var c,d,e,f,g,h,i=0,j=this.length,k=this,l=j-1,m=a[0],n=ea.isFunction(m);if(n||j>1&&"string"==typeof m&&!ca.checkClone&&Ta.test(m))return this.each(function(c){var d=k.eq(c);n&&(a[0]=m.call(this,c,d.html())),d.domManip(a,b)});if(j&&(h=ea.buildFragment(a,this[0].ownerDocument,!1,this),c=h.firstChild,1===h.childNodes.length&&(h=c),c)){for(f=ea.map(q(h,"script"),t),e=f.length;j>i;i++)d=h,i!==l&&(d=ea.clone(d,!0,!0),e&&ea.merge(f,q(d,"script"))),b.call(this[i],d,i);if(e)for(g=f[f.length-1].ownerDocument,ea.map(f,u),i=0;e>i;i++)d=f[i],Ua.test(d.type||"")&&!ea._data(d,"globalEval")&&ea.contains(g,d)&&(d.src?ea._evalUrl&&ea._evalUrl(d.src):ea.globalEval((d.text||d.textContent||d.innerHTML||"").replace(Wa,"")));h=c=null}return this}}),ea.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){ea.fn[a]=function(a){for(var c,d=0,e=[],f=ea(a),g=f.length-1;g>=d;d++)c=d===g?this:this.clone(!0),ea(f[d])[b](c),Z.apply(e,c.get());return this.pushStack(e)}});var $a,_a={};!function(){var a;ca.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=oa.getElementsByTagName("body")[0],c&&c.style?(b=oa.createElement("div"),d=oa.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==xa&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(oa.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var ab,bb,cb=/^margin/,db=new RegExp("^("+Aa+")(?!px)[a-z%]+$","i"),eb=/^(top|right|bottom|left)$/;a.getComputedStyle?(ab=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},bb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||ab(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||ea.contains(a.ownerDocument,a)||(g=ea.style(a,b)),db.test(g)&&cb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)), void 0===g?g:g+""}):oa.documentElement.currentStyle&&(ab=function(a){return a.currentStyle},bb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||ab(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),db.test(g)&&!eb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"}),function(){function b(){var b,c,d,e;c=oa.getElementsByTagName("body")[0],c&&c.style&&(b=oa.createElement("div"),d=oa.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f=g=!1,i=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(b,null)||{}).top,g="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,e=b.appendChild(oa.createElement("div")),e.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",e.style.marginRight=e.style.width="0",b.style.width="1px",i=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",e=b.getElementsByTagName("td"),e[0].style.cssText="margin:0;border:0;padding:0;display:none",h=0===e[0].offsetHeight,h&&(e[0].style.display="",e[1].style.display="none",h=0===e[0].offsetHeight),c.removeChild(d))}var c,d,e,f,g,h,i;c=oa.createElement("div"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",e=c.getElementsByTagName("a")[0],d=e&&e.style,d&&(d.cssText="float:left;opacity:.5",ca.opacity="0.5"===d.opacity,ca.cssFloat=!!d.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",ca.clearCloneStyle="content-box"===c.style.backgroundClip,ca.boxSizing=""===d.boxSizing||""===d.MozBoxSizing||""===d.WebkitBoxSizing,ea.extend(ca,{reliableHiddenOffsets:function(){return null==h&&b(),h},boxSizingReliable:function(){return null==g&&b(),g},pixelPosition:function(){return null==f&&b(),f},reliableMarginRight:function(){return null==i&&b(),i}}))}(),ea.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var fb=/alpha\([^)]*\)/i,gb=/opacity\s*=\s*([^)]*)/,hb=/^(none|table(?!-c[ea]).+)/,ib=new RegExp("^("+Aa+")(.*)$","i"),jb=new RegExp("^([+-])=("+Aa+")","i"),kb={position:"absolute",visibility:"hidden",display:"block"},lb={letterSpacing:"0",fontWeight:"400"},mb=["Webkit","O","Moz","ms"];ea.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":ca.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=ea.camelCase(b),i=a.style;if(b=ea.cssProps[h]||(ea.cssProps[h]=B(i,h)),g=ea.cssHooks[b]||ea.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=jb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(ea.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||ea.cssNumber[h]||(c+="px"),ca.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=ea.camelCase(b);return b=ea.cssProps[h]||(ea.cssProps[h]=B(a.style,h)),g=ea.cssHooks[b]||ea.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=bb(a,b,d)),"normal"===f&&b in lb&&(f=lb[b]),""===c||c?(e=parseFloat(f),c===!0||ea.isNumeric(e)?e||0:f):f}}),ea.each(["height","width"],function(a,b){ea.cssHooks[b]={get:function(a,c,d){return c?hb.test(ea.css(a,"display"))&&0===a.offsetWidth?ea.swap(a,kb,function(){return F(a,b,d)}):F(a,b,d):void 0},set:function(a,c,d){var e=d&&ab(a);return D(a,c,d?E(a,b,d,ca.boxSizing&&"border-box"===ea.css(a,"boxSizing",!1,e),e):0)}}}),ca.opacity||(ea.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=ea.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===ea.trim(f.replace(fb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=fb.test(f)?f.replace(fb,e):f+" "+e)}}),ea.cssHooks.marginRight=A(ca.reliableMarginRight,function(a,b){return b?ea.swap(a,{display:"inline-block"},bb,[a,"marginRight"]):void 0}),ea.each({margin:"",padding:"",border:"Width"},function(a,b){ea.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+Ba[d]+b]=f[d]||f[d-2]||f[0];return e}},cb.test(a)||(ea.cssHooks[a+b].set=D)}),ea.fn.extend({css:function(a,b){return Da(this,function(a,b,c){var d,e,f={},g=0;if(ea.isArray(b)){for(d=ab(a),e=b.length;e>g;g++)f[b[g]]=ea.css(a,b[g],!1,d);return f}return void 0!==c?ea.style(a,b,c):ea.css(a,b)},a,b,arguments.length>1)},show:function(){return C(this,!0)},hide:function(){return C(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){Ca(this)?ea(this).show():ea(this).hide()})}}),ea.Tween=G,G.prototype={constructor:G,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(ea.cssNumber[c]?"":"px")},cur:function(){var a=G.propHooks[this.prop];return a&&a.get?a.get(this):G.propHooks._default.get(this)},run:function(a){var b,c=G.propHooks[this.prop];return this.options.duration?this.pos=b=ea.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):G.propHooks._default.set(this),this}},G.prototype.init.prototype=G.prototype,G.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=ea.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){ea.fx.step[a.prop]?ea.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[ea.cssProps[a.prop]]||ea.cssHooks[a.prop])?ea.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},G.propHooks.scrollTop=G.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},ea.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},ea.fx=G.prototype.init,ea.fx.step={};var nb,ob,pb=/^(?:toggle|show|hide)$/,qb=new RegExp("^(?:([+-])=|)("+Aa+")([a-z%]*)$","i"),rb=/queueHooks$/,sb=[K],tb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=qb.exec(b),f=e&&e[3]||(ea.cssNumber[a]?"":"px"),g=(ea.cssNumber[a]||"px"!==f&&+d)&&qb.exec(ea.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,ea.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};ea.Animation=ea.extend(M,{tweener:function(a,b){ea.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],tb[c]=tb[c]||[],tb[c].unshift(b)},prefilter:function(a,b){b?sb.unshift(a):sb.push(a)}}),ea.speed=function(a,b,c){var d=a&&"object"==typeof a?ea.extend({},a):{complete:c||!c&&b||ea.isFunction(a)&&a,duration:a,easing:c&&b||b&&!ea.isFunction(b)&&b};return d.duration=ea.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in ea.fx.speeds?ea.fx.speeds[d.duration]:ea.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){ea.isFunction(d.old)&&d.old.call(this),d.queue&&ea.dequeue(this,d.queue)},d},ea.fn.extend({fadeTo:function(a,b,c,d){return this.filter(Ca).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=ea.isEmptyObject(a),f=ea.speed(b,c,d),g=function(){var b=M(this,ea.extend({},a),f);(e||ea._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=ea.timers,g=ea._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&rb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&ea.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=ea._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=ea.timers,g=d?d.length:0;for(c.finish=!0,ea.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),ea.each(["toggle","show","hide"],function(a,b){var c=ea.fn[b];ea.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(I(b,!0),a,d,e)}}),ea.each({slideDown:I("show"),slideUp:I("hide"),slideToggle:I("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){ea.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),ea.timers=[],ea.fx.tick=function(){var a,b=ea.timers,c=0;for(nb=ea.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||ea.fx.stop(),nb=void 0},ea.fx.timer=function(a){ea.timers.push(a),a()?ea.fx.start():ea.timers.pop()},ea.fx.interval=13,ea.fx.start=function(){ob||(ob=setInterval(ea.fx.tick,ea.fx.interval))},ea.fx.stop=function(){clearInterval(ob),ob=null},ea.fx.speeds={slow:600,fast:200,_default:400},ea.fn.delay=function(a,b){return a=ea.fx?ea.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=oa.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=oa.createElement("select"),e=c.appendChild(oa.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",ca.getSetAttribute="t"!==b.className,ca.style=/top/.test(d.getAttribute("style")),ca.hrefNormalized="/a"===d.getAttribute("href"),ca.checkOn=!!a.value,ca.optSelected=e.selected,ca.enctype=!!oa.createElement("form").enctype,c.disabled=!0,ca.optDisabled=!e.disabled,a=oa.createElement("input"),a.setAttribute("value",""),ca.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),ca.radioValue="t"===a.value}();var ub=/\r/g;ea.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=ea.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,ea(this).val()):a,null==e?e="":"number"==typeof e?e+="":ea.isArray(e)&&(e=ea.map(e,function(a){return null==a?"":a+""})),b=ea.valHooks[this.type]||ea.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=ea.valHooks[e.type]||ea.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ub,""):null==c?"":c)}}}),ea.extend({valHooks:{option:{get:function(a){var b=ea.find.attr(a,"value");return null!=b?b:ea.trim(ea.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(ca.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!ea.nodeName(c.parentNode,"optgroup"))){if(b=ea(c).val(),f)return b;g.push(b)}return g},set:function(a,b){for(var c,d,e=a.options,f=ea.makeArray(b),g=e.length;g--;)if(d=e[g],ea.inArray(ea.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),ea.each(["radio","checkbox"],function(){ea.valHooks[this]={set:function(a,b){return ea.isArray(b)?a.checked=ea.inArray(ea(a).val(),b)>=0:void 0}},ca.checkOn||(ea.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var vb,wb,xb=ea.expr.attrHandle,yb=/^(?:checked|selected)$/i,zb=ca.getSetAttribute,Ab=ca.input;ea.fn.extend({attr:function(a,b){return Da(this,ea.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){ea.removeAttr(this,a)})}}),ea.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===xa?ea.prop(a,b,c):(1===f&&ea.isXMLDoc(a)||(b=b.toLowerCase(),d=ea.attrHooks[b]||(ea.expr.match.bool.test(b)?wb:vb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=ea.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void ea.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(ta);if(f&&1===a.nodeType)for(;c=f[e++];)d=ea.propFix[c]||c,ea.expr.match.bool.test(c)?Ab&&zb||!yb.test(c)?a[d]=!1:a[ea.camelCase("default-"+c)]=a[d]=!1:ea.attr(a,c,""),a.removeAttribute(zb?c:d)},attrHooks:{type:{set:function(a,b){if(!ca.radioValue&&"radio"===b&&ea.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),wb={set:function(a,b,c){return b===!1?ea.removeAttr(a,c):Ab&&zb||!yb.test(c)?a.setAttribute(!zb&&ea.propFix[c]||c,c):a[ea.camelCase("default-"+c)]=a[c]=!0,c}},ea.each(ea.expr.match.bool.source.match(/\w+/g),function(a,b){var c=xb[b]||ea.find.attr;xb[b]=Ab&&zb||!yb.test(b)?function(a,b,d){var e,f;return d||(f=xb[b],xb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,xb[b]=f),e}:function(a,b,c){return c?void 0:a[ea.camelCase("default-"+b)]?b.toLowerCase():null}}),Ab&&zb||(ea.attrHooks.value={set:function(a,b,c){return ea.nodeName(a,"input")?void(a.defaultValue=b):vb&&vb.set(a,b,c)}}),zb||(vb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},xb.id=xb.name=xb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},ea.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:vb.set},ea.attrHooks.contenteditable={set:function(a,b,c){vb.set(a,""===b?!1:b,c)}},ea.each(["width","height"],function(a,b){ea.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),ca.style||(ea.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var Bb=/^(?:input|select|textarea|button|object)$/i,Cb=/^(?:a|area)$/i;ea.fn.extend({prop:function(a,b){return Da(this,ea.prop,a,b,arguments.length>1)},removeProp:function(a){return a=ea.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),ea.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!ea.isXMLDoc(a),f&&(b=ea.propFix[b]||b,e=ea.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=ea.find.attr(a,"tabindex");return b?parseInt(b,10):Bb.test(a.nodeName)||Cb.test(a.nodeName)&&a.href?0:-1}}}}),ca.hrefNormalized||ea.each(["href","src"],function(a,b){ea.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),ca.optSelected||(ea.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),ea.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ea.propFix[this.toLowerCase()]=this}),ca.enctype||(ea.propFix.enctype="encoding");var Db=/[\t\r\n\f]/g;ea.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(ea.isFunction(a))return this.each(function(b){ea(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(ta)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(Db," "):" ")){for(f=0;e=b[f++];)d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=ea.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(ea.isFunction(a))return this.each(function(b){ea(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(ta)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(Db," "):"")){for(f=0;e=b[f++];)for(;d.indexOf(" "+e+" ")>=0;)d=d.replace(" "+e+" "," ");g=a?ea.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):ea.isFunction(a)?this.each(function(c){ea(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if("string"===c)for(var b,d=0,e=ea(this),f=a.match(ta)||[];b=f[d++];)e.hasClass(b)?e.removeClass(b):e.addClass(b);else(c===xa||"boolean"===c)&&(this.className&&ea._data(this,"__className__",this.className),this.className=this.className||a===!1?"":ea._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(Db," ").indexOf(b)>=0)return!0;return!1}}),ea.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){ea.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),ea.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var Eb=ea.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;ea.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=ea.trim(b+"");return e&&!ea.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():ea.error("Invalid JSON: "+b)},ea.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||ea.error("Invalid XML: "+b),c};var Hb,Ib,Jb=/#.*$/,Kb=/([?&])_=[^&]*/,Lb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Mb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nb=/^(?:GET|HEAD)$/,Ob=/^\/\//,Pb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Qb={},Rb={},Sb="*/".concat("*");try{Ib=location.href}catch(Tb){Ib=oa.createElement("a"),Ib.href="",Ib=Ib.href}Hb=Pb.exec(Ib.toLowerCase())||[],ea.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ib,type:"GET",isLocal:Mb.test(Hb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Sb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":ea.parseJSON,"text xml":ea.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?P(P(a,ea.ajaxSettings),b):P(ea.ajaxSettings,a)},ajaxPrefilter:N(Qb),ajaxTransport:N(Rb),ajax:function(a,b){function c(a,b,c,d){var e,k,r,s,u,w=b;2!==t&&(t=2,h&&clearTimeout(h),j=void 0,g=d||"",v.readyState=a>0?4:0,e=a>=200&&300>a||304===a,c&&(s=Q(l,v,c)),s=R(l,s,v,e),e?(l.ifModified&&(u=v.getResponseHeader("Last-Modified"),u&&(ea.lastModified[f]=u),u=v.getResponseHeader("etag"),u&&(ea.etag[f]=u)),204===a||"HEAD"===l.type?w="nocontent":304===a?w="notmodified":(w=s.state,k=s.data,r=s.error,e=!r)):(r=w,(a||!w)&&(w="error",0>a&&(a=0))),v.status=a,v.statusText=(b||w)+"",e?o.resolveWith(m,[k,w,v]):o.rejectWith(m,[v,w,r]),v.statusCode(q),q=void 0,i&&n.trigger(e?"ajaxSuccess":"ajaxError",[v,l,e?k:r]),p.fireWith(m,[v,w]),i&&(n.trigger("ajaxComplete",[v,l]),--ea.active||ea.event.trigger("ajaxStop")))}"object"==typeof a&&(b=a,a=void 0),b=b||{};var d,e,f,g,h,i,j,k,l=ea.ajaxSetup({},b),m=l.context||l,n=l.context&&(m.nodeType||m.jquery)?ea(m):ea.event,o=ea.Deferred(),p=ea.Callbacks("once memory"),q=l.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!k)for(k={};b=Lb.exec(g);)k[b[1].toLowerCase()]=b[2];b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return j&&j.abort(b),c(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,l.url=((a||l.url||Ib)+"").replace(Jb,"").replace(Ob,Hb[1]+"//"),l.type=b.method||b.type||l.method||l.type,l.dataTypes=ea.trim(l.dataType||"*").toLowerCase().match(ta)||[""],null==l.crossDomain&&(d=Pb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Hb[1]&&d[2]===Hb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Hb[3]||("http:"===Hb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=ea.param(l.data,l.traditional)),O(Qb,l,b,v),2===t)return v;i=l.global,i&&0===ea.active++&&ea.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Nb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Kb.test(f)?f.replace(Kb,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(ea.lastModified[f]&&v.setRequestHeader("If-Modified-Since",ea.lastModified[f]),ea.etag[f]&&v.setRequestHeader("If-None-Match",ea.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",l.contentType),v.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Sb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)v.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,v,l)===!1||2===t))return v.abort();u="abort";for(e in{success:1,error:1,complete:1})v[e](l[e]);if(j=O(Rb,l,b,v)){v.readyState=1,i&&n.trigger("ajaxSend",[v,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){v.abort("timeout")},l.timeout));try{t=1,j.send(r,c)}catch(w){if(!(2>t))throw w;c(-1,w)}}else c(-1,"No Transport");return v},getJSON:function(a,b,c){return ea.get(a,b,c,"json")},getScript:function(a,b){return ea.get(a,void 0,b,"script")}}),ea.each(["get","post"],function(a,b){ea[b]=function(a,c,d,e){return ea.isFunction(c)&&(e=e||d,d=c,c=void 0),ea.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),ea.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){ea.fn[b]=function(a){return this.on(b,a)}}),ea._evalUrl=function(a){return ea.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},ea.fn.extend({wrapAll:function(a){if(ea.isFunction(a))return this.each(function(b){ea(this).wrapAll(a.call(this,b))});if(this[0]){var b=ea(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){for(var a=this;a.firstChild&&1===a.firstChild.nodeType;)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return ea.isFunction(a)?this.each(function(b){ea(this).wrapInner(a.call(this,b))}):this.each(function(){var b=ea(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=ea.isFunction(a);return this.each(function(c){ea(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){ea.nodeName(this,"body")||ea(this).replaceWith(this.childNodes)}).end()}}),ea.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!ca.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||ea.css(a,"display"))},ea.expr.filters.visible=function(a){return!ea.expr.filters.hidden(a)};var Ub=/%20/g,Vb=/\[\]$/,Wb=/\r?\n/g,Xb=/^(?:submit|button|image|reset|file)$/i,Yb=/^(?:input|select|textarea|keygen)/i;ea.param=function(a,b){var c,d=[],e=function(a,b){b=ea.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=ea.ajaxSettings&&ea.ajaxSettings.traditional),ea.isArray(a)||a.jquery&&!ea.isPlainObject(a))ea.each(a,function(){e(this.name,this.value)});else for(c in a)S(c,a[c],b,e);return d.join("&").replace(Ub,"+")},ea.fn.extend({serialize:function(){return ea.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=ea.prop(this,"elements");return a?ea.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!ea(this).is(":disabled")&&Yb.test(this.nodeName)&&!Xb.test(a)&&(this.checked||!Ea.test(a))}).map(function(a,b){var c=ea(this).val();return null==c?null:ea.isArray(c)?ea.map(c,function(a){return{name:b.name,value:a.replace(Wb,"\r\n")}}):{name:b.name,value:c.replace(Wb,"\r\n")}}).get()}}),ea.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&T()||U()}:T;var Zb=0,$b={},_b=ea.ajaxSettings.xhr();a.ActiveXObject&&ea(a).on("unload",function(){for(var a in $b)$b[a](void 0,!0)}),ca.cors=!!_b&&"withCredentials"in _b,_b=ca.ajax=!!_b,_b&&ea.ajaxTransport(function(a){if(!a.crossDomain||ca.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Zb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete $b[g],b=void 0,f.onreadystatechange=ea.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=$b[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}}),ea.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return ea.globalEval(a),a}}}),ea.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),ea.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=oa.head||ea("head")[0]||oa.documentElement;return{send:function(d,e){b=oa.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ac=[],bc=/(=)\?(?=&|$)|\?\?/;ea.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ac.pop()||ea.expando+"_"+Eb++;return this[a]=!0,a}}),ea.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=ea.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||ea.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ac.push(e)),g&&ea.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),ea.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||oa;var d=la.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=ea.buildFragment([a],b,e),e&&e.length&&ea(e).remove(),ea.merge([],d.childNodes))};var cc=ea.fn.load;ea.fn.load=function(a,b,c){if("string"!=typeof a&&cc)return cc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=ea.trim(a.slice(h,a.length)),a=a.slice(0,h)),ea.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&ea.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?ea("<div>").append(ea.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},ea.expr.filters.animated=function(a){return ea.grep(ea.timers,function(b){return a===b.elem}).length};var dc=a.document.documentElement;ea.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=ea.css(a,"position"),l=ea(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=ea.css(a,"top"),i=ea.css(a,"left"),j=("absolute"===k||"fixed"===k)&&ea.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),ea.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},ea.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){ea.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,ea.contains(b,e)?(typeof e.getBoundingClientRect!==xa&&(d=e.getBoundingClientRect()),c=V(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===ea.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),ea.nodeName(a[0],"html")||(c=a.offset()),c.top+=ea.css(a[0],"borderTopWidth",!0),c.left+=ea.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-ea.css(d,"marginTop",!0),left:b.left-c.left-ea.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||dc;a&&!ea.nodeName(a,"html")&&"static"===ea.css(a,"position");)a=a.offsetParent;return a||dc})}}),ea.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);ea.fn[a]=function(d){return Da(this,function(a,d,e){var f=V(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?ea(f).scrollLeft():e,c?e:ea(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),ea.each(["top","left"],function(a,b){ea.cssHooks[b]=A(ca.pixelPosition,function(a,c){return c?(c=bb(a,b),db.test(c)?ea(a).position()[b]+"px":c):void 0})}),ea.each({Height:"height",Width:"width"},function(a,b){ea.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){ea.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Da(this,function(b,c,d){var e;return ea.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement, Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?ea.css(b,c,g):ea.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),ea.fn.size=function(){return this.length},ea.fn.andSelf=ea.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return ea});var ec=a.jQuery,fc=a.$;return ea.noConflict=function(b){return a.$===ea&&(a.$=fc),b&&a.jQuery===ea&&(a.jQuery=ec),ea},typeof b===xa&&(a.jQuery=a.$=ea),ea}),function(){function a(a,b){if(a!==b){var c=a===a,d=b===b;if(a>b||!c||"undefined"==typeof a&&d)return 1;if(b>a||!d||"undefined"==typeof b&&c)return-1}return 0}function b(a,b,c){if(b!==b)return m(a,c);for(var d=(c||0)-1,e=a.length;++d<e;)if(a[d]===b)return d;return-1}function c(a,b){var c=a.length;for(a.sort(b);c--;)a[c]=a[c].value;return a}function d(a){return"string"==typeof a?a:null==a?"":a+""}function e(a){return a.charCodeAt(0)}function f(a,b){for(var c=-1,d=a.length;++c<d&&b.indexOf(a.charAt(c))>-1;);return c}function g(a,b){for(var c=a.length;c--&&b.indexOf(a.charAt(c))>-1;);return c}function h(b,c){return a(b.criteria,c.criteria)||b.index-c.index}function i(b,c){for(var d=-1,e=b.criteria,f=c.criteria,g=e.length;++d<g;){var h=a(e[d],f[d]);if(h)return h}return b.index-c.index}function j(a){return Ma[a]}function k(a){return Na[a]}function l(a){return"\\"+Qa[a]}function m(a,b,c){for(var d=a.length,e=c?b||d:(b||0)-1;c?e--:++e<d;){var f=a[e];if(f!==f)return e}return-1}function n(a){return a&&"object"==typeof a||!1}function o(a){return 160>=a&&a>=9&&13>=a||32==a||160==a||5760==a||6158==a||a>=8192&&(8202>=a||8232==a||8233==a||8239==a||8287==a||12288==a||65279==a)}function p(a,b){for(var c=-1,d=a.length,e=-1,f=[];++c<d;)a[c]===b&&(a[c]=O,f[++e]=c);return f}function q(a,b){for(var c,d=-1,e=a.length,f=-1,g=[];++d<e;){var h=a[d],i=b?b(h,d,a):h;d&&c===i||(c=i,g[++f]=h)}return g}function r(a){for(var b=-1,c=a.length;++b<c&&o(a.charCodeAt(b)););return b}function s(a){for(var b=a.length;b--&&o(a.charCodeAt(b)););return b}function t(a){return Oa[a]}function u(o){function V(a){if(n(a)&&!Pg(a)){if(a instanceof Z)return a;if(Tf.call(a,"__wrapped__"))return new Z(a.__wrapped__,a.__chain__,Za(a.__actions__))}return new Z(a)}function Z(a,b,c){this.__actions__=c||[],this.__chain__=!!b,this.__wrapped__=a}function _(a){this.actions=null,this.dir=1,this.dropCount=0,this.filtered=!1,this.iteratees=null,this.takeCount=vg,this.views=null,this.wrapped=a}function Ma(){var a=this.actions,b=this.iteratees,c=this.views,d=new _(this.wrapped);return d.actions=a?Za(a):null,d.dir=this.dir,d.dropCount=this.dropCount,d.filtered=this.filtered,d.iteratees=b?Za(b):null,d.takeCount=this.takeCount,d.views=c?Za(c):null,d}function Na(){var a=this.filtered,b=a?new _(this):this.clone();return b.dir=-1*this.dir,b.filtered=a,b}function Oa(){var a=this.wrapped.value();if(!Pg(a))return Ub(a,this.actions);var b=this.dir,c=0>b,d=a.length,e=pc(0,d,this.views),f=e.start,g=e.end,h=this.dropCount,i=pg(g-f,this.takeCount-h),j=c?g:f-1,k=this.iteratees,l=k?k.length:0,m=0,n=[];a:for(;d--&&i>m;){j+=b;for(var o=-1,p=a[j];++o<l;){var q=k[o],r=q.iteratee,s=r(p,j,a),t=q.type;if(t==L)p=s;else if(!s){if(t==K)continue a;break a}}h?h--:n[m++]=p}return c?n.reverse():n}function Pa(){this.__data__={}}function Qa(a){return this.has(a)&&delete this.__data__[a]}function Sa(a){return"__proto__"==a?v:this.__data__[a]}function Ta(a){return"__proto__"!=a&&Tf.call(this.__data__,a)}function Ua(a,b){return"__proto__"!=a&&(this.__data__[a]=b),this}function Va(a){var b=a?a.length:0;for(this.data={hash:lg(null),set:new eg};b--;)this.push(a[b])}function Xa(a,b){var c=a.data,d="string"==typeof b||te(b)?c.set.has(b):c.hash[b];return d?0:-1}function Ya(a){var b=this.data;"string"==typeof a||te(a)?b.set.add(a):b.hash[a]=!0}function Za(a,b){var c=-1,d=a.length;for(b||(b=Ef(d));++c<d;)b[c]=a[c];return b}function $a(a,b){for(var c=-1,d=a.length;++c<d&&b(a[c],c,a)!==!1;);return a}function _a(a,b){for(var c=a.length;c--&&b(a[c],c,a)!==!1;);return a}function ab(a,b){for(var c=-1,d=a.length;++c<d;)if(!b(a[c],c,a))return!1;return!0}function bb(a,b){for(var c=-1,d=a.length,e=-1,f=[];++c<d;){var g=a[c];b(g,c,a)&&(f[++e]=g)}return f}function cb(a,b){for(var c=-1,d=a.length,e=Ef(d);++c<d;)e[c]=b(a[c],c,a);return e}function db(a){for(var b=-1,c=a.length,d=ug;++b<c;){var e=a[b];e>d&&(d=e)}return d}function eb(a){for(var b=-1,c=a.length,d=vg;++b<c;){var e=a[b];d>e&&(d=e)}return d}function fb(a,b,c,d){var e=-1,f=a.length;for(d&&f&&(c=a[++e]);++e<f;)c=b(c,a[e],e,a);return c}function gb(a,b,c,d){var e=a.length;for(d&&e&&(c=a[--e]);e--;)c=b(c,a[e],e,a);return c}function hb(a,b){for(var c=-1,d=a.length;++c<d;)if(b(a[c],c,a))return!0;return!1}function ib(a,b){return"undefined"==typeof a?b:a}function jb(a,b,c,d){return"undefined"!=typeof a&&Tf.call(d,c)?a:b}function kb(a,b,c){var d=Tg(b);if(!c)return mb(b,a,d);for(var e=-1,f=d.length;++e<f;){var g=d[e],h=a[g],i=c(h,b[g],g,a,b);(i===i?i===h:h!==h)&&("undefined"!=typeof h||g in a)||(a[g]=i)}return a}function lb(a,b){for(var c=-1,d=a.length,e=wc(d),f=b.length,g=Ef(f);++c<f;){var h=b[c];e?(h=parseFloat(h),g[c]=uc(h,d)?a[h]:v):g[c]=a[h]}return g}function mb(a,b,c){c||(c=b,b={});for(var d=-1,e=c.length;++d<e;){var f=c[d];b[f]=a[f]}return b}function nb(a,b){for(var c=-1,d=b.length;++c<d;){var e=b[c];a[e]=ic(a[e],x,a)}return a}function ob(a,b,c){var e=typeof a;return"function"==e?"undefined"!=typeof b&&tc(a)?Xb(a,b,c):a:null==a?uf:"object"==e?Jb(a,!c):Mb(c?d(a):a)}function pb(a,b,c,d,e,f,g){var h;if(c&&(h=e?c(a,d,e):c(a)),"undefined"!=typeof h)return h;if(!te(a))return a;var i=Pg(a);if(i){if(h=qc(a),!b)return Za(a,h)}else{var j=Vf.call(a),k=j==U;if(j!=X&&j!=P&&(!k||e))return Ka[j]?sc(a,j,b):e?a:{};if(h=rc(k?{}:a),!b)return mb(a,h,Tg(a))}f||(f=[]),g||(g=[]);for(var l=f.length;l--;)if(f[l]==a)return g[l];return f.push(a),g.push(h),(i?$a:Bb)(a,function(d,e){h[e]=pb(d,b,c,e,a,f,g)}),h}function qb(a,b,c,d){if(!se(a))throw new Nf(N);return fg(function(){a.apply(v,Qb(c,d))},b)}function rb(a,c){var d=a?a.length:0,e=[];if(!d)return e;var f=-1,g=oc(),h=g==b,i=h&&c.length>=200&&Fg(c),j=c.length;i&&(g=Xa,h=!1,c=i);a:for(;++f<d;){var k=a[f];if(h&&k===k){for(var l=j;l--;)if(c[l]===k)continue a;e.push(k)}else g(c,k)<0&&e.push(k)}return e}function sb(a,b){var c=a?a.length:0;if(!wc(c))return Bb(a,b);for(var d=-1,e=Fc(a);++d<c&&b(e[d],d,e)!==!1;);return a}function tb(a,b){var c=a?a.length:0;if(!wc(c))return Cb(a,b);for(var d=Fc(a);c--&&b(d[c],c,d)!==!1;);return a}function ub(a,b){var c=!0;return sb(a,function(a,d,e){return c=!!b(a,d,e)}),c}function vb(a,b){var c=[];return sb(a,function(a,d,e){b(a,d,e)&&c.push(a)}),c}function wb(a,b,c,d){var e;return c(a,function(a,c,f){return b(a,c,f)?(e=d?c:a,!1):void 0}),e}function xb(a,b,c,d){for(var e=(d||0)-1,f=a.length,g=-1,h=[];++e<f;){var i=a[e];if(n(i)&&wc(i.length)&&(Pg(i)||le(i))){b&&(i=xb(i,b,c));var j=-1,k=i.length;for(h.length+=k;++j<k;)h[++g]=i[j]}else c||(h[++g]=i)}return h}function yb(a,b,c){for(var d=-1,e=Fc(a),f=c(a),g=f.length;++d<g;){var h=f[d];if(b(e[h],h,e)===!1)break}return a}function zb(a,b,c){for(var d=Fc(a),e=c(a),f=e.length;f--;){var g=e[f];if(b(d[g],g,d)===!1)break}return a}function Ab(a,b){return yb(a,b,Qe)}function Bb(a,b){return yb(a,b,Tg)}function Cb(a,b){return zb(a,b,Tg)}function Db(a,b){for(var c=-1,d=b.length,e=-1,f=[];++c<d;){var g=b[c];se(a[g])&&(f[++e]=g)}return f}function Eb(a,b,c){var d=-1,e="function"==typeof b,f=a?a.length:0,g=wc(f)?Ef(f):[];return sb(a,function(a){var f=e?b:null!=a&&a[b];g[++d]=f?f.apply(a,c):v}),g}function Fb(a,b,c,d,e,f){if(a===b)return 0!==a||1/a==1/b;var g=typeof a,h=typeof b;return"function"!=g&&"object"!=g&&"function"!=h&&"object"!=h||null==a||null==b?a!==a&&b!==b:Gb(a,b,Fb,c,d,e,f)}function Gb(a,b,c,d,e,f,g){var h=Pg(a),i=Pg(b),j=Q,k=Q;h||(j=Vf.call(a),j==P?j=X:j!=X&&(h=Be(a))),i||(k=Vf.call(b),k==P?k=X:k!=X&&(i=Be(b)));var l=j==X,m=k==X,n=j==k;if(n&&!h&&!l)return kc(a,b,j);var o=l&&Tf.call(a,"__wrapped__"),p=m&&Tf.call(b,"__wrapped__");if(o||p)return c(o?a.value():a,p?b.value():b,d,e,f,g);if(!n)return!1;f||(f=[]),g||(g=[]);for(var q=f.length;q--;)if(f[q]==a)return g[q]==b;f.push(a),g.push(b);var r=(h?jc:lc)(a,b,c,d,e,f,g);return f.pop(),g.pop(),r}function Hb(a,b,c,d,e){var f=b.length;if(null==a)return!f;for(var g=-1,h=!e;++g<f;)if(h&&d[g]?c[g]!==a[b[g]]:!Tf.call(a,b[g]))return!1;for(g=-1;++g<f;){var i=b[g];if(h&&d[g])var j=Tf.call(a,i);else{var k=a[i],l=c[g];j=e?e(k,l,i):v,"undefined"==typeof j&&(j=Fb(l,k,e,!0))}if(!j)return!1}return!0}function Ib(a,b){var c=[];return sb(a,function(a,d,e){c.push(b(a,d,e))}),c}function Jb(a,b){var c=Tg(a),d=c.length;if(1==d){var e=c[0],f=a[e];if(xc(f))return function(a){return null!=a&&f===a[e]&&Tf.call(a,e)}}b&&(a=pb(a,!0));for(var g=Ef(d),h=Ef(d);d--;)f=a[c[d]],g[d]=f,h[d]=xc(f);return function(a){return Hb(a,c,g,h)}}function Kb(a,b,c,d,e){var f=wc(b.length)&&(Pg(b)||Be(b));return(f?$a:Bb)(b,function(b,g,h){if(n(b))return d||(d=[]),e||(e=[]),Lb(a,h,g,Kb,c,d,e);var i=a[g],j=c?c(i,b,g,a,h):v,k="undefined"==typeof j;k&&(j=b),!f&&"undefined"==typeof j||!k&&(j===j?j===i:i!==i)||(a[g]=j)}),a}function Lb(a,b,c,d,e,f,g){for(var h=f.length,i=b[c];h--;)if(f[h]==i)return void(a[c]=g[h]);var j=a[c],k=e?e(j,i,c,a,b):v,l="undefined"==typeof k;l&&(k=i,wc(i.length)&&(Pg(i)||Be(i))?k=Pg(j)?j:j?Za(j):[]:(Rg(i)||le(i))&&(k=le(j)?Ee(j):Rg(j)?j:{})),f.push(i),g.push(k),l?a[c]=d(k,i,e,f,g):(k===k?k!==j:j===j)&&(a[c]=k)}function Mb(a){return function(b){return null==b?v:b[a]}}function Nb(b,c){var d=c.length,e=lb(b,c);for(c.sort(a);d--;){var f=parseFloat(c[d]);if(f!=g&&uc(f)){var g=f;gg.call(b,f,1)}}return e}function Ob(a,b){return a+ag(tg()*(b-a+1))}function Pb(a,b,c,d,e){return e(a,function(a,e,f){c=d?(d=!1,a):b(c,a,e,f)}),c}function Qb(a,b,c){var d=-1,e=a.length;b=null==b?0:+b||0,0>b&&(b=-b>e?0:e+b),c="undefined"==typeof c||c>e?e:+c||0,0>c&&(c+=e),e=b>c?0:c-b;for(var f=Ef(e);++d<e;)f[d]=a[d+b];return f}function Rb(a,b){var c;return sb(a,function(a,d,e){return c=b(a,d,e),!c}),!!c}function Sb(a,c){var d=-1,e=oc(),f=a.length,g=e==b,h=g&&f>=200,i=h&&Fg(),j=[];i?(e=Xa,g=!1):(h=!1,i=c?[]:j);a:for(;++d<f;){var k=a[d],l=c?c(k,d,a):k;if(g&&k===k){for(var m=i.length;m--;)if(i[m]===l)continue a;c&&i.push(l),j.push(k)}else e(i,l)<0&&((c||h)&&i.push(l),j.push(k))}return j}function Tb(a,b){for(var c=-1,d=b.length,e=Ef(d);++c<d;)e[c]=a[b[c]];return e}function Ub(a,b){var c=a;c instanceof _&&(c=c.value());for(var d=-1,e=b.length;++d<e;){var f=[c],g=b[d];cg.apply(f,g.args),c=g.func.apply(g.thisArg,f)}return c}function Vb(a,b,c){var d=0,e=a?a.length:d;if("number"==typeof b&&b===b&&yg>=e){for(;e>d;){var f=d+e>>>1,g=a[f];(c?b>=g:b>g)?d=f+1:e=f}return e}return Wb(a,b,uf,c)}function Wb(a,b,c,d){b=c(b);for(var e=0,f=a?a.length:0,g=b!==b,h="undefined"==typeof b;f>e;){var i=ag((e+f)/2),j=c(a[i]),k=j===j;if(g)var l=k||d;else l=h?k&&(d||"undefined"!=typeof j):d?b>=j:b>j;l?e=i+1:f=i}return pg(f,xg)}function Xb(a,b,c){if("function"!=typeof a)return uf;if("undefined"==typeof b)return a;switch(c){case 1:return function(c){return a.call(b,c)};case 3:return function(c,d,e){return a.call(b,c,d,e)};case 4:return function(c,d,e,f){return a.call(b,c,d,e,f)};case 5:return function(c,d,e,f,g){return a.call(b,c,d,e,f,g)}}return function(){return a.apply(b,arguments)}}function Yb(a){return Zf.call(a,0)}function Zb(a,b,c){for(var d=c.length,e=-1,f=og(a.length-d,0),g=-1,h=b.length,i=Ef(f+h);++g<h;)i[g]=b[g];for(;++e<d;)i[c[e]]=a[e];for(;f--;)i[g++]=a[e++];return i}function $b(a,b,c){for(var d=-1,e=c.length,f=-1,g=og(a.length-e,0),h=-1,i=b.length,j=Ef(g+i);++f<g;)j[f]=a[f];for(var k=f;++h<i;)j[k+h]=b[h];for(;++d<e;)j[k+c[d]]=a[f++];return j}function _b(a,b){return function(c,d,e){var f=b?b():{};if(d=nc(d,e,3),Pg(c))for(var g=-1,h=c.length;++g<h;){var i=c[g];a(f,i,d(i,g,c),c)}else sb(c,function(b,c,e){a(f,b,d(b,c,e),e)});return f}}function ac(a){return function(){var b=arguments.length,c=arguments[0];if(2>b||null==c)return c;if(b>3&&vc(arguments[1],arguments[2],arguments[3])&&(b=2),b>3&&"function"==typeof arguments[b-2])var d=Xb(arguments[--b-1],arguments[b--],5);else b>2&&"function"==typeof arguments[b-1]&&(d=arguments[--b]);for(var e=0;++e<b;){var f=arguments[e];f&&a(c,f,d)}return c}}function bc(a,b){function c(){return(this instanceof c?d:a).apply(b,arguments)}var d=dc(a);return c}function cc(a){return function(b){for(var c=-1,d=qf(_e(b)),e=d.length,f="";++c<e;)f=a(f,d[c],c);return f}}function dc(a){return function(){var b=Dg(a.prototype),c=a.apply(b,arguments);return te(c)?c:b}}function ec(a,b){return function(c,d,f){f&&vc(c,d,f)&&(d=null);var g=nc(),h=null==d;if(g===ob&&h||(h=!1,d=g(d,f,3)),h){var i=Pg(c);if(i||!Ae(c))return a(i?c:Ec(c));d=e}return mc(c,d,b)}}function fc(a,b,c,d,e,f,g,h,i,j){function k(){for(var u=arguments.length,v=u,w=Ef(u);v--;)w[v]=arguments[v];if(d&&(w=Zb(w,d,e)),f&&(w=$b(w,f,g)),o||r){var z=k.placeholder,A=p(w,z);if(u-=A.length,j>u){var B=h?Za(h):null,E=og(j-u,0),F=o?A:null,G=o?null:A,H=o?w:null,I=o?null:w;b|=o?C:D,b&=~(o?D:C),q||(b&=~(x|y));var J=fc(a,b,c,H,F,I,G,B,i,E);return J.placeholder=z,J}}var K=m?c:this;return n&&(a=K[t]),h&&(w=Bc(w,h)),l&&i<w.length&&(w.length=i),(this instanceof k?s||dc(a):a).apply(K,w)}var l=b&F,m=b&x,n=b&y,o=b&A,q=b&z,r=b&B,s=!n&&dc(a),t=a;return k}function gc(a,b,c){var e=a.length;if(b=+b,e>=b||!mg(b))return"";var f=b-e;return c=null==c?" ":d(c),hf(c,$f(f/c.length)).slice(0,f)}function hc(a,b,c,d){function e(){for(var b=-1,h=arguments.length,i=-1,j=d.length,k=Ef(h+j);++i<j;)k[i]=d[i];for(;h--;)k[i++]=arguments[++b];return(this instanceof e?g:a).apply(f?c:this,k)}var f=b&x,g=dc(a);return e}function ic(a,b,c,d,e,f,g,h){var i=b&y;if(!i&&!se(a))throw new Nf(N);var j=d?d.length:0;if(j||(b&=~(C|D),d=e=null),j-=e?e.length:0,b&D){var k=d,l=e;d=e=null}var m=!i&&Gg(a),n=[a,b,c,d,e,k,l,f,g,h];if(m&&m!==!0&&(yc(n,m),b=n[1],h=n[9]),n[9]=null==h?i?0:a.length:og(h-j,0)||0,b==x)var o=bc(n[0],n[2]);else o=b!=C&&b!=(x|C)||n[4].length?fc.apply(null,n):hc.apply(null,n);var p=m?Eg:Hg;return p(o,n)}function jc(a,b,c,d,e,f,g){var h=-1,i=a.length,j=b.length,k=!0;if(i!=j&&!(e&&j>i))return!1;for(;k&&++h<i;){var l=a[h],m=b[h];if(k=v,d&&(k=e?d(m,l,h):d(l,m,h)),"undefined"==typeof k)if(e)for(var n=j;n--&&(m=b[n],!(k=l&&l===m||c(l,m,d,e,f,g))););else k=l&&l===m||c(l,m,d,e,f,g)}return!!k}function kc(a,b,c){switch(c){case R:case S:return+a==+b;case T:return a.name==b.name&&a.message==b.message;case W:return a!=+a?b!=+b:0==a?1/a==1/b:a==+b;case Y:case $:return a==d(b)}return!1}function lc(a,b,c,d,e,f,g){var h=Tg(a),i=h.length,j=Tg(b),k=j.length;if(i!=k&&!e)return!1;for(var l,m=-1;++m<i;){var n=h[m],o=Tf.call(b,n);if(o){var p=a[n],q=b[n];o=v,d&&(o=e?d(q,p,n):d(p,q,n)),"undefined"==typeof o&&(o=p&&p===q||c(p,q,d,e,f,g))}if(!o)return!1;l||(l="constructor"==n)}if(!l){var r=a.constructor,s=b.constructor;if(r!=s&&"constructor"in a&&"constructor"in b&&!("function"==typeof r&&r instanceof r&&"function"==typeof s&&s instanceof s))return!1}return!0}function mc(a,b,c){var d=c?vg:ug,e=d,f=e;return sb(a,function(a,g,h){var i=b(a,g,h);((c?e>i:i>e)||i===d&&i===f)&&(e=i,f=a)}),f}function nc(a,b,c){var d=V.callback||sf;return d=d===sf?ob:d,c?d(a,b,c):d}function oc(a,c,d){var e=V.indexOf||Sc;return e=e===Sc?b:e,a?e(a,c,d):e}function pc(a,b,c){for(var d=-1,e=c?c.length:0;++d<e;){var f=c[d],g=f.size;switch(f.type){case"drop":a+=g;break;case"dropRight":b-=g;break;case"take":b=pg(b,a+g);break;case"takeRight":a=og(a,b-g)}}return{start:a,end:b}}function qc(a){var b=a.length,c=new a.constructor(b);return b&&"string"==typeof a[0]&&Tf.call(a,"index")&&(c.index=a.index,c.input=a.input),c}function rc(a){var b=a.constructor;return"function"==typeof b&&b instanceof b||(b=Kf),new b}function sc(a,b,c){var d=a.constructor;switch(b){case aa:return Yb(a);case R:case S:return new d(+a);case ba:case ca:case da:case ea:case fa:case ga:case ha:case ia:case ja:var e=a.buffer;return new d(c?Yb(e):e,a.byteOffset,a.length);case W:case $:return new d(a);case Y:var f=new d(a.source,va.exec(a));f.lastIndex=a.lastIndex}return f}function tc(a){var b=V.support,c=!(b.funcNames?a.name:b.funcDecomp);if(!c){var d=Rf.call(a);b.funcNames||(c=!wa.test(d)),c||(c=Da.test(d)||we(a),Eg(a,c))}return c}function uc(a,b){return a=+a,b=null==b?Ag:b,a>-1&&a%1==0&&b>a}function vc(a,b,c){if(!te(c))return!1;var d=typeof b;if("number"==d)var e=c.length,f=wc(e)&&uc(b,e);else f="string"==d&&b in a;return f&&c[b]===a}function wc(a){return"number"==typeof a&&a>-1&&a%1==0&&Ag>=a}function xc(a){return a===a&&(0===a?1/a>0:!te(a))}function yc(a,b){var c=a[1],d=b[1],e=c|d,f=F|E,g=x|y,h=f|g|z|B,i=c&F&&!(d&F),j=c&E&&!(d&E),k=(j?a:b)[7],l=(i?a:b)[8],m=!(c>=E&&d>g||c>g&&d>=E),n=e>=f&&h>=e&&(E>c||(j||i)&&k.length<=l);if(!m&&!n)return a;d&x&&(a[2]=b[2],e|=c&x?0:z);var o=b[3];if(o){var q=a[3];a[3]=q?Zb(q,o,b[4]):Za(o),a[4]=q?p(a[3],O):Za(b[4])}return o=b[5],o&&(q=a[5],a[5]=q?$b(q,o,b[6]):Za(o),a[6]=q?p(a[5],O):Za(b[6])),o=b[7],o&&(a[7]=Za(o)),d&F&&(a[8]=null==a[8]?b[8]:pg(a[8],b[8])),null==a[9]&&(a[9]=b[9]),a[0]=b[0],a[1]=e,a}function zc(a,b){a=Fc(a);for(var c=-1,d=b.length,e={};++c<d;){var f=b[c];f in a&&(e[f]=a[f])}return e}function Ac(a,b){var c={};return Ab(a,function(a,d,e){b(a,d,e)&&(c[d]=a)}),c}function Bc(a,b){for(var c=a.length,d=pg(b.length,c),e=Za(a);d--;){var f=b[d];a[d]=uc(f,c)?e[f]:v}return a}function Cc(a){var b;V.support;if(!n(a)||Vf.call(a)!=X||!Tf.call(a,"constructor")&&(b=a.constructor,"function"==typeof b&&!(b instanceof b)))return!1;var c;return Ab(a,function(a,b){c=b}),"undefined"==typeof c||Tf.call(a,c)}function Dc(a){for(var b=Qe(a),c=b.length,d=c&&a.length,e=V.support,f=d&&wc(d)&&(Pg(a)||e.nonEnumArgs&&le(a)),g=-1,h=[];++g<c;){var i=b[g];(f&&uc(i,d)||Tf.call(a,i))&&h.push(i)}return h}function Ec(a){return null==a?[]:wc(a.length)?te(a)?a:Kf(a):Xe(a)}function Fc(a){return te(a)?a:Kf(a)}function Gc(a,b,c){b=(c?vc(a,b,c):null==b)?1:og(+b||1,1);for(var d=0,e=a?a.length:0,f=-1,g=Ef($f(e/b));e>d;)g[++f]=Qb(a,d,d+=b);return g}function Hc(a){for(var b=-1,c=a?a.length:0,d=-1,e=[];++b<c;){var f=a[b];f&&(e[++d]=f)}return e}function Ic(){for(var a=-1,b=arguments.length;++a<b;){var c=arguments[a];if(Pg(c)||le(c))break}return rb(c,xb(arguments,!1,!0,++a))}function Jc(a,b,c){var d=a?a.length:0;return d?((c?vc(a,b,c):null==b)&&(b=1),Qb(a,0>b?0:b)):[]}function Kc(a,b,c){var d=a?a.length:0;return d?((c?vc(a,b,c):null==b)&&(b=1),b=d-(+b||0),Qb(a,0,0>b?0:b)):[]}function Lc(a,b,c){var d=a?a.length:0;if(!d)return[];for(b=nc(b,c,3);d--&&b(a[d],d,a););return Qb(a,0,d+1)}function Mc(a,b,c){var d=a?a.length:0;if(!d)return[];var e=-1;for(b=nc(b,c,3);++e<d&&b(a[e],e,a););return Qb(a,e)}function Nc(a,b,c){var d=-1,e=a?a.length:0;for(b=nc(b,c,3);++d<e;)if(b(a[d],d,a))return d;return-1}function Oc(a,b,c){var d=a?a.length:0;for(b=nc(b,c,3);d--;)if(b(a[d],d,a))return d;return-1}function Pc(a){return a?a[0]:v}function Qc(a,b,c){var d=a?a.length:0;return c&&vc(a,b,c)&&(b=!1),d?xb(a,b):[]}function Rc(a){var b=a?a.length:0;return b?xb(a,!0):[]}function Sc(a,c,d){var e=a?a.length:0;if(!e)return-1;if("number"==typeof d)d=0>d?og(e+d,0):d||0;else if(d){var f=Vb(a,c),g=a[f];return(c===c?c===g:g!==g)?f:-1}return b(a,c,d)}function Tc(a){return Kc(a,1)}function Uc(){for(var a=[],c=-1,d=arguments.length,e=[],f=oc(),g=f==b;++c<d;){var h=arguments[c];(Pg(h)||le(h))&&(a.push(h),e.push(g&&h.length>=120&&Fg(c&&h)))}d=a.length;var i=a[0],j=-1,k=i?i.length:0,l=[],m=e[0];a:for(;++j<k;)if(h=i[j],(m?Xa(m,h):f(l,h))<0){for(c=d;--c;){var n=e[c];if((n?Xa(n,h):f(a[c],h))<0)continue a}m&&m.push(h),l.push(h)}return l}function Vc(a){var b=a?a.length:0;return b?a[b-1]:v}function Wc(a,b,c){var d=a?a.length:0;if(!d)return-1;var e=d;if("number"==typeof c)e=(0>c?og(d+c,0):pg(c||0,d-1))+1;else if(c){e=Vb(a,b,!0)-1;var f=a[e];return(b===b?b===f:f!==f)?e:-1}if(b!==b)return m(a,e,!0);for(;e--;)if(a[e]===b)return e;return-1}function Xc(){var a=arguments[0];if(!a||!a.length)return a;for(var b=0,c=oc(),d=arguments.length;++b<d;)for(var e=0,f=arguments[b];(e=c(a,f,e))>-1;)gg.call(a,e,1);return a}function Yc(a){return Nb(a||[],xb(arguments,!1,!1,1))}function Zc(a,b,c){var d=-1,e=a?a.length:0,f=[];for(b=nc(b,c,3);++d<e;){var g=a[d];b(g,d,a)&&(f.push(g),gg.call(a,d--,1),e--)}return f}function $c(a){return Jc(a,1)}function _c(a,b,c){var d=a?a.length:0;return d?(c&&"number"!=typeof c&&vc(a,b,c)&&(b=0,c=d),Qb(a,b,c)):[]}function ad(a,b,c,d){var e=nc(c);return e===ob&&null==c?Vb(a,b):Wb(a,b,e(c,d,1))}function bd(a,b,c,d){var e=nc(c);return e===ob&&null==c?Vb(a,b,!0):Wb(a,b,e(c,d,1),!0)}function cd(a,b,c){var d=a?a.length:0;return d?((c?vc(a,b,c):null==b)&&(b=1),Qb(a,0,0>b?0:b)):[]}function dd(a,b,c){var d=a?a.length:0;return d?((c?vc(a,b,c):null==b)&&(b=1),b=d-(+b||0),Qb(a,0>b?0:b)):[]}function ed(a,b,c){var d=a?a.length:0;if(!d)return[];for(b=nc(b,c,3);d--&&b(a[d],d,a););return Qb(a,d+1)}function fd(a,b,c){var d=a?a.length:0;if(!d)return[];var e=-1;for(b=nc(b,c,3);++e<d&&b(a[e],e,a););return Qb(a,0,e)}function gd(){return Sb(xb(arguments,!1,!0))}function hd(a,c,d,e){var f=a?a.length:0;if(!f)return[];"boolean"!=typeof c&&null!=c&&(e=d,d=vc(a,c,e)?null:c,c=!1);var g=nc();return(g!==ob||null!=d)&&(d=g(d,e,3)),c&&oc()==b?q(a,d):Sb(a,d)}function id(a){for(var b=-1,c=(a&&a.length&&db(cb(a,Sf)))>>>0,d=Ef(c);++b<c;)d[b]=cb(a,Mb(b));return d}function jd(a){return rb(a,Qb(arguments,1))}function kd(){for(var a=-1,b=arguments.length;++a<b;){var c=arguments[a];if(Pg(c)||le(c))var d=d?rb(d,c).concat(rb(c,d)):c}return d?Sb(d):[]}function ld(){for(var a=arguments.length,b=Ef(a);a--;)b[a]=arguments[a];return id(b)}function md(a,b){var c=-1,d=a?a.length:0,e={};for(!d||b||Pg(a[0])||(b=[]);++c<d;){var f=a[c];b?e[f]=b[c]:f&&(e[f[0]]=f[1])}return e}function nd(a){var b=V(a);return b.__chain__=!0,b}function od(a,b,c){return b.call(c,a),a}function pd(a,b,c){return b.call(c,a)}function qd(){return nd(this)}function rd(){var a=this.__wrapped__;return a instanceof _?new Z(a.reverse()):this.thru(function(a){return a.reverse()})}function sd(){return this.value()+""}function td(){return Ub(this.__wrapped__,this.__actions__)}function ud(a){var b=a?a.length:0;return wc(b)&&(a=Ec(a)),lb(a,xb(arguments,!1,!1,1))}function vd(a,b,c){var d=a?a.length:0;return wc(d)||(a=Xe(a),d=a.length),d?(c="number"==typeof c?0>c?og(d+c,0):c||0:0,"string"==typeof a||!Pg(a)&&Ae(a)?d>c&&a.indexOf(b,c)>-1:oc(a,b,c)>-1):!1}function wd(a,b,c){var d=Pg(a)?ab:ub;return("function"!=typeof b||"undefined"!=typeof c)&&(b=nc(b,c,3)),d(a,b)}function xd(a,b,c){var d=Pg(a)?bb:vb;return b=nc(b,c,3),d(a,b)}function yd(a,b,c){if(Pg(a)){var d=Nc(a,b,c);return d>-1?a[d]:v}return b=nc(b,c,3),wb(a,b,sb)}function zd(a,b,c){return b=nc(b,c,3),wb(a,b,tb)}function Ad(a,b){return yd(a,vf(b))}function Bd(a,b,c){return"function"==typeof b&&"undefined"==typeof c&&Pg(a)?$a(a,b):sb(a,Xb(b,c,3))}function Cd(a,b,c){return"function"==typeof b&&"undefined"==typeof c&&Pg(a)?_a(a,b):tb(a,Xb(b,c,3))}function Dd(a,b){return Eb(a,b,Qb(arguments,2))}function Ed(a,b,c){var d=Pg(a)?cb:Ib;return b=nc(b,c,3),d(a,b)}function Fd(a,b){return Ed(a,zf(b))}function Gd(a,b,c,d){var e=Pg(a)?fb:Pb;return e(a,nc(b,d,4),c,arguments.length<3,sb)}function Hd(a,b,c,d){var e=Pg(a)?gb:Pb;return e(a,nc(b,d,4),c,arguments.length<3,tb)}function Id(a,b,c){var d=Pg(a)?bb:vb;return b=nc(b,c,3),d(a,function(a,c,d){return!b(a,c,d)})}function Jd(a,b,c){if(c?vc(a,b,c):null==b){a=Ec(a);var d=a.length;return d>0?a[Ob(0,d-1)]:v}var e=Kd(a);return e.length=pg(0>b?0:+b||0,e.length),e}function Kd(a){a=Ec(a);for(var b=-1,c=a.length,d=Ef(c);++b<c;){var e=Ob(0,b);b!=e&&(d[b]=d[e]),d[e]=a[b]}return d}function Ld(a){var b=a?a.length:0;return wc(b)?b:Tg(a).length}function Md(a,b,c){var d=Pg(a)?hb:Rb;return("function"!=typeof b||"undefined"!=typeof c)&&(b=nc(b,c,3)),d(a,b)}function Nd(a,b,d){var e=-1,f=a?a.length:0,g=wc(f)?Ef(f):[];return d&&vc(a,b,d)&&(b=null),b=nc(b,d,3),sb(a,function(a,c,d){g[++e]={criteria:b(a,c,d),index:e,value:a}}),c(g,h)}function Od(a){var b=arguments;b.length>3&&vc(b[1],b[2],b[3])&&(b=[a,b[1]]);var d=-1,e=a?a.length:0,f=xb(b,!1,!1,1),g=wc(e)?Ef(e):[];return sb(a,function(a,b,c){for(var e=f.length,h=Ef(e);e--;)h[e]=null==a?v:a[f[e]];g[++d]={criteria:h,index:d,value:a}}),c(g,i)}function Pd(a,b){return xd(a,vf(b))}function Qd(a,b){if(!se(b)){if(!se(a))throw new Nf(N);var c=a;a=b,b=c}return a=mg(a=+a)?a:0,function(){return--a<1?b.apply(this,arguments):void 0}}function Rd(a,b,c){return c&&vc(a,b,c)&&(b=null),b=a&&null==b?a.length:og(+b||0,0),ic(a,F,null,null,null,null,b)}function Sd(a,b){var c;if(!se(b)){if(!se(a))throw new Nf(N);var d=a;a=b,b=d}return function(){return--a>0?c=b.apply(this,arguments):b=null,c}}function Td(a,b){var c=x;if(arguments.length>2){var d=Qb(arguments,2),e=p(d,Td.placeholder);c|=C}return ic(a,c,b,d,e)}function Ud(a){return nb(a,arguments.length>1?xb(arguments,!1,!1,1):Ne(a))}function Vd(a,b){var c=x|y;if(arguments.length>2){var d=Qb(arguments,2),e=p(d,Vd.placeholder);c|=C}return ic(b,c,a,d,e)}function Wd(a,b,c){c&&vc(a,b,c)&&(b=null);var d=ic(a,A,null,null,null,null,null,b);return d.placeholder=Wd.placeholder,d}function Xd(a,b,c){c&&vc(a,b,c)&&(b=null);var d=ic(a,B,null,null,null,null,null,b);return d.placeholder=Xd.placeholder,d}function Yd(a,b,c){function d(){m&&_f(m),i&&_f(i),i=m=n=v}function e(){var c=b-(Og()-k);if(0>=c||c>b){i&&_f(i);var d=n;i=m=n=v,d&&(o=Og(),j=a.apply(l,h),m||i||(h=l=null))}else m=fg(e,c)}function f(){m&&_f(m),i=m=n=v,(q||p!==b)&&(o=Og(),j=a.apply(l,h),m||i||(h=l=null))}function g(){if(h=arguments,k=Og(),l=this,n=q&&(m||!r),p===!1)var c=r&&!m;else{i||r||(o=k);var d=p-(k-o),g=0>=d||d>p;g?(i&&(i=_f(i)),o=k,j=a.apply(l,h)):i||(i=fg(f,d))}return g&&m?m=_f(m):m||b===p||(m=fg(e,b)),c&&(g=!0,j=a.apply(l,h)),!g||m||i||(h=l=null),j}var h,i,j,k,l,m,n,o=0,p=!1,q=!0;if(!se(a))throw new Nf(N);if(b=0>b?0:b,c===!0){var r=!0;q=!1}else te(c)&&(r=c.leading,p="maxWait"in c&&og(+c.maxWait||0,b),q="trailing"in c?c.trailing:q);return g.cancel=d,g}function Zd(a){return qb(a,1,arguments,1)}function $d(a,b){return qb(a,b,arguments,2)}function _d(){var a=arguments,b=a.length;if(!b)return function(){};if(!ab(a,se))throw new Nf(N);return function(){for(var c=0,d=a[c].apply(this,arguments);++c<b;)d=a[c].call(this,d);return d}}function ae(){var a=arguments,b=a.length-1;if(0>b)return function(){};if(!ab(a,se))throw new Nf(N);return function(){for(var c=b,d=a[c].apply(this,arguments);c--;)d=a[c].call(this,d);return d}}function be(a,b){if(!se(a)||b&&!se(b))throw new Nf(N);var c=function(){var d=c.cache,e=b?b.apply(this,arguments):arguments[0];if(d.has(e))return d.get(e);var f=a.apply(this,arguments);return d.set(e,f),f};return c.cache=new be.Cache,c}function ce(a){if(!se(a))throw new Nf(N);return function(){return!a.apply(this,arguments)}}function de(a){return Sd(a,2)}function ee(a){var b=Qb(arguments,1),c=p(b,ee.placeholder);return ic(a,C,null,b,c)}function fe(a){var b=Qb(arguments,1),c=p(b,fe.placeholder);return ic(a,D,null,b,c)}function ge(a){var b=xb(arguments,!1,!1,1);return ic(a,E,null,null,null,b)}function he(a,b,c){var d=!0,e=!0;if(!se(a))throw new Nf(N);return c===!1?d=!1:te(c)&&(d="leading"in c?!!c.leading:d,e="trailing"in c?!!c.trailing:e),La.leading=d,La.maxWait=+b,La.trailing=e,Yd(a,b,La)}function ie(a,b){return b=null==b?uf:b,ic(b,C,null,[a],[])}function je(a,b,c,d){return"boolean"!=typeof b&&null!=b&&(d=c,c=vc(a,b,d)?null:b,b=!1),c="function"==typeof c&&Xb(c,d,1),pb(a,b,c)}function ke(a,b,c){return b="function"==typeof b&&Xb(b,c,1),pb(a,!0,b)}function le(a){var b=n(a)?a.length:v;return wc(b)&&Vf.call(a)==P||!1}function me(a){return a===!0||a===!1||n(a)&&Vf.call(a)==R||!1}function ne(a){return n(a)&&Vf.call(a)==S||!1}function oe(a){return a&&1===a.nodeType&&n(a)&&Vf.call(a).indexOf("Element")>-1||!1}function pe(a){if(null==a)return!0;var b=a.length;return wc(b)&&(Pg(a)||Ae(a)||le(a)||n(a)&&se(a.splice))?!b:!Tg(a).length}function qe(a,b,c,d){if(c="function"==typeof c&&Xb(c,d,3),!c&&xc(a)&&xc(b))return a===b;var e=c?c(a,b):v;return"undefined"==typeof e?Fb(a,b,c):!!e}function re(a){return n(a)&&"string"==typeof a.message&&Vf.call(a)==T||!1}function se(a){return"function"==typeof a||!1}function te(a){var b=typeof a;return"function"==b||a&&"object"==b||!1}function ue(a,b,c,d){var e=Tg(b),f=e.length;if(c="function"==typeof c&&Xb(c,d,3),!c&&1==f){var g=e[0],h=b[g];if(xc(h))return null!=a&&h===a[g]&&Tf.call(a,g)}for(var i=Ef(f),j=Ef(f);f--;)h=i[f]=b[e[f]],j[f]=xc(h);return Hb(a,e,i,j,c)}function ve(a){return ye(a)&&a!=+a}function we(a){return null==a?!1:Vf.call(a)==U?Xf.test(Rf.call(a)):n(a)&&ya.test(a)||!1}function xe(a){return null===a}function ye(a){return"number"==typeof a||n(a)&&Vf.call(a)==W||!1}function ze(a){return n(a)&&Vf.call(a)==Y||!1}function Ae(a){return"string"==typeof a||n(a)&&Vf.call(a)==$||!1}function Be(a){return n(a)&&wc(a.length)&&Ja[Vf.call(a)]||!1}function Ce(a){return"undefined"==typeof a}function De(a){var b=a?a.length:0;return wc(b)?b?Za(a):[]:Xe(a)}function Ee(a){return mb(a,Qe(a))}function Fe(a,b,c){var d=Dg(a);return c&&vc(a,b,c)&&(b=null),b?mb(b,d,Tg(b)):d}function Ge(a){if(null==a)return a;var b=Za(arguments);return b.push(ib),Sg.apply(v,b)}function He(a,b,c){return b=nc(b,c,3),wb(a,b,Bb,!0)}function Ie(a,b,c){return b=nc(b,c,3),wb(a,b,Cb,!0)}function Je(a,b,c){return("function"!=typeof b||"undefined"!=typeof c)&&(b=Xb(b,c,3)),yb(a,b,Qe)}function Ke(a,b,c){return b=Xb(b,c,3),zb(a,b,Qe)}function Le(a,b,c){return("function"!=typeof b||"undefined"!=typeof c)&&(b=Xb(b,c,3)),Bb(a,b)}function Me(a,b,c){return b=Xb(b,c,3),zb(a,b,Tg)}function Ne(a){return Db(a,Qe(a))}function Oe(a,b){return a?Tf.call(a,b):!1}function Pe(a,b,c){c&&vc(a,b,c)&&(b=null);for(var d=-1,e=Tg(a),f=e.length,g={};++d<f;){var h=e[d],i=a[h];b?Tf.call(g,i)?g[i].push(h):g[i]=[h]:g[i]=h}return g}function Qe(a){if(null==a)return[];te(a)||(a=Kf(a));var b=a.length;b=b&&wc(b)&&(Pg(a)||Cg.nonEnumArgs&&le(a))&&b||0;for(var c=a.constructor,d=-1,e="function"==typeof c&&c.prototype==a,f=Ef(b),g=b>0;++d<b;)f[d]=d+"";for(var h in a)g&&uc(h,b)||"constructor"==h&&(e||!Tf.call(a,h))||f.push(h);return f}function Re(a,b,c){var d={};return b=nc(b,c,3),Bb(a,function(a,c,e){d[c]=b(a,c,e)}),d}function Se(a,b,c){if(null==a)return{};if("function"!=typeof b){var d=cb(xb(arguments,!1,!1,1),Mf);return zc(a,rb(Qe(a),d))}return b=Xb(b,c,3),Ac(a,function(a,c,d){return!b(a,c,d)})}function Te(a){for(var b=-1,c=Tg(a),d=c.length,e=Ef(d);++b<d;){var f=c[b];e[b]=[f,a[f]]}return e}function Ue(a,b,c){return null==a?{}:"function"==typeof b?Ac(a,Xb(b,c,3)):zc(a,xb(arguments,!1,!1,1))}function Ve(a,b,c){var d=null==a?v:a[b];return"undefined"==typeof d&&(d=c),se(d)?d.call(a):d}function We(a,b,c,d){var e=Pg(a)||Be(a);if(b=nc(b,d,4),null==c)if(e||te(a)){var f=a.constructor;c=e?Pg(a)?new f:[]:Dg("function"==typeof f&&f.prototype)}else c={};return(e?$a:Bb)(a,function(a,d,e){return b(c,a,d,e)}),c}function Xe(a){return Tb(a,Tg(a))}function Ye(a){return Tb(a,Qe(a))}function Ze(a,b,c){c&&vc(a,b,c)&&(b=c=null);var d=null==a,e=null==b;if(null==c&&(e&&"boolean"==typeof a?(c=a,a=1):"boolean"==typeof b&&(c=b,e=!0)),d&&e&&(b=1,e=!1),a=+a||0,e?(b=a,a=0):b=+b||0,c||a%1||b%1){var f=tg();return pg(a+f*(b-a+parseFloat("1e-"+((f+"").length-1))),b)}return Ob(a,b)}function $e(a){return a=d(a),a&&a.charAt(0).toUpperCase()+a.slice(1)}function _e(a){return a=d(a),a&&a.replace(za,j)}function af(a,b,c){a=d(a),b+="";var e=a.length;return c=("undefined"==typeof c?e:pg(0>c?0:+c||0,e))-b.length,c>=0&&a.indexOf(b,c)==c}function bf(a){return a=d(a),a&&qa.test(a)?a.replace(oa,k):a}function cf(a){return a=d(a),a&&Ca.test(a)?a.replace(Ba,"\\$&"):a}function df(a,b,c){a=d(a),b=+b;var e=a.length;if(e>=b||!mg(b))return a;var f=(b-e)/2,g=ag(f),h=$f(f);return c=gc("",h,c),c.slice(0,g)+a+c}function ef(a,b,c){return a=d(a),a&&gc(a,b,c)+a}function ff(a,b,c){return a=d(a),a&&a+gc(a,b,c)}function gf(a,b,c){return c&&vc(a,b,c)&&(b=0),sg(a,b)}function hf(a,b){var c="";if(a=d(a),b=+b,1>b||!a||!mg(b))return c;do b%2&&(c+=a),b=ag(b/2),a+=a;while(b);return c}function jf(a,b,c){return a=d(a),c=null==c?0:pg(0>c?0:+c||0,a.length),a.lastIndexOf(b,c)==c}function kf(a,b,c){var e=V.templateSettings;c&&vc(a,b,c)&&(b=c=null),a=d(a),b=kb(kb({},c||b),e,jb); var f,g,h=kb(kb({},b.imports),e.imports,jb),i=Tg(h),j=Tb(h,i),k=0,m=b.interpolate||Aa,n="__p += '",o=Lf((b.escape||Aa).source+"|"+m.source+"|"+(m===ta?ua:Aa).source+"|"+(b.evaluate||Aa).source+"|$","g"),p="//# sourceURL="+("sourceURL"in b?b.sourceURL:"lodash.templateSources["+ ++Ia+"]")+"\n";a.replace(o,function(b,c,d,e,h,i){return d||(d=e),n+=a.slice(k,i).replace(Ea,l),c&&(f=!0,n+="' +\n__e("+c+") +\n'"),h&&(g=!0,n+="';\n"+h+";\n__p += '"),d&&(n+="' +\n((__t = ("+d+")) == null ? '' : __t) +\n'"),k=i+b.length,b}),n+="';\n";var q=b.variable;q||(n="with (obj) {\n"+n+"\n}\n"),n=(g?n.replace(ka,""):n).replace(la,"$1").replace(ma,"$1;"),n="function("+(q||"obj")+") {\n"+(q?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(f?", __e = _.escape":"")+(g?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+n+"return __p\n}";var r=rf(function(){return Hf(i,p+"return "+n).apply(v,j)});if(r.source=n,re(r))throw r;return r}function lf(a,b,c){var e=a;return(a=d(a))?(c?vc(e,b,c):null==b)?a.slice(r(a),s(a)+1):(b=d(b),a.slice(f(a,b),g(a,b)+1)):a}function mf(a,b,c){var e=a;return a=d(a),a?(c?vc(e,b,c):null==b)?a.slice(r(a)):a.slice(f(a,d(b))):a}function nf(a,b,c){var e=a;return a=d(a),a?(c?vc(e,b,c):null==b)?a.slice(0,s(a)+1):a.slice(0,g(a,d(b))+1):a}function of(a,b,c){c&&vc(a,b,c)&&(b=null);var e=G,f=H;if(null!=b)if(te(b)){var g="separator"in b?b.separator:g;e="length"in b?+b.length||0:e,f="omission"in b?d(b.omission):f}else e=+b||0;if(a=d(a),e>=a.length)return a;var h=e-f.length;if(1>h)return f;var i=a.slice(0,h);if(null==g)return i+f;if(ze(g)){if(a.slice(h).search(g)){var j,k,l=a.slice(0,h);for(g.global||(g=Lf(g.source,(va.exec(g)||"")+"g")),g.lastIndex=0;j=g.exec(l);)k=j.index;i=i.slice(0,null==k?h:k)}}else if(a.indexOf(g,h)!=h){var m=i.lastIndexOf(g);m>-1&&(i=i.slice(0,m))}return i+f}function pf(a){return a=d(a),a&&pa.test(a)?a.replace(na,t):a}function qf(a,b,c){return c&&vc(a,b,c)&&(b=null),a=d(a),a.match(b||Fa)||[]}function rf(a){try{return a()}catch(b){return re(b)?b:Gf(b)}}function sf(a,b,c){return c&&vc(a,b,c)&&(b=null),ob(a,b)}function tf(a){return function(){return a}}function uf(a){return a}function vf(a){return Jb(a,!0)}function wf(a,b,c){if(null==c){var d=te(b),e=d&&Tg(b),f=e&&e.length&&Db(b,e);(f?f.length:d)||(f=!1,c=b,b=a,a=this)}f||(f=Db(b,Tg(b)));var g=!0,h=-1,i=se(a),j=f.length;c===!1?g=!1:te(c)&&"chain"in c&&(g=c.chain);for(;++h<j;){var k=f[h],l=b[k];a[k]=l,i&&(a.prototype[k]=function(b){return function(){var c=this.__chain__;if(g||c){var d=a(this.__wrapped__);return(d.__actions__=Za(this.__actions__)).push({func:b,args:arguments,thisArg:a}),d.__chain__=c,d}var e=[this.value()];return cg.apply(e,arguments),b.apply(a,e)}}(l))}return a}function xf(){return o._=Wf,this}function yf(){}function zf(a){return Mb(a+"")}function Af(a){return function(b){return null==a?v:a[b]}}function Bf(a,b,c){c&&vc(a,b,c)&&(b=c=null),a=+a||0,c=null==c?1:+c||0,null==b?(b=a,a=0):b=+b||0;for(var d=-1,e=og($f((b-a)/(c||1)),0),f=Ef(e);++d<e;)f[d]=a,a+=c;return f}function Cf(a,b,c){if(a=+a,1>a||!mg(a))return[];var d=-1,e=Ef(pg(a,wg));for(b=Xb(b,c,1);++d<a;)wg>d?e[d]=b(d):b(d);return e}function Df(a){var b=++Uf;return d(a)+b}o=o?Wa.defaults(Ra.Object(),o,Wa.pick(Ra,Ha)):Ra;var Ef=o.Array,Ff=o.Date,Gf=o.Error,Hf=o.Function,If=o.Math,Jf=o.Number,Kf=o.Object,Lf=o.RegExp,Mf=o.String,Nf=o.TypeError,Of=Ef.prototype,Pf=Kf.prototype,Qf=(Qf=o.window)&&Qf.document,Rf=Hf.prototype.toString,Sf=Mb("length"),Tf=Pf.hasOwnProperty,Uf=0,Vf=Pf.toString,Wf=o._,Xf=Lf("^"+cf(Vf).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Yf=we(Yf=o.ArrayBuffer)&&Yf,Zf=we(Zf=Yf&&new Yf(0).slice)&&Zf,$f=If.ceil,_f=o.clearTimeout,ag=If.floor,bg=we(bg=Kf.getPrototypeOf)&&bg,cg=Of.push,dg=Pf.propertyIsEnumerable,eg=we(eg=o.Set)&&eg,fg=o.setTimeout,gg=Of.splice,hg=we(hg=o.Uint8Array)&&hg,ig=(Of.unshift,we(ig=o.WeakMap)&&ig),jg=function(){try{var a=we(a=o.Float64Array)&&a,b=new a(new Yf(10),0,1)&&a}catch(c){}return b}(),kg=we(kg=Ef.isArray)&&kg,lg=we(lg=Kf.create)&&lg,mg=o.isFinite,ng=we(ng=Kf.keys)&&ng,og=If.max,pg=If.min,qg=we(qg=Ff.now)&&qg,rg=we(rg=Jf.isFinite)&&rg,sg=o.parseInt,tg=If.random,ug=Jf.NEGATIVE_INFINITY,vg=Jf.POSITIVE_INFINITY,wg=If.pow(2,32)-1,xg=wg-1,yg=wg>>>1,zg=jg?jg.BYTES_PER_ELEMENT:0,Ag=If.pow(2,53)-1,Bg=ig&&new ig,Cg=V.support={};!function(a){Cg.funcDecomp=!we(o.WinRTError)&&Da.test(u),Cg.funcNames="string"==typeof Hf.name;try{Cg.dom=11===Qf.createDocumentFragment().nodeType}catch(b){Cg.dom=!1}try{Cg.nonEnumArgs=!dg.call(arguments,1)}catch(b){Cg.nonEnumArgs=!0}}(0,0),V.templateSettings={escape:ra,evaluate:sa,interpolate:ta,variable:"",imports:{_:V}};var Dg=function(){function a(){}return function(b){if(te(b)){a.prototype=b;var c=new a;a.prototype=null}return c||o.Object()}}(),Eg=Bg?function(a,b){return Bg.set(a,b),a}:uf;Zf||(Yb=Yf&&hg?function(a){var b=a.byteLength,c=jg?ag(b/zg):0,d=c*zg,e=new Yf(b);if(c){var f=new jg(e,0,c);f.set(new jg(a,0,c))}return b!=d&&(f=new hg(e,d),f.set(new hg(a,d))),e}:tf(null));var Fg=lg&&eg?function(a){return new Va(a)}:tf(null),Gg=Bg?function(a){return Bg.get(a)}:yf,Hg=function(){var a=0,b=0;return function(c,d){var e=Og(),f=J-(e-b);if(b=e,f>0){if(++a>=I)return c}else a=0;return Eg(c,d)}}(),Ig=_b(function(a,b,c){Tf.call(a,c)?++a[c]:a[c]=1}),Jg=_b(function(a,b,c){Tf.call(a,c)?a[c].push(b):a[c]=[b]}),Kg=_b(function(a,b,c){a[c]=b}),Lg=ec(db),Mg=ec(eb,!0),Ng=_b(function(a,b,c){a[c?0:1].push(b)},function(){return[[],[]]}),Og=qg||function(){return(new Ff).getTime()},Pg=kg||function(a){return n(a)&&wc(a.length)&&Vf.call(a)==Q||!1};Cg.dom||(oe=function(a){return a&&1===a.nodeType&&n(a)&&!Rg(a)||!1});var Qg=rg||function(a){return"number"==typeof a&&mg(a)};(se(/x/)||hg&&!se(hg))&&(se=function(a){return Vf.call(a)==U});var Rg=bg?function(a){if(!a||Vf.call(a)!=X)return!1;var b=a.valueOf,c=we(b)&&(c=bg(b))&&bg(c);return c?a==c||bg(a)==c:Cc(a)}:Cc,Sg=ac(kb),Tg=ng?function(a){if(a)var b=a.constructor,c=a.length;return"function"==typeof b&&b.prototype===a||"function"!=typeof a&&c&&wc(c)?Dc(a):te(a)?ng(a):[]}:Dc,Ug=ac(Kb),Vg=cc(function(a,b,c){return b=b.toLowerCase(),c?a+b.charAt(0).toUpperCase()+b.slice(1):b}),Wg=cc(function(a,b,c){return a+(c?"-":"")+b.toLowerCase()});8!=sg(Ga+"08")&&(gf=function(a,b,c){return(c?vc(a,b,c):null==b)?b=0:b&&(b=+b),a=lf(a),sg(a,b||(xa.test(a)?16:10))});var Xg=cc(function(a,b,c){return a+(c?"_":"")+b.toLowerCase()});return Z.prototype=V.prototype,Pa.prototype["delete"]=Qa,Pa.prototype.get=Sa,Pa.prototype.has=Ta,Pa.prototype.set=Ua,Va.prototype.push=Ya,be.Cache=Pa,V.after=Qd,V.ary=Rd,V.assign=Sg,V.at=ud,V.before=Sd,V.bind=Td,V.bindAll=Ud,V.bindKey=Vd,V.callback=sf,V.chain=nd,V.chunk=Gc,V.compact=Hc,V.constant=tf,V.countBy=Ig,V.create=Fe,V.curry=Wd,V.curryRight=Xd,V.debounce=Yd,V.defaults=Ge,V.defer=Zd,V.delay=$d,V.difference=Ic,V.drop=Jc,V.dropRight=Kc,V.dropRightWhile=Lc,V.dropWhile=Mc,V.filter=xd,V.flatten=Qc,V.flattenDeep=Rc,V.flow=_d,V.flowRight=ae,V.forEach=Bd,V.forEachRight=Cd,V.forIn=Je,V.forInRight=Ke,V.forOwn=Le,V.forOwnRight=Me,V.functions=Ne,V.groupBy=Jg,V.indexBy=Kg,V.initial=Tc,V.intersection=Uc,V.invert=Pe,V.invoke=Dd,V.keys=Tg,V.keysIn=Qe,V.map=Ed,V.mapValues=Re,V.matches=vf,V.memoize=be,V.merge=Ug,V.mixin=wf,V.negate=ce,V.omit=Se,V.once=de,V.pairs=Te,V.partial=ee,V.partialRight=fe,V.partition=Ng,V.pick=Ue,V.pluck=Fd,V.property=zf,V.propertyOf=Af,V.pull=Xc,V.pullAt=Yc,V.range=Bf,V.rearg=ge,V.reject=Id,V.remove=Zc,V.rest=$c,V.shuffle=Kd,V.slice=_c,V.sortBy=Nd,V.sortByAll=Od,V.take=cd,V.takeRight=dd,V.takeRightWhile=ed,V.takeWhile=fd,V.tap=od,V.throttle=he,V.thru=pd,V.times=Cf,V.toArray=De,V.toPlainObject=Ee,V.transform=We,V.union=gd,V.uniq=hd,V.unzip=id,V.values=Xe,V.valuesIn=Ye,V.where=Pd,V.without=jd,V.wrap=ie,V.xor=kd,V.zip=ld,V.zipObject=md,V.backflow=ae,V.collect=Ed,V.compose=ae,V.each=Bd,V.eachRight=Cd,V.extend=Sg,V.iteratee=sf,V.methods=Ne,V.object=md,V.select=xd,V.tail=$c,V.unique=hd,wf(V,V),V.attempt=rf,V.camelCase=Vg,V.capitalize=$e,V.clone=je,V.cloneDeep=ke,V.deburr=_e,V.endsWith=af,V.escape=bf,V.escapeRegExp=cf,V.every=wd,V.find=yd,V.findIndex=Nc,V.findKey=He,V.findLast=zd,V.findLastIndex=Oc,V.findLastKey=Ie,V.findWhere=Ad,V.first=Pc,V.has=Oe,V.identity=uf,V.includes=vd,V.indexOf=Sc,V.isArguments=le,V.isArray=Pg,V.isBoolean=me,V.isDate=ne,V.isElement=oe,V.isEmpty=pe,V.isEqual=qe,V.isError=re,V.isFinite=Qg,V.isFunction=se,V.isMatch=ue,V.isNaN=ve,V.isNative=we,V.isNull=xe,V.isNumber=ye,V.isObject=te,V.isPlainObject=Rg,V.isRegExp=ze,V.isString=Ae,V.isTypedArray=Be,V.isUndefined=Ce,V.kebabCase=Wg,V.last=Vc,V.lastIndexOf=Wc,V.max=Lg,V.min=Mg,V.noConflict=xf,V.noop=yf,V.now=Og,V.pad=df,V.padLeft=ef,V.padRight=ff,V.parseInt=gf,V.random=Ze,V.reduce=Gd,V.reduceRight=Hd,V.repeat=hf,V.result=Ve,V.runInContext=u,V.size=Ld,V.snakeCase=Xg,V.some=Md,V.sortedIndex=ad,V.sortedLastIndex=bd,V.startsWith=jf,V.template=kf,V.trim=lf,V.trimLeft=mf,V.trimRight=nf,V.trunc=of,V.unescape=pf,V.uniqueId=Df,V.words=qf,V.all=wd,V.any=Md,V.contains=vd,V.detect=yd,V.foldl=Gd,V.foldr=Hd,V.head=Pc,V.include=vd,V.inject=Gd,wf(V,function(){var a={};return Bb(V,function(b,c){V.prototype[c]||(a[c]=b)}),a}(),!1),V.sample=Jd,V.prototype.sample=function(a){return this.__chain__||null!=a?this.thru(function(b){return Jd(b,a)}):Jd(this.value())},V.VERSION=w,$a(["bind","bindKey","curry","curryRight","partial","partialRight"],function(a){V[a].placeholder=V}),$a(["filter","map","takeWhile"],function(a,b){var c=b==K;_.prototype[a]=function(a,d){var e=this.clone(),f=e.filtered,g=e.iteratees||(e.iteratees=[]);return e.filtered=f||c||b==M&&e.dir<0,g.push({iteratee:nc(a,d,3),type:b}),e}}),$a(["drop","take"],function(a,b){var c=a+"Count",d=a+"While";_.prototype[a]=function(d){d=null==d?1:og(+d||0,0);var e=this.clone();if(e.filtered){var f=e[c];e[c]=b?pg(f,d):f+d}else{var g=e.views||(e.views=[]);g.push({size:d,type:a+(e.dir<0?"Right":"")})}return e},_.prototype[a+"Right"]=function(b){return this.reverse()[a](b).reverse()},_.prototype[a+"RightWhile"]=function(a,b){return this.reverse()[d](a,b).reverse()}}),$a(["first","last"],function(a,b){var c="take"+(b?"Right":"");_.prototype[a]=function(){return this[c](1).value()[0]}}),$a(["initial","rest"],function(a,b){var c="drop"+(b?"":"Right");_.prototype[a]=function(){return this[c](1)}}),$a(["pluck","where"],function(a,b){var c=b?"filter":"map",d=b?vf:zf;_.prototype[a]=function(a){return this[c](d(a))}}),_.prototype.dropWhile=function(a,b){var c,d,e=this.dir<0;return a=nc(a,b,3),this.filter(function(b,f,g){return c=c&&(e?d>f:f>d),d=f,c||(c=!a(b,f,g))})},_.prototype.reject=function(a,b){return a=nc(a,b,3),this.filter(function(b,c,d){return!a(b,c,d)})},_.prototype.slice=function(a,b){a=null==a?0:+a||0;var c=0>a?this.takeRight(-a):this.drop(a);return"undefined"!=typeof b&&(b=+b||0,c=0>b?c.dropRight(-b):c.take(b-a)),c},Bb(_.prototype,function(a,b){var c=/^(?:first|last)$/.test(b);V.prototype[b]=function(){var d=this.__wrapped__,e=arguments,f=this.__chain__,g=!!this.__actions__.length,h=d instanceof _,i=h&&!g;if(c&&!f)return i?a.call(d):V[b](this.value());var j=function(a){var c=[a];return cg.apply(c,e),V[b].apply(V,c)};if(h||Pg(d)){var k=i?d:new _(this),l=a.apply(k,e);if(!c&&(g||l.actions)){var m=l.actions||(l.actions=[]);m.push({func:pd,args:[j],thisArg:V})}return new Z(l,f)}return this.thru(j)}}),$a(["concat","join","pop","push","shift","sort","splice","unshift"],function(a){var b=Of[a],c=/^(?:push|sort|unshift)$/.test(a)?"tap":"thru",d=/^(?:join|pop|shift)$/.test(a);V.prototype[a]=function(){var a=arguments;return d&&!this.__chain__?b.apply(this.value(),a):this[c](function(c){return b.apply(c,a)})}}),_.prototype.clone=Ma,_.prototype.reverse=Na,_.prototype.value=Oa,V.prototype.chain=qd,V.prototype.reverse=rd,V.prototype.toString=sd,V.prototype.toJSON=V.prototype.valueOf=V.prototype.value=td,V.prototype.collect=V.prototype.map,V.prototype.head=V.prototype.first,V.prototype.select=V.prototype.filter,V.prototype.tail=V.prototype.rest,V}var v,w="3.0.0",x=1,y=2,z=4,A=8,B=16,C=32,D=64,E=128,F=256,G=30,H="...",I=150,J=16,K=0,L=1,M=2,N="Expected a function",O="__lodash_placeholder__",P="[object Arguments]",Q="[object Array]",R="[object Boolean]",S="[object Date]",T="[object Error]",U="[object Function]",V="[object Map]",W="[object Number]",X="[object Object]",Y="[object RegExp]",Z="[object Set]",$="[object String]",_="[object WeakMap]",aa="[object ArrayBuffer]",ba="[object Float32Array]",ca="[object Float64Array]",da="[object Int8Array]",ea="[object Int16Array]",fa="[object Int32Array]",ga="[object Uint8Array]",ha="[object Uint8ClampedArray]",ia="[object Uint16Array]",ja="[object Uint32Array]",ka=/\b__p \+= '';/g,la=/\b(__p \+=) '' \+/g,ma=/(__e\(.*?\)|\b__t\)) \+\n'';/g,na=/&(?:amp|lt|gt|quot|#39|#96);/g,oa=/[&<>"'`]/g,pa=RegExp(na.source),qa=RegExp(oa.source),ra=/<%-([\s\S]+?)%>/g,sa=/<%([\s\S]+?)%>/g,ta=/<%=([\s\S]+?)%>/g,ua=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,va=/\w*$/,wa=/^\s*function[ \n\r\t]+\w/,xa=/^0[xX]/,ya=/^\[object .+?Constructor\]$/,za=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Aa=/($^)/,Ba=/[.*+?^${}()|[\]\/\\]/g,Ca=RegExp(Ba.source),Da=/\bthis\b/,Ea=/['\n\r\u2028\u2029\\]/g,Fa=function(){var a="[A-Z\\xc0-\\xd6\\xd8-\\xde]",b="[a-z\\xdf-\\xf6\\xf8-\\xff]+";return RegExp(a+"{2,}(?="+a+b+")|"+a+"?"+b+"|"+a+"+|[0-9]+","g")}(),Ga=" \f \ufeff\n\r\u2028\u2029 ",Ha=["Array","ArrayBuffer","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Math","Number","Object","RegExp","Set","String","_","clearTimeout","document","isFinite","parseInt","setTimeout","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","window","WinRTError"],Ia=-1,Ja={};Ja[ba]=Ja[ca]=Ja[da]=Ja[ea]=Ja[fa]=Ja[ga]=Ja[ha]=Ja[ia]=Ja[ja]=!0,Ja[P]=Ja[Q]=Ja[aa]=Ja[R]=Ja[S]=Ja[T]=Ja[U]=Ja[V]=Ja[W]=Ja[X]=Ja[Y]=Ja[Z]=Ja[$]=Ja[_]=!1;var Ka={};Ka[P]=Ka[Q]=Ka[aa]=Ka[R]=Ka[S]=Ka[ba]=Ka[ca]=Ka[da]=Ka[ea]=Ka[fa]=Ka[W]=Ka[X]=Ka[Y]=Ka[$]=Ka[ga]=Ka[ha]=Ka[ia]=Ka[ja]=!0,Ka[T]=Ka[U]=Ka[V]=Ka[Z]=Ka[_]=!1;var La={leading:!1,maxWait:0,trailing:!1},Ma={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss"},Na={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Oa={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Pa={"function":!0,object:!0},Qa={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Ra=Pa[typeof window]&&window!==(this&&this.window)?window:this,Sa=Pa[typeof exports]&&exports&&!exports.nodeType&&exports,Ta=Pa[typeof module]&&module&&!module.nodeType&&module,Ua=Sa&&Ta&&"object"==typeof global&&global;!Ua||Ua.global!==Ua&&Ua.window!==Ua&&Ua.self!==Ua||(Ra=Ua);var Va=Ta&&Ta.exports===Sa&&Sa,Wa=u();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(Ra._=Wa,define(function(){return Wa})):Sa&&Ta?Va?(Ta.exports=Wa)._=Wa:Sa._=Wa:Ra._=Wa}.call(this),function(a,b){if("function"==typeof define&&define.amd)define(["../../.","jquery","exports"],function(c,d,e){a.Backbone=b(a,e,c,d)});else if("undefined"!=typeof exports){var c=require("underscore");b(a,exports,c)}else a.Backbone=b(a,{},a._,a.jQuery||a.Zepto||a.ender||a.$)}(this,function(a,b,c,d){var e=a.Backbone,f=[],g=(f.push,f.slice);f.splice;b.VERSION="1.1.2",b.$=d,b.noConflict=function(){return a.Backbone=e,this},b.emulateHTTP=!1,b.emulateJSON=!1;var h=b.Events={on:function(a,b,c){if(!j(this,"on",a,[b,c])||!b)return this;this._events||(this._events={});var d=this._events[a]||(this._events[a]=[]);return d.push({callback:b,context:c,ctx:c||this}),this},once:function(a,b,d){if(!j(this,"once",a,[b,d])||!b)return this;var e=this,f=c.once(function(){e.off(a,f),b.apply(this,arguments)});return f._callback=b,this.on(a,f,d)},off:function(a,b,d){var e,f,g,h,i,k,l,m;if(!this._events||!j(this,"off",a,[b,d]))return this;if(!a&&!b&&!d)return this._events=void 0,this;for(h=a?[a]:c.keys(this._events),i=0,k=h.length;k>i;i++)if(a=h[i],g=this._events[a]){if(this._events[a]=e=[],b||d)for(l=0,m=g.length;m>l;l++)f=g[l],(b&&b!==f.callback&&b!==f.callback._callback||d&&d!==f.context)&&e.push(f);e.length||delete this._events[a]}return this},trigger:function(a){if(!this._events)return this;var b=g.call(arguments,1);if(!j(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;return c&&k(c,b),d&&k(d,arguments),this},stopListening:function(a,b,d){var e=this._listeningTo;if(!e)return this;var f=!b&&!d;d||"object"!=typeof b||(d=this),a&&((e={})[a._listenId]=a);for(var g in e)a=e[g],a.off(b,d,this),(f||c.isEmpty(a._events))&&delete this._listeningTo[g];return this}},i=/\s+/,j=function(a,b,c,d){if(!c)return!0;if("object"==typeof c){for(var e in c)a[b].apply(a,[e,c[e]].concat(d));return!1}if(i.test(c)){for(var f=c.split(i),g=0,h=f.length;h>g;g++)a[b].apply(a,[f[g]].concat(d));return!1}return!0},k=function(a,b){var c,d=-1,e=a.length,f=b[0],g=b[1],h=b[2];switch(b.length){case 0:for(;++d<e;)(c=a[d]).callback.call(c.ctx);return;case 1:for(;++d<e;)(c=a[d]).callback.call(c.ctx,f);return;case 2:for(;++d<e;)(c=a[d]).callback.call(c.ctx,f,g);return;case 3:for(;++d<e;)(c=a[d]).callback.call(c.ctx,f,g,h);return;default:for(;++d<e;)(c=a[d]).callback.apply(c.ctx,b);return}},l={listenTo:"on",listenToOnce:"once"};c.each(l,function(a,b){h[b]=function(b,d,e){var f=this._listeningTo||(this._listeningTo={}),g=b._listenId||(b._listenId=c.uniqueId("l"));return f[g]=b,e||"object"!=typeof d||(e=this),b[a](d,e,this),this}}),h.bind=h.on,h.unbind=h.off,c.extend(b,h);var m=b.Model=function(a,b){var d=a||{};b||(b={}),this.cid=c.uniqueId("c"),this.attributes={},b.collection&&(this.collection=b.collection),b.parse&&(d=this.parse(d,b)||{}),d=c.defaults({},d,c.result(this,"defaults")),this.set(d,b),this.changed={},this.initialize.apply(this,arguments)};c.extend(m.prototype,h,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(a){return c.clone(this.attributes)},sync:function(){return b.sync.apply(this,arguments)},get:function(a){return this.attributes[a]},escape:function(a){return c.escape(this.get(a))},has:function(a){return null!=this.get(a)},set:function(a,b,d){var e,f,g,h,i,j,k,l;if(null==a)return this;if("object"==typeof a?(f=a,d=b):(f={})[a]=b,d||(d={}),!this._validate(f,d))return!1;g=d.unset,i=d.silent,h=[],j=this._changing,this._changing=!0,j||(this._previousAttributes=c.clone(this.attributes),this.changed={}),l=this.attributes,k=this._previousAttributes,this.idAttribute in f&&(this.id=f[this.idAttribute]);for(e in f)b=f[e],c.isEqual(l[e],b)||h.push(e),c.isEqual(k[e],b)?delete this.changed[e]:this.changed[e]=b,g?delete l[e]:l[e]=b;if(!i){h.length&&(this._pending=d);for(var m=0,n=h.length;n>m;m++)this.trigger("change:"+h[m],this,l[h[m]],d)}if(j)return this;if(!i)for(;this._pending;)d=this._pending,this._pending=!1,this.trigger("change",this,d);return this._pending=!1,this._changing=!1,this},unset:function(a,b){return this.set(a,void 0,c.extend({},b,{unset:!0}))},clear:function(a){var b={};for(var d in this.attributes)b[d]=void 0;return this.set(b,c.extend({},a,{unset:!0}))},hasChanged:function(a){return null==a?!c.isEmpty(this.changed):c.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?c.clone(this.changed):!1;var b,d=!1,e=this._changing?this._previousAttributes:this.attributes;for(var f in a)c.isEqual(e[f],b=a[f])||((d||(d={}))[f]=b);return d},previous:function(a){return null!=a&&this._previousAttributes?this._previousAttributes[a]:null},previousAttributes:function(){return c.clone(this._previousAttributes)},fetch:function(a){a=a?c.clone(a):{},void 0===a.parse&&(a.parse=!0);var b=this,d=a.success;return a.success=function(c){return b.set(b.parse(c,a),a)?(d&&d(b,c,a),void b.trigger("sync",b,c,a)):!1},L(this,a),this.sync("read",this,a)},save:function(a,b,d){var e,f,g,h=this.attributes;if(null==a||"object"==typeof a?(e=a,d=b):(e={})[a]=b,d=c.extend({validate:!0},d),e&&!d.wait){if(!this.set(e,d))return!1}else if(!this._validate(e,d))return!1;e&&d.wait&&(this.attributes=c.extend({},h,e)),void 0===d.parse&&(d.parse=!0);var i=this,j=d.success;return d.success=function(a){i.attributes=h;var b=i.parse(a,d);return d.wait&&(b=c.extend(e||{},b)),c.isObject(b)&&!i.set(b,d)?!1:(j&&j(i,a,d),void i.trigger("sync",i,a,d))},L(this,d),f=this.isNew()?"create":d.patch?"patch":"update","patch"===f&&(d.attrs=e),g=this.sync(f,this,d),e&&d.wait&&(this.attributes=h),g},destroy:function(a){a=a?c.clone(a):{};var b=this,d=a.success,e=function(){b.trigger("destroy",b,b.collection,a)};if(a.success=function(c){(a.wait||b.isNew())&&e(),d&&d(b,c,a),b.isNew()||b.trigger("sync",b,c,a)},this.isNew())return a.success(),!1;L(this,a);var f=this.sync("delete",this,a);return a.wait||e(),f},url:function(){var a=c.result(this,"urlRoot")||c.result(this.collection,"url")||K();return this.isNew()?a:a.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(a,b){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(a){return this._validate({},c.extend(a||{},{validate:!0}))},_validate:function(a,b){if(!b.validate||!this.validate)return!0;a=c.extend({},this.attributes,a);var d=this.validationError=this.validate(a,b)||null;return d?(this.trigger("invalid",this,d,c.extend(b,{validationError:d})),!1):!0}});var n=["keys","values","pairs","invert","pick","omit"];c.each(n,function(a){m.prototype[a]=function(){var b=g.call(arguments);return b.unshift(this.attributes),c[a].apply(c,b)}});var o=b.Collection=function(a,b){b||(b={}),b.model&&(this.model=b.model),void 0!==b.comparator&&(this.comparator=b.comparator),this._reset(),this.initialize.apply(this,arguments),a&&this.reset(a,c.extend({silent:!0},b))},p={add:!0,remove:!0,merge:!0},q={add:!0,remove:!1};c.extend(o.prototype,h,{model:m,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return b.sync.apply(this,arguments)},add:function(a,b){return this.set(a,c.extend({merge:!1},b,q))},remove:function(a,b){var d=!c.isArray(a);a=d?[a]:c.clone(a),b||(b={});var e,f,g,h;for(e=0,f=a.length;f>e;e++)h=a[e]=this.get(a[e]),h&&(delete this._byId[h.id],delete this._byId[h.cid],g=this.indexOf(h),this.models.splice(g,1),this.length--,b.silent||(b.index=g,h.trigger("remove",h,this,b)),this._removeReference(h,b));return d?a[0]:a},set:function(a,b){b=c.defaults({},b,p),b.parse&&(a=this.parse(a,b));var d=!c.isArray(a);a=d?a?[a]:[]:c.clone(a);var e,f,g,h,i,j,k,l=b.at,n=this.model,o=this.comparator&&null==l&&b.sort!==!1,q=c.isString(this.comparator)?this.comparator:null,r=[],s=[],t={},u=b.add,v=b.merge,w=b.remove,x=!o&&u&&w?[]:!1;for(e=0,f=a.length;f>e;e++){if(i=a[e]||{},g=i instanceof m?h=i:i[n.prototype.idAttribute||"id"],j=this.get(g))w&&(t[j.cid]=!0),v&&(i=i===h?h.attributes:i,b.parse&&(i=j.parse(i,b)),j.set(i,b),o&&!k&&j.hasChanged(q)&&(k=!0)),a[e]=j;else if(u){if(h=a[e]=this._prepareModel(i,b),!h)continue;r.push(h),this._addReference(h,b)}h=j||h,!x||!h.isNew()&&t[h.id]||x.push(h),t[h.id]=!0}if(w){for(e=0,f=this.length;f>e;++e)t[(h=this.models[e]).cid]||s.push(h);s.length&&this.remove(s,b)}if(r.length||x&&x.length)if(o&&(k=!0),this.length+=r.length,null!=l)for(e=0,f=r.length;f>e;e++)this.models.splice(l+e,0,r[e]);else{x&&(this.models.length=0);var y=x||r;for(e=0,f=y.length;f>e;e++)this.models.push(y[e])}if(k&&this.sort({silent:!0}),!b.silent){for(e=0,f=r.length;f>e;e++)(h=r[e]).trigger("add",h,this,b);(k||x&&x.length)&&this.trigger("sort",this,b)}return d?a[0]:a},reset:function(a,b){b||(b={});for(var d=0,e=this.models.length;e>d;d++)this._removeReference(this.models[d],b);return b.previousModels=this.models,this._reset(),a=this.add(a,c.extend({silent:!0},b)),b.silent||this.trigger("reset",this,b),a},push:function(a,b){return this.add(a,c.extend({at:this.length},b))},pop:function(a){var b=this.at(this.length-1);return this.remove(b,a),b},unshift:function(a,b){return this.add(a,c.extend({at:0},b))},shift:function(a){var b=this.at(0);return this.remove(b,a),b},slice:function(){return g.apply(this.models,arguments)},get:function(a){return null==a?void 0:this._byId[a]||this._byId[a.id]||this._byId[a.cid]},at:function(a){return this.models[a]},where:function(a,b){return c.isEmpty(a)?b?void 0:[]:this[b?"find":"filter"](function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},findWhere:function(a){return this.where(a,!0)},sort:function(a){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");return a||(a={}),c.isString(this.comparator)||1===this.comparator.length?this.models=this.sortBy(this.comparator,this):this.models.sort(c.bind(this.comparator,this)),a.silent||this.trigger("sort",this,a),this},pluck:function(a){return c.invoke(this.models,"get",a)},fetch:function(a){a=a?c.clone(a):{},void 0===a.parse&&(a.parse=!0);var b=a.success,d=this;return a.success=function(c){var e=a.reset?"reset":"set";d[e](c,a),b&&b(d,c,a),d.trigger("sync",d,c,a)},L(this,a),this.sync("read",this,a)},create:function(a,b){if(b=b?c.clone(b):{},!(a=this._prepareModel(a,b)))return!1;b.wait||this.add(a,b);var d=this,e=b.success;return b.success=function(a,c){b.wait&&d.add(a,b),e&&e(a,c,b)},a.save(null,b),a},parse:function(a,b){return a},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0,this.models=[],this._byId={}},_prepareModel:function(a,b){if(a instanceof m)return a;b=b?c.clone(b):{},b.collection=this;var d=new this.model(a,b);return d.validationError?(this.trigger("invalid",this,d.validationError,b),!1):d},_addReference:function(a,b){this._byId[a.cid]=a,null!=a.id&&(this._byId[a.id]=a),a.collection||(a.collection=this),a.on("all",this._onModelEvent,this)},_removeReference:function(a,b){this===a.collection&&delete a.collection,a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"!==a&&"remove"!==a||c===this)&&("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});var r=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];c.each(r,function(a){o.prototype[a]=function(){var b=g.call(arguments);return b.unshift(this.models),c[a].apply(c,b)}});var s=["groupBy","countBy","sortBy","indexBy"];c.each(s,function(a){o.prototype[a]=function(b,d){var e=c.isFunction(b)?b:function(a){return a.get(b)};return c[a](this.models,e,d)}});var t=b.View=function(a){this.cid=c.uniqueId("view"),a||(a={}),c.extend(this,c.pick(a,v)),this._ensureElement(),this.initialize.apply(this,arguments),this.delegateEvents()},u=/^(\S+)\s*(.*)$/,v=["model","collection","el","id","attributes","className","tagName","events"];c.extend(t.prototype,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){return this.$el.remove(),this.stopListening(),this},setElement:function(a,c){return this.$el&&this.undelegateEvents(),this.$el=a instanceof b.$?a:b.$(a),this.el=this.$el[0],c!==!1&&this.delegateEvents(),this},delegateEvents:function(a){if(!a&&!(a=c.result(this,"events")))return this;this.undelegateEvents();for(var b in a){var d=a[b];if(c.isFunction(d)||(d=this[a[b]]),d){var e=b.match(u),f=e[1],g=e[2];d=c.bind(d,this),f+=".delegateEvents"+this.cid,""===g?this.$el.on(f,d):this.$el.on(f,g,d)}}return this},undelegateEvents:function(){return this.$el.off(".delegateEvents"+this.cid),this},_ensureElement:function(){if(this.el)this.setElement(c.result(this,"el"),!1);else{var a=c.extend({},c.result(this,"attributes"));this.id&&(a.id=c.result(this,"id")),this.className&&(a["class"]=c.result(this,"className"));var d=b.$("<"+c.result(this,"tagName")+">").attr(a);this.setElement(d,!1)}}}),b.sync=function(a,d,e){var f=x[a];c.defaults(e||(e={}),{emulateHTTP:b.emulateHTTP,emulateJSON:b.emulateJSON});var g={type:f,dataType:"json"};if(e.url||(g.url=c.result(d,"url")||K()),null!=e.data||!d||"create"!==a&&"update"!==a&&"patch"!==a||(g.contentType="application/json",g.data=JSON.stringify(e.attrs||d.toJSON(e))),e.emulateJSON&&(g.contentType="application/x-www-form-urlencoded",g.data=g.data?{model:g.data}:{}),e.emulateHTTP&&("PUT"===f||"DELETE"===f||"PATCH"===f)){g.type="POST",e.emulateJSON&&(g.data._method=f);var h=e.beforeSend;e.beforeSend=function(a){return a.setRequestHeader("X-HTTP-Method-Override",f),h?h.apply(this,arguments):void 0}}"GET"===g.type||e.emulateJSON||(g.processData=!1),"PATCH"===g.type&&w&&(g.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")});var i=e.xhr=b.ajax(c.extend(g,e));return d.trigger("request",d,i,e),i};var w=!("undefined"==typeof window||!window.ActiveXObject||window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent),x={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};b.ajax=function(){return b.$.ajax.apply(b.$,arguments)};var y=b.Router=function(a){a||(a={}),a.routes&&(this.routes=a.routes),this._bindRoutes(),this.initialize.apply(this,arguments)},z=/\((.*?)\)/g,A=/(\(\?)?:\w+/g,B=/\*\w+/g,C=/[\-{}\[\]+?.,\\\^$|#\s]/g;c.extend(y.prototype,h,{initialize:function(){},route:function(a,d,e){c.isRegExp(a)||(a=this._routeToRegExp(a)),c.isFunction(d)&&(e=d,d=""),e||(e=this[d]);var f=this;return b.history.route(a,function(c){var g=f._extractParameters(a,c);f.execute(e,g),f.trigger.apply(f,["route:"+d].concat(g)),f.trigger("route",d,g),b.history.trigger("route",f,d,g)}),this},execute:function(a,b){a&&a.apply(this,b)},navigate:function(a,c){return b.history.navigate(a,c),this},_bindRoutes:function(){if(this.routes){this.routes=c.result(this,"routes");for(var a,b=c.keys(this.routes);null!=(a=b.pop());)this.route(a,this.routes[a])}},_routeToRegExp:function(a){return a=a.replace(C,"\\$&").replace(z,"(?:$1)?").replace(A,function(a,b){return b?a:"([^/?]+)"}).replace(B,"([^?]*?)"),new RegExp("^"+a+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(a,b){var d=a.exec(b).slice(1);return c.map(d,function(a,b){return b===d.length-1?a||null:a?decodeURIComponent(a):null})}});var D=b.History=function(){this.handlers=[],c.bindAll(this,"checkUrl"),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)},E=/^[#\/]|\s+$/g,F=/^\/+|\/+$/g,G=/msie [\w.]+/,H=/\/$/,I=/#.*$/;D.started=!1,c.extend(D.prototype,h,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(a){var b=(a||this).location.href.match(/#(.*)$/);return b?b[1]:""},getFragment:function(a,b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){a=decodeURI(this.location.pathname+this.location.search);var c=this.root.replace(H,"");a.indexOf(c)||(a=a.slice(c.length))}else a=this.getHash();return a.replace(E,"")},start:function(a){if(D.started)throw new Error("Backbone.history has already been started");D.started=!0,this.options=c.extend({root:"/"},this.options,a),this.root=this.options.root,this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var d=this.getFragment(),e=document.documentMode,f=G.exec(navigator.userAgent.toLowerCase())&&(!e||7>=e);if(this.root=("/"+this.root+"/").replace(F,"/"),f&&this._wantsHashChange){var g=b.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=g.hide().appendTo("body")[0].contentWindow,this.navigate(d); -}this._hasPushState?b.$(window).on("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!f?b.$(window).on("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),this.fragment=d;var h=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot())return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+"#"+this.fragment),!0;this._hasPushState&&this.atRoot()&&h.hash&&(this.fragment=this.getHash().replace(E,""),this.history.replaceState({},document.title,this.root+this.fragment))}return this.options.silent?void 0:this.loadUrl()},stop:function(){b.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),D.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(a){var b=this.getFragment();return b===this.fragment&&this.iframe&&(b=this.getFragment(this.getHash(this.iframe))),b===this.fragment?!1:(this.iframe&&this.navigate(b),void this.loadUrl())},loadUrl:function(a){return a=this.fragment=this.getFragment(a),c.any(this.handlers,function(b){return b.route.test(a)?(b.callback(a),!0):void 0})},navigate:function(a,b){if(!D.started)return!1;b&&b!==!0||(b={trigger:!!b});var c=this.root+(a=this.getFragment(a||""));if(a=a.replace(I,""),this.fragment!==a){if(this.fragment=a,""===a&&"/"!==c&&(c=c.slice(0,-1)),this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,c);else{if(!this._wantsHashChange)return this.location.assign(c);this._updateHash(this.location,a,b.replace),this.iframe&&a!==this.getFragment(this.getHash(this.iframe))&&(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,a,b.replace))}return b.trigger?this.loadUrl(a):void 0}},_updateHash:function(a,b,c){if(c){var d=a.href.replace(/(javascript:|#).*$/,"");a.replace(d+"#"+b)}else a.hash="#"+b}}),b.history=new D;var J=function(a,b){var d,e=this;d=a&&c.has(a,"constructor")?a.constructor:function(){return e.apply(this,arguments)},c.extend(d,e,b);var f=function(){this.constructor=d};return f.prototype=e.prototype,d.prototype=new f,a&&c.extend(d.prototype,a),d.__super__=e.prototype,d};m.extend=o.extend=y.extend=t.extend=D.extend=J;var K=function(){throw new Error('A "url" property or function must be specified')},L=function(a,b){var c=b.error;b.error=function(d){c&&c(a,d,b),a.trigger("error",a,d,b)}};return b}),"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(a){return 10>a?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g,h=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,g=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;f>c;c+=1)g[c]=str(c,i)||"null";return e=0===g.length?"[]":gap?"[\n"+gap+g.join(",\n"+gap)+"\n"+h+"]":"["+g.join(",")+"]",gap=h,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;f>c;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));return e=0===g.length?"{}":gap?"{\n"+gap+g.join(",\n"+gap)+"\n"+h+"}":"{"+g.join(",")+"}",gap=h,e}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;c>d;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),function(a){"function"==typeof require&&"undefined"!=typeof module&&module.exports?module.exports=a(require("underscore")):"function"==typeof define?define(["underscore"],a):this.Cocktail=a(_)}(function(a){var b={};b.mixins={},b.mixin=function(c){var d=a.chain(arguments).toArray().rest().flatten().value(),e=c.prototype||c,f={};return a.each(d,function(c){a.isString(c)&&(c=b.mixins[c]),a.each(c,function(b,c){if(a.isFunction(b)){if(e[c]===b)return;e[c]&&(f[c]=f.hasOwnProperty(c)?f[c]:[e[c]],f[c].push(b)),e[c]=b}else a.isArray(b)?e[c]=a.union(b,e[c]||[]):a.isObject(b)?e[c]=a.extend({},b,e[c]||{}):c in e||(e[c]=b)})}),a.each(f,function(b,c){e[c]=function(){var c,d=this,e=arguments;return a.each(b,function(b){var f=a.isFunction(b)?b.apply(d,e):b;c="undefined"==typeof f?c:f}),c}}),c};var c;return b.patch=function(d){c=d.Model.extend;var e=function(a,d){var e=c.call(this,a,d),f=e.prototype.mixins;return f&&e.prototype.hasOwnProperty("mixins")&&b.mixin(e,f),e};a.each([d.Model,d.Collection,d.Router,d.View],function(c){c.mixin=function(){b.mixin(this,a.toArray(arguments))},c.extend=e})},b.unpatch=function(b){a.each([b.Model,b.Collection,b.Router,b.View],function(a){a.mixin=void 0,a.extend=c})},b});var saveAs=saveAs||function(a){"use strict";if(!("undefined"==typeof a||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=b.createElementNS("http://www.w3.org/1999/xhtml","a"),e="download"in d,f=function(a){var b=new MouseEvent("click");a.dispatchEvent(b)},g=/constructor/i.test(a.HTMLElement)||a.safari,h=/CriOS\/[\d]+/.test(navigator.userAgent),i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=4e4,l=function(a){var b=function(){"string"==typeof a?c().revokeObjectURL(a):a.remove()};setTimeout(b,k)},m=function(a,b,c){b=[].concat(b);for(var d=b.length;d--;){var e=a["on"+b[d]];if("function"==typeof e)try{e.call(a,c||a)}catch(f){i(f)}}},n=function(a){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob([String.fromCharCode(65279),a],{type:a.type}):a},o=function(b,i,k){k||(b=n(b));var o,p=this,q=b.type,r=q===j,s=function(){m(p,"writestart progress write writeend".split(" "))},t=function(){if((h||r&&g)&&a.FileReader){var d=new FileReader;return d.onloadend=function(){var b=h?d.result:d.result.replace(/^data:[^;]*;/,"data:attachment/file;"),c=a.open(b,"_blank");c||(a.location.href=b),b=void 0,p.readyState=p.DONE,s()},d.readAsDataURL(b),void(p.readyState=p.INIT)}if(o||(o=c().createObjectURL(b)),r)a.location.href=o;else{var e=a.open(o,"_blank");e||(a.location.href=o)}p.readyState=p.DONE,s(),l(o)};return p.readyState=p.INIT,e?(o=c().createObjectURL(b),void setTimeout(function(){d.href=o,d.download=i,f(d),s(),l(o),p.readyState=p.DONE})):void t()},p=o.prototype,q=function(a,b,c){return new o(a,b||a.name||"download",c)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(a,b,c){return b=b||a.name||"download",c||(a=n(a)),navigator.msSaveOrOpenBlob(a,b)}:(p.abort=function(){},p.readyState=p.INIT=0,p.WRITING=1,p.DONE=2,p.error=p.onwritestart=p.onprogress=p.onwrite=p.onabort=p.onerror=p.onwriteend=null,q)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define("FileSaver.js",function(){return saveAs}),function(a,b){if("object"==typeof exports)module.exports=b(require("underscore"),require("backbone"));else if("function"==typeof define&&define.amd)define(["underscore","backbone"],b);else{for(var c="FilteredCollection",d=c.split("."),e=a,f=0;f<d.length-1;f++)void 0===e[d[f]]&&(e[d[f]]={}),e=e[d[f]];e[d[d.length-1]]=b(a._,a.Backbone)}}(this,function(a,b){function c(c){return{underscore:a,backbone:b}[c]}var d=function(a){function b(a){var c=b.cache[a];if(!c){var d={};c=b.cache[a]={id:a,exports:d},b.modules[a].call(d,c,d)}return c.exports}return b.cache=[],b.modules=[function(a,d){function e(){this._filterResultCache={}}function f(a){for(var b in this._filterResultCache)this._filterResultCache.hasOwnProperty(b)&&delete this._filterResultCache[b][a]}function g(a,b){this._filters[a]&&f.call(this,a),this._filters[a]=b,this.trigger("filtered:add",a)}function h(a){delete this._filters[a],f.call(this,a),this.trigger("filtered:remove",a)}function i(a){this._filterResultCache[a.cid]||(this._filterResultCache[a.cid]={});var b=this._filterResultCache[a.cid];for(var c in this._filters)if(this._filters.hasOwnProperty(c)&&(b.hasOwnProperty(c)||(b[c]=this._filters[c].fn(a)),!b[c]))return!1;return!0}function j(){var a=[];this._superset&&(a=this._superset.filter(p.bind(i,this))),this._collection.reset(a),this.length=this._collection.length}function k(a){if(this._filterResultCache[a.cid]={},i.call(this,a)){if(!this._collection.get(a.cid)){for(var b=this.superset().indexOf(a),c=null,d=b-1;d>=0;d-=1)if(this.contains(this.superset().at(d))){c=this.indexOf(this.superset().at(d))+1;break}c=c||0,this._collection.add(a,{at:c})}}else this._collection.get(a.cid)&&this._collection.remove(a);this.length=this._collection.length}function l(a){this._filterResultCache[a.cid]={},i.call(this,a)||this._collection.get(a.cid)&&this._collection.remove(a)}function m(a,b,c){"change:"===a.slice(0,7)&&l.call(this,arguments[1])}function n(a){this.contains(a)&&this._collection.remove(a),this.length=this._collection.length}function o(a){this._superset=a,this._collection=new q.Collection(a.toArray()),r(this._collection,this),this.resetFilters(),this.listenTo(this._superset,"reset sort",j),this.listenTo(this._superset,"add change",k),this.listenTo(this._superset,"remove",n),this.listenTo(this._superset,"all",m)}var p=c("underscore"),q=c("backbone"),r=b(1),s=b(2),t={defaultFilterName:"__default",filterBy:function(a,b){return b||(b=a,a=this.defaultFilterName),g.call(this,a,s(b)),j.call(this),this},removeFilter:function(a){return a||(a=this.defaultFilterName),h.call(this,a),j.call(this),this},resetFilters:function(){return this._filters={},e.call(this),this.trigger("filtered:reset"),j.call(this),this},superset:function(){return this._superset},refilter:function(a){return"object"==typeof a&&a.cid?k.call(this,a):(e.call(this),j.call(this)),this},getFilters:function(){return p.keys(this._filters)},hasFilter:function(a){return p.contains(this.getFilters(),a)},destroy:function(){this.stopListening(),this._collection.reset([]),this._superset=this._collection,this.length=0,this.trigger("filtered:destroy")}};p.extend(o.prototype,t,q.Events),a.exports=o},function(a,b){function d(a,b){function c(){b.length=a.length}function d(c){var d=e.toArray(arguments),f="change"===c||"change:"===c.slice(0,7);"reset"===c&&(b.models=a.models),e.contains(h,c)?(e.contains(["add","remove","destroy"],c)?d[2]=b:e.contains(["reset","sort"],c)&&(d[1]=b),b.trigger.apply(this,d)):f&&b.contains(d[1])&&b.trigger.apply(this,d)}var i={};return e.each(e.functions(f.Collection.prototype),function(b){e.contains(g,b)||(i[b]=function(){return a[b].apply(a,arguments)})}),e.extend(b,f.Events,i),b.listenTo(a,"all",c),b.listenTo(a,"all",d),b.models=a.models,c(),b}var e=c("underscore"),f=c("backbone"),g=["_onModelEvent","_prepareModel","_removeReference","_reset","add","initialize","sync","remove","reset","set","push","pop","unshift","shift","sort","parse","fetch","create","model","off","on","listenTo","listenToOnce","bind","trigger","once","stopListening"],h=["add","remove","reset","sort","destroy","sync","request","error"];a.exports=d},function(a,b){function d(a,b){return function(c){return c.get(a)===b}}function e(a,b){return function(c){return b(c.get(a))}}function f(a,b){return i.isArray(b)||(b=null),{fn:a,keys:b}}function g(a){var b=i.keys(a),c=i.map(b,function(b){var c=a[b];return i.isFunction(c)?e(b,c):d(b,c)}),g=function(a){for(var b=0;b<c.length;b++)if(!c[b](a))return!1;return!0};return f(g,b)}function h(a,b){return i.isFunction(a)?f(a,b):i.isObject(a)?g(a):void 0}var i=c("underscore");a.exports=h}],b(0)}();return d}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.ChildViewContainer;return a.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;return this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength(),this},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;return a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength(),this},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck","reduce"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(a,b),a.ChildViewContainer.VERSION="0.1.6",a.ChildViewContainer.noConflict=function(){return a.ChildViewContainer=c,this},a.ChildViewContainer}),function(a,b){"function"==typeof define&&define.amd?define(["underscore","backbone","jquery"],function(c,d,e){return a.Backbone=b(c,d,e)}):"undefined"!=typeof exports&&"undefined"!=typeof require?module.exports=b(require("underscore"),require("backbone"),require("jquery")):a.Backbone=b(a._,a.Backbone,a.jQuery)}(this,function(a,b,c){function d(b,d){if(b&&a.isObject(b)){if(a.isFunction(b.getCacheKey))return b.getCacheKey(d);b=d&&d.url?d.url:a.isFunction(b.url)?b.url():b.url}else if(a.isFunction(b))return b(d);return d&&d.data?"string"==typeof d.data?b+"?"+d.data:b+"?"+c.param(d.data):b}function e(a,c,d){c=c||{};var e=b.fetchCache.getCacheKey(a,c),f=!1,g=c.lastSync||(new Date).getTime(),h=!1;e&&c.cache!==!1&&(c.cache||c.prefill)&&(c.expires!==!1&&(f=(new Date).getTime()+1e3*(c.expires||300)),c.prefillExpires!==!1&&(h=(new Date).getTime()+1e3*(c.prefillExpires||300)),b.fetchCache._cache[e]={expires:f,lastSync:g,prefillExpires:h,value:d},b.fetchCache.setLocalStorage())}function f(c,e){return a.isFunction(c)?c=c():c&&a.isObject(c)&&(c=d(c,e)),b.fetchCache._cache[c]}function g(a,b){return f(a).lastSync}function h(c,e){a.isFunction(c)?c=c():c&&a.isObject(c)&&(c=d(c,e)),delete b.fetchCache._cache[c],b.fetchCache.setLocalStorage()}function i(){b.fetchCache._cache={}}function j(){if(n&&b.fetchCache.localStorage)try{localStorage.setItem(b.fetchCache.getLocalStorageKey(),JSON.stringify(b.fetchCache._cache))}catch(a){var c=a.code||a.number||a.message;if(22!==c&&1014!==c)throw a;this._deleteCacheWithPriority()}}function k(){if(n&&b.fetchCache.localStorage){var a=localStorage.getItem(b.fetchCache.getLocalStorageKey())||"{}";b.fetchCache._cache=JSON.parse(a)}}function l(a){return window.setTimeout(a,0)}var m={modelFetch:b.Model.prototype.fetch,modelSync:b.Model.prototype.sync,collectionFetch:b.Collection.prototype.fetch},n=function(){var a="undefined"!=typeof window.localStorage;if(a)try{localStorage.setItem("test_support","test_support"),localStorage.removeItem("test_support")}catch(b){a=!1}return a}();return b.fetchCache=b.fetchCache||{},b.fetchCache._cache=b.fetchCache._cache||{},b.fetchCache.enabled=!0,b.fetchCache.priorityFn=function(a,b){return a&&a.expires&&b&&b.expires?a.expires-b.expires:a},b.fetchCache._prioritize=function(){var b=a.values(this._cache).sort(this.priorityFn),c=a.indexOf(a.values(this._cache),b[0]);return a.keys(this._cache)[c]},b.fetchCache._deleteCacheWithPriority=function(){b.fetchCache._cache[this._prioritize()]=null,delete b.fetchCache._cache[this._prioritize()],b.fetchCache.setLocalStorage()},b.fetchCache.getLocalStorageKey=function(){return"backboneCache"},"undefined"==typeof b.fetchCache.localStorage&&(b.fetchCache.localStorage=!0),b.Model.prototype.fetch=function(d){function e(){return d.prefill&&(!d.prefillExpires||k)}function g(){d.parse&&(n=q.parse(n,d)),q.set(n,d),a.isFunction(d.prefillSuccess)&&d.prefillSuccess.call(p,q,n,d),q.trigger("cachesync",q,n,d),q.trigger("sync",q,n,d),e()?o.notifyWith(p,[q]):(a.isFunction(d.success)&&d.success.call(p,q,n,d),o.resolveWith(p,[q]))}if(!b.fetchCache.enabled)return m.modelFetch.apply(this,arguments);d=a.defaults(d||{},{parse:!0});var h=b.fetchCache.getCacheKey(this,d),i=f(h),j=!1,k=!1,n=!1,o=new c.Deferred,p=d.context||this,q=this;if(i&&(j=i.expires,j=j&&i.expires<(new Date).getTime(),k=i.prefillExpires,k=k&&i.prefillExpires<(new Date).getTime(),n=i.value),!j&&(d.cache||d.prefill)&&n&&(null==d.async&&(d.async=!0),d.async?l(g):g(),!e()))return o.promise();var r=m.modelFetch.apply(this,arguments);return"undefined"!=typeof r&&(r.done(a.bind(o.resolve,p,this)).done(a.bind(b.fetchCache.setCache,null,this,d)).fail(a.bind(o.reject,p,this)),o.abort=r.abort),o.promise()},b.Model.prototype.sync=function(a,c,d){if("read"===a||!b.fetchCache.enabled)return m.modelSync.apply(this,arguments);var e,f,g=c.collection,i=[];for(i.push(b.fetchCache.getCacheKey(c,d)),g&&i.push(b.fetchCache.getCacheKey(g)),e=0,f=i.length;f>e;e++)h(i[e]);return m.modelSync.apply(this,arguments)},b.Collection.prototype.fetch=function(d){function e(){return d.prefill&&(!d.prefillExpires||k)}function g(){q[d.reset?"reset":"set"](n,d),a.isFunction(d.prefillSuccess)&&d.prefillSuccess.call(p,q),q.trigger("cachesync",q,n,d),q.trigger("sync",q,n,d),e()?o.notifyWith(p,[q]):(a.isFunction(d.success)&&d.success.call(p,q,n,d),o.resolveWith(p,[q]))}if(!b.fetchCache.enabled)return m.collectionFetch.apply(this,arguments);d=a.defaults(d||{},{parse:!0});var h=b.fetchCache.getCacheKey(this,d),i=f(h),j=!1,k=!1,n=!1,o=new c.Deferred,p=d.context||this,q=this;if(i&&(j=i.expires,j=j&&i.expires<(new Date).getTime(),k=i.prefillExpires,k=k&&i.prefillExpires<(new Date).getTime(),n=i.value),!j&&(d.cache||d.prefill)&&n&&(null==d.async&&(d.async=!0),d.async?l(g):g(),!e()))return o.promise();var r=m.collectionFetch.apply(this,arguments);return"undefined"!=typeof r&&(r.done(a.bind(o.resolve,p,this)).done(a.bind(b.fetchCache.setCache,null,this,d)).fail(a.bind(o.reject,p,this)),o.abort=r.abort),o.promise()},k(),b.fetchCache._superMethods=m,b.fetchCache.setCache=e,b.fetchCache.getCache=f,b.fetchCache.getCacheKey=d,b.fetchCache.getLastSync=g,b.fetchCache.clearItem=h,b.fetchCache.reset=i,b.fetchCache.setLocalStorage=j,b.fetchCache.getLocalStorage=k,b}),function(a,b){"object"==typeof exports&&"function"==typeof require?module.exports=b(require("backbone")):"function"==typeof define&&define.amd?define(["backbone"],function(c){return b(c||a.Backbone)}):b(Backbone)}(this,function(a){function b(){return(65536*(1+Math.random())|0).toString(16).substring(1)}function c(){return b()+b()+"-"+b()+"-"+b()+"-"+b()+"-"+b()+b()+b()}function d(a){return a===Object(a)}function e(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1}function f(a,b){for(var c in b)a[c]=b[c];return a}function g(a,b){if(null==a)return void 0;var c=a[b];return"function"==typeof c?a[b]():c}return a.LocalStorage=window.Store=function(a,b){if(!this.localStorage)throw"Backbone.localStorage: Environment does not support localStorage.";this.name=a,this.serializer=b||{serialize:function(a){return d(a)?JSON.stringify(a):a},deserialize:function(a){return a&&JSON.parse(a)}};var c=this.localStorage().getItem(this.name);this.records=c&&c.split(",")||[]},f(a.LocalStorage.prototype,{save:function(){this.localStorage().setItem(this.name,this.records.join(","))},create:function(a){return a.id||0===a.id||(a.id=c(),a.set(a.idAttribute,a.id)),this.localStorage().setItem(this._itemName(a.id),this.serializer.serialize(a)),this.records.push(a.id.toString()),this.save(),this.find(a)},update:function(a){this.localStorage().setItem(this._itemName(a.id),this.serializer.serialize(a));var b=a.id.toString();return e(this.records,b)||(this.records.push(b),this.save()),this.find(a)},find:function(a){return this.serializer.deserialize(this.localStorage().getItem(this._itemName(a.id)))},findAll:function(){for(var a,b,c=[],d=0;d<this.records.length;d++)a=this.records[d],b=this.serializer.deserialize(this.localStorage().getItem(this._itemName(a))),null!=b&&c.push(b);return c},destroy:function(a){this.localStorage().removeItem(this._itemName(a.id));for(var b=a.id.toString(),c=0;c<this.records.length;c++)this.records[c]===b&&this.records.splice(c,1);return this.save(),a},localStorage:function(){return localStorage},_clear:function(){var a=this.localStorage(),b=new RegExp("^"+this.name+"-");a.removeItem(this.name);for(var c in a)b.test(c)&&a.removeItem(c);this.records.length=0},_storageSize:function(){return this.localStorage().length},_itemName:function(a){return this.name+"-"+a}}),a.LocalStorage.sync=window.Store.sync=a.localSync=function(b,c,d){var e,f,h=g(c,"localStorage")||g(c.collection,"localStorage"),i=a.$?a.$.Deferred&&a.$.Deferred():a.Deferred&&a.Deferred();try{switch(b){case"read":e=void 0!=c.id?h.find(c):h.findAll();break;case"create":e=h.create(c);break;case"update":e=h.update(c);break;case"delete":e=h.destroy(c)}}catch(j){f=22===j.code&&0===h._storageSize()?"Private browsing is unsupported":j.message}return e?(d&&d.success&&("0.9.10"===a.VERSION?d.success(c,e,d):d.success(e)),i&&i.resolve(e)):(f=f?f:"Record Not Found",d&&d.error&&("0.9.10"===a.VERSION?d.error(c,f,d):d.error(f)),i&&i.reject(f)),d&&d.complete&&d.complete(e),i&&i.promise()},a.ajaxSync=a.sync,a.getSyncMethod=function(b,c){var d=c&&c.ajaxSync;return d||!g(b,"localStorage")&&!g(b.collection,"localStorage")?a.ajaxSync:a.localSync},a.sync=function(b,c,d){return a.getSyncMethod(c,d).apply(this,[b,c,d])},a.LocalStorage}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(c,d){return a.Marionette=a.Mn=b(a,c,d)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(a,c,d)}else a.Marionette=a.Mn=b(a,a.Backbone,a._)}(this,function(a,b,c){"use strict";!function(a,b){var c=a.ChildViewContainer;return a.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;return this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength(),this},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;return a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength(),this},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(a,b),a.ChildViewContainer.VERSION="0.1.5",a.ChildViewContainer.noConflict=function(){return a.ChildViewContainer=c,this},a.ChildViewContainer}(b,c),function(a,b){var c=a.Wreqr,d=a.Wreqr={};return a.Wreqr.VERSION="1.3.1",a.Wreqr.noConflict=function(){return a.Wreqr=c,this},d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this)},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(b)return function(){var a=Array.prototype.slice.apply(arguments);return b.callback.apply(b.context,a)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,b),d.CommandStorage=function(){var c=function(a){this.options=a,this._commands={},b.isFunction(this.initialize)&&this.initialize(a)};return b.extend(c.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),c}(),d.Commands=function(a){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this);var c=Array.prototype.slice.call(arguments);a.Handlers.prototype.constructor.apply(this,c)},execute:function(a,b){a=arguments[0],b=Array.prototype.slice.call(arguments,1),this.hasHandler(a)?this.getHandler(a).apply(this,b):this.storage.addCommand(a,b)},_executeCommands:function(a,c,d){var e=this.storage.getCommands(a);b.each(e.instances,function(a){c.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var c,d=a.storageType||this.storageType;c=b.isFunction(d)?new d:d,this.storage=c}})}(d),d.RequestResponse=function(a){return a.Handlers.extend({request:function(){var a=arguments[0],b=Array.prototype.slice.call(arguments,1);return this.hasHandler(a)?this.getHandler(a).apply(this,b):void 0}})}(d),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,b),d.Channel=function(c){var d=function(b){this.vent=new a.Wreqr.EventAggregator,this.reqres=new a.Wreqr.RequestResponse,this.commands=new a.Wreqr.Commands,this.channelName=b};return b.extend(d.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(a,b){return this._connect("vent",a,b),this},connectCommands:function(a,b){return this._connect("commands",a,b),this},connectRequests:function(a,b){return this._connect("reqres",a,b),this},_connect:function(a,c,d){if(c){d=d||this;var e="vent"===a?"on":"setHandler";b.each(c,function(c,f){this[a][e](f,b.bind(c,d))},this)}}}),d}(d),d.radio=function(a){var c=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};b.extend(c.prototype,{channel:function(a){if(!a)throw new Error("Channel must receive a name");return this._getChannel(a)},_getChannel:function(b){var c=this._channels[b];return c||(c=new a.Channel(b),this._channels[b]=c),c},_proxyMethods:function(){b.each(["vent","commands","reqres"],function(a){b.each(d[a],function(b){this[a][b]=e(this,a,b)},this)},this)}});var d={vent:["on","off","trigger","once","stopListening","listenTo","listenToOnce"],commands:["execute","setHandler","setHandlers","removeHandler","removeAllHandlers"],reqres:["request","setHandler","setHandlers","removeHandler","removeAllHandlers"]},e=function(a,b,c){return function(d){var e=a._getChannel(d)[b],f=Array.prototype.slice.call(arguments,1);return e[c].apply(e,f)}};return new c}(d),a.Wreqr}(b,c);var d=a.Marionette,e=b.Marionette={};e.VERSION="2.3.1",e.noConflict=function(){return a.Marionette=d,this},b.Marionette=e,e.Deferred=b.$.Deferred,e.extend=b.Model.extend,e.isNodeAttached=function(a){return b.$.contains(document.documentElement,a)},e.getOption=function(a,b){return a&&b?a.options&&void 0!==a.options[b]?a.options[b]:a[b]:void 0},e.proxyGetOption=function(a){return e.getOption(this,a)},e._getValue=function(a,b,d){return c.isFunction(a)&&(a=a.apply(b,d)),a},e.normalizeMethods=function(a){return c.reduce(a,function(a,b,d){return c.isFunction(b)||(b=this[b]),b&&(a[d]=b),a},{},this)},e.normalizeUIString=function(a,b){return a.replace(/@ui\.[a-zA-Z_$0-9]*/g,function(a){return b[a.slice(4)]})},e.normalizeUIKeys=function(a,b){return c.reduce(a,function(a,c,d){var f=e.normalizeUIString(d,b);return a[f]=c,a},{})},e.normalizeUIValues=function(a,b){return c.each(a,function(d,f){c.isString(d)&&(a[f]=e.normalizeUIString(d,b))}),a},e.actAsCollection=function(a,b){var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];c.each(d,function(d){a[d]=function(){var a=c.values(c.result(this,b)),e=[a].concat(c.toArray(arguments));return c[d].apply(c,e)}})};var f=e.deprecate=function(a,b){c.isObject(a)&&(a=a.prev+" is going to be removed in the future. Please use "+a.next+" instead."+(a.url?" See: "+a.url:"")),void 0!==b&&b||f._cache[a]||(f._warn("Deprecation warning: "+a),f._cache[a]=!0)};f._warn="undefined"!=typeof console&&(console.warn||console.log)||function(){},f._cache={},e._triggerMethod=function(){function a(a,b,c){return c.toUpperCase()}var b=/(^|:)(\w)/gi;return function(d,e,f){var g=arguments.length<3;g&&(f=e,e=f[0]);var h,i="on"+e.replace(b,a),j=d[i];return c.isFunction(j)&&(h=j.apply(d,g?c.rest(f):f)),c.isFunction(d.trigger)&&(g+f.length>1?d.trigger.apply(d,g?f:[e].concat(c.rest(f,0))):d.trigger(e)),h}}(),e.triggerMethod=function(a){return e._triggerMethod(this,arguments)}, -e.triggerMethodOn=function(a){var b=c.isFunction(a.triggerMethod)?a.triggerMethod:e.triggerMethod;return b.apply(a,c.rest(arguments))},e.MonitorDOMRefresh=function(a){function b(){a._isShown=!0,f()}function d(){a._isRendered=!0,f()}function f(){a._isShown&&a._isRendered&&e.isNodeAttached(a.el)&&c.isFunction(a.triggerMethod)&&a.triggerMethod("dom:refresh")}a.on({show:b,render:d})},function(a){function b(b,d,e,f){var g=f.split(/\s+/);c.each(g,function(c){var f=b[c];if(!f)throw new a.Error('Method "'+c+'" was configured as an event handler, but does not exist.');b.listenTo(d,e,f)})}function d(a,b,c,d){a.listenTo(b,c,d)}function e(a,b,d,e){var f=e.split(/\s+/);c.each(f,function(c){var e=a[c];a.stopListening(b,d,e)})}function f(a,b,c,d){a.stopListening(b,c,d)}function g(b,d,e,f,g){if(d&&e){if(!c.isObject(e))throw new a.Error({message:"Bindings must be an object or function.",url:"marionette.functions.html#marionettebindentityevents"});e=a._getValue(e,b),c.each(e,function(a,e){c.isFunction(a)?f(b,d,e,a):g(b,d,e,a)})}}a.bindEntityEvents=function(a,c,e){g(a,c,e,d,b)},a.unbindEntityEvents=function(a,b,c){g(a,b,c,f,e)},a.proxyBindEntityEvents=function(b,c){return a.bindEntityEvents(this,b,c)},a.proxyUnbindEntityEvents=function(b,c){return a.unbindEntityEvents(this,b,c)}}(e);var g=["description","fileName","lineNumber","name","message","number"];return e.Error=e.extend.call(Error,{urlRoot:"http://marionettejs.com/docs/v"+e.VERSION+"/",constructor:function(a,b){c.isObject(a)?(b=a,a=b.message):b||(b={});var d=Error.call(this,a);c.extend(this,c.pick(d,g),c.pick(b,g)),this.captureStackTrace(),b.url&&(this.url=this.urlRoot+b.url)},captureStackTrace:function(){Error.captureStackTrace&&Error.captureStackTrace(this,e.Error)},toString:function(){return this.name+": "+this.message+(this.url?" See: "+this.url:"")}}),e.Error.extend=e.extend,e.Callbacks=function(){this._deferred=e.Deferred(),this._callbacks=[]},c.extend(e.Callbacks.prototype,{add:function(a,b){var d=c.result(this._deferred,"promise");this._callbacks.push({cb:a,ctx:b}),d.then(function(c){b&&(c.context=b),a.call(c.context,c.options)})},run:function(a,b){this._deferred.resolve({options:a,context:b})},reset:function(){var a=this._callbacks;this._deferred=e.Deferred(),this._callbacks=[],c.each(a,function(a){this.add(a.cb,a.ctx)},this)}}),e.Controller=function(a){this.options=a||{},c.isFunction(this.initialize)&&this.initialize(this.options)},e.Controller.extend=e.extend,c.extend(e.Controller.prototype,b.Events,{destroy:function(){return e._triggerMethod(this,"before:destroy",arguments),e._triggerMethod(this,"destroy",arguments),this.stopListening(),this.off(),this},triggerMethod:e.triggerMethod,getOption:e.proxyGetOption}),e.Object=function(a){this.options=c.extend({},c.result(this,"options"),a),this.initialize.apply(this,arguments)},e.Object.extend=e.extend,c.extend(e.Object.prototype,b.Events,{initialize:function(){},destroy:function(){this.triggerMethod("before:destroy"),this.triggerMethod("destroy"),this.stopListening()},triggerMethod:e.triggerMethod,getOption:e.proxyGetOption,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.Region=e.Object.extend({constructor:function(a){if(this.options=a||{},this.el=this.getOption("el"),this.el=this.el instanceof b.$?this.el[0]:this.el,!this.el)throw new e.Error({name:"NoElError",message:'An "el" must be specified for a region.'});this.$el=this.getEl(this.el),e.Object.call(this,a)},show:function(a,b){if(this._ensureElement()){this._ensureViewIsIntact(a);var c=b||{},d=a!==this.currentView,f=!!c.preventDestroy,g=!!c.forceShow,h=!!this.currentView,i=d&&!f,j=d||g;if(h&&this.triggerMethod("before:swapOut",this.currentView,this,b),this.currentView&&delete this.currentView._parent,i?this.empty():h&&j&&this.currentView.off("destroy",this.empty,this),j){a.once("destroy",this.empty,this),a.render(),a._parent=this,h&&this.triggerMethod("before:swap",a,this,b),this.triggerMethod("before:show",a,this,b),e.triggerMethodOn(a,"before:show",a,this,b),h&&this.triggerMethod("swapOut",this.currentView,this,b);var k=e.isNodeAttached(this.el),l=[],m=c.triggerBeforeAttach||this.triggerBeforeAttach,n=c.triggerAttach||this.triggerAttach;return k&&m&&(l=this._displayedViews(a),this._triggerAttach(l,"before:")),this.attachHtml(a),this.currentView=a,k&&n&&(l=this._displayedViews(a),this._triggerAttach(l)),h&&this.triggerMethod("swap",a,this,b),this.triggerMethod("show",a,this,b),e.triggerMethodOn(a,"show",a,this,b),this}return this}},triggerBeforeAttach:!0,triggerAttach:!0,_triggerAttach:function(a,b){var d=(b||"")+"attach";c.each(a,function(a){e.triggerMethodOn(a,d,a,this)},this)},_displayedViews:function(a){return c.union([a],c.result(a,"_getNestedViews")||[])},_ensureElement:function(){if(c.isObject(this.el)||(this.$el=this.getEl(this.el),this.el=this.$el[0]),!this.$el||0===this.$el.length){if(this.getOption("allowMissingEl"))return!1;throw new e.Error('An "el" '+this.$el.selector+" must exist in DOM")}return!0},_ensureViewIsIntact:function(a){if(!a)throw new e.Error({name:"ViewNotValid",message:"The view passed is undefined and therefore invalid. You must pass a view instance to show."});if(a.isDestroyed)throw new e.Error({name:"ViewDestroyedError",message:'View (cid: "'+a.cid+'") has already been destroyed and cannot be used.'})},getEl:function(a){return b.$(a,e._getValue(this.options.parentEl,this))},attachHtml:function(a){this.$el.contents().detach(),this.el.appendChild(a.el)},empty:function(){var a=this.currentView;if(a)return a.off("destroy",this.empty,this),this.triggerMethod("before:empty",a),this._destroyView(),this.triggerMethod("empty",a),delete this.currentView,this},_destroyView:function(){var a=this.currentView;a.destroy&&!a.isDestroyed?a.destroy():a.remove&&(a.remove(),a.isDestroyed=!0)},attachView:function(a){return this.currentView=a,this},hasView:function(){return!!this.currentView},reset:function(){return this.empty(),this.$el&&(this.el=this.$el.selector),delete this.$el,this}},{buildRegion:function(a,b){if(c.isString(a))return this._buildRegionFromSelector(a,b);if(a.selector||a.el||a.regionClass)return this._buildRegionFromObject(a,b);if(c.isFunction(a))return this._buildRegionFromRegionClass(a);throw new e.Error({message:"Improper region configuration type.",url:"marionette.region.html#region-configuration-types"})},_buildRegionFromSelector:function(a,b){return new b({el:a})},_buildRegionFromObject:function(a,b){var d=a.regionClass||b,e=c.omit(a,"selector","regionClass");return a.selector&&!e.el&&(e.el=a.selector),new d(e)},_buildRegionFromRegionClass:function(a){return new a}}),e.RegionManager=e.Controller.extend({constructor:function(a){this._regions={},e.Controller.call(this,a),this.addRegions(this.getOption("regions"))},addRegions:function(a,b){return a=e._getValue(a,this,arguments),c.reduce(a,function(a,d,e){return c.isString(d)&&(d={selector:d}),d.selector&&(d=c.defaults({},d,b)),a[e]=this.addRegion(e,d),a},{},this)},addRegion:function(a,b){var c;return c=b instanceof e.Region?b:e.Region.buildRegion(b,e.Region),this.triggerMethod("before:add:region",a,c),c._parent=this,this._store(a,c),this.triggerMethod("add:region",a,c),c},get:function(a){return this._regions[a]},getRegions:function(){return c.clone(this._regions)},removeRegion:function(a){var b=this._regions[a];return this._remove(a,b),b},removeRegions:function(){var a=this.getRegions();return c.each(this._regions,function(a,b){this._remove(b,a)},this),a},emptyRegions:function(){var a=this.getRegions();return c.invoke(a,"empty"),a},destroy:function(){return this.removeRegions(),e.Controller.prototype.destroy.apply(this,arguments)},_store:function(a,b){this._regions[a]=b,this._setLength()},_remove:function(a,b){this.triggerMethod("before:remove:region",a,b),b.empty(),b.stopListening(),delete b._parent,delete this._regions[a],this._setLength(),this.triggerMethod("remove:region",a,b)},_setLength:function(){this.length=c.size(this._regions)}}),e.actAsCollection(e.RegionManager.prototype,"_regions"),e.TemplateCache=function(a){this.templateId=a},c.extend(e.TemplateCache,{templateCaches:{},get:function(a){var b=this.templateCaches[a];return b||(b=new e.TemplateCache(a),this.templateCaches[a]=b),b.load()},clear:function(){var a,b=c.toArray(arguments),d=b.length;if(d>0)for(a=0;d>a;a++)delete this.templateCaches[b[a]];else this.templateCaches={}}}),c.extend(e.TemplateCache.prototype,{load:function(){if(this.compiledTemplate)return this.compiledTemplate;var a=this.loadTemplate(this.templateId);return this.compiledTemplate=this.compileTemplate(a),this.compiledTemplate},loadTemplate:function(a){var c=b.$(a).html();if(!c||0===c.length)throw new e.Error({name:"NoTemplateError",message:'Could not find template: "'+a+'"'});return c},compileTemplate:function(a){return c.template(a)}}),e.Renderer={render:function(a,b){if(!a)throw new e.Error({name:"TemplateNotFoundError",message:"Cannot render the template since its false, null or undefined."});var d=c.isFunction(a)?a:e.TemplateCache.get(a);return d(b)}},e.View=b.View.extend({isDestroyed:!1,constructor:function(a){c.bindAll(this,"render"),a=e._getValue(a,this),this.options=c.extend({},c.result(this,"options"),a),this._behaviors=e.Behaviors(this),b.View.apply(this,arguments),e.MonitorDOMRefresh(this),this.on("show",this.onShowCalled)},getTemplate:function(){return this.getOption("template")},serializeModel:function(a){return a.toJSON.apply(a,c.rest(arguments))},mixinTemplateHelpers:function(a){a=a||{};var b=this.getOption("templateHelpers");return b=e._getValue(b,this),c.extend(a,b)},normalizeUIKeys:function(a){var b=c.result(this,"_uiBindings");return e.normalizeUIKeys(a,b||c.result(this,"ui"))},normalizeUIValues:function(a){var b=c.result(this,"ui"),d=c.result(this,"_uiBindings");return e.normalizeUIValues(a,d||b)},configureTriggers:function(){if(this.triggers){var a=this.normalizeUIKeys(c.result(this,"triggers"));return c.reduce(a,function(a,b,c){return a[c]=this._buildViewTrigger(b),a},{},this)}},delegateEvents:function(a){return this._delegateDOMEvents(a),this.bindEntityEvents(this.model,this.getOption("modelEvents")),this.bindEntityEvents(this.collection,this.getOption("collectionEvents")),c.each(this._behaviors,function(a){a.bindEntityEvents(this.model,a.getOption("modelEvents")),a.bindEntityEvents(this.collection,a.getOption("collectionEvents"))},this),this},_delegateDOMEvents:function(a){var d=e._getValue(a||this.events,this);d=this.normalizeUIKeys(d),c.isUndefined(a)&&(this.events=d);var f={},g=c.result(this,"behaviorEvents")||{},h=this.configureTriggers(),i=c.result(this,"behaviorTriggers")||{};c.extend(f,g,d,h,i),b.View.prototype.delegateEvents.call(this,f)},undelegateEvents:function(){return b.View.prototype.undelegateEvents.apply(this,arguments),this.unbindEntityEvents(this.model,this.getOption("modelEvents")),this.unbindEntityEvents(this.collection,this.getOption("collectionEvents")),c.each(this._behaviors,function(a){a.unbindEntityEvents(this.model,a.getOption("modelEvents")),a.unbindEntityEvents(this.collection,a.getOption("collectionEvents"))},this),this},onShowCalled:function(){},_ensureViewIsIntact:function(){if(this.isDestroyed)throw new e.Error({name:"ViewDestroyedError",message:'View (cid: "'+this.cid+'") has already been destroyed and cannot be used.'})},destroy:function(){if(!this.isDestroyed){var a=c.toArray(arguments);return this.triggerMethod.apply(this,["before:destroy"].concat(a)),this.isDestroyed=!0,this.triggerMethod.apply(this,["destroy"].concat(a)),this.unbindUIElements(),this.remove(),c.invoke(this._behaviors,"destroy",a),this}},bindUIElements:function(){this._bindUIElements(),c.invoke(this._behaviors,this._bindUIElements)},_bindUIElements:function(){if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var a=c.result(this,"_uiBindings");this.ui={},c.each(a,function(a,b){this.ui[b]=this.$(a)},this)}},unbindUIElements:function(){this._unbindUIElements(),c.invoke(this._behaviors,this._unbindUIElements)},_unbindUIElements:function(){this.ui&&this._uiBindings&&(c.each(this.ui,function(a,b){delete this.ui[b]},this),this.ui=this._uiBindings,delete this._uiBindings)},_buildViewTrigger:function(a){var b=c.isObject(a),d=c.defaults({},b?a:{},{preventDefault:!0,stopPropagation:!0}),e=b?d.event:a;return function(a){a&&(a.preventDefault&&d.preventDefault&&a.preventDefault(),a.stopPropagation&&d.stopPropagation&&a.stopPropagation());var b={view:this,model:this.model,collection:this.collection};this.triggerMethod(e,b)}},setElement:function(){var a=b.View.prototype.setElement.apply(this,arguments);return c.invoke(this._behaviors,"proxyViewProperties",this),a},triggerMethod:function(){for(var a=e._triggerMethod,b=a(this,arguments),c=this._behaviors,d=0,f=c&&c.length;f>d;d++)a(c[d],arguments);return b},_getImmediateChildren:function(){return[]},_getNestedViews:function(){var a=this._getImmediateChildren();return a.length?c.reduce(a,function(a,b){return b._getNestedViews?a.concat(b._getNestedViews()):a},a):a},normalizeMethods:e.normalizeMethods,getOption:e.proxyGetOption,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.ItemView=e.View.extend({constructor:function(){e.View.apply(this,arguments)},serializeData:function(){if(!this.model&&!this.collection)return{};var a=[this.model||this.collection];return arguments.length&&a.push.apply(a,arguments),this.model?this.serializeModel.apply(this,a):{items:this.serializeCollection.apply(this,a)}},serializeCollection:function(a){return a.toJSON.apply(a,c.rest(arguments))},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderTemplate(),this.bindUIElements(),this.triggerMethod("render",this),this},_renderTemplate:function(){var a=this.getTemplate();if(a!==!1){if(!a)throw new e.Error({name:"UndefinedTemplateError",message:"Cannot render the template since it is null or undefined."});var b=this.serializeData();b=this.mixinTemplateHelpers(b);var c=e.Renderer.render(a,b,this);return this.attachElContent(c),this}},attachElContent:function(a){return this.$el.html(a),this}}),e.CollectionView=e.View.extend({childViewEventPrefix:"childview",constructor:function(a){var b=a||{};c.isUndefined(this.sort)&&(this.sort=c.isUndefined(b.sort)?!0:b.sort),this.once("render",this._initialEvents),this._initChildViewStorage(),e.View.apply(this,arguments),this.initRenderBuffer()},initRenderBuffer:function(){this.elBuffer=document.createDocumentFragment(),this._bufferedChildren=[]},startBuffering:function(){this.initRenderBuffer(),this.isBuffering=!0},endBuffering:function(){this.isBuffering=!1,this._triggerBeforeShowBufferedChildren(),this.attachBuffer(this,this.elBuffer),this._triggerShowBufferedChildren(),this.initRenderBuffer()},_triggerBeforeShowBufferedChildren:function(){this._isShown&&c.each(this._bufferedChildren,c.partial(this._triggerMethodOnChild,"before:show"))},_triggerShowBufferedChildren:function(){this._isShown&&(c.each(this._bufferedChildren,c.partial(this._triggerMethodOnChild,"show")),this._bufferedChildren=[])},_triggerMethodOnChild:function(a,b){e.triggerMethodOn(b,a)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this.render),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},_onCollectionAdd:function(a){this.destroyEmptyView();var b=this.getChildView(a),c=this.collection.indexOf(a);this.addChild(a,b,c)},_onCollectionRemove:function(a){var b=this.children.findByModel(a);this.removeChildView(b),this.checkEmpty()},onShowCalled:function(){this.children.each(c.partial(this._triggerMethodOnChild,"show"))},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderChildren(),this.triggerMethod("render",this),this},resortView:function(){this.render()},_sortViews:function(){var a=this.collection.find(function(a,b){var c=this.children.findByModel(a);return!c||c._index!==b},this);a&&this.resortView()},_emptyViewIndex:-1,_renderChildren:function(){this.destroyEmptyView(),this.destroyChildren(),this.isEmpty(this.collection)?this.showEmptyView():(this.triggerMethod("before:render:collection",this),this.startBuffering(),this.showCollection(),this.endBuffering(),this.triggerMethod("render:collection",this))},showCollection:function(){var a;this.collection.each(function(b,c){a=this.getChildView(b),this.addChild(b,a,c)},this)},showEmptyView:function(){var a=this.getEmptyView();if(a&&!this._showingEmptyView){this.triggerMethod("before:render:empty"),this._showingEmptyView=!0;var c=new b.Model;this.addEmptyView(c,a),this.triggerMethod("render:empty")}},destroyEmptyView:function(){this._showingEmptyView&&(this.triggerMethod("before:remove:empty"),this.destroyChildren(),delete this._showingEmptyView,this.triggerMethod("remove:empty"))},getEmptyView:function(){return this.getOption("emptyView")},addEmptyView:function(a,b){var d=this.getOption("emptyViewOptions")||this.getOption("childViewOptions");c.isFunction(d)&&(d=d.call(this,a,this._emptyViewIndex));var f=this.buildChildView(a,b,d);f._parent=this,this.proxyChildEvents(f),this._isShown&&e.triggerMethodOn(f,"before:show"),this.children.add(f),this.renderChildView(f,this._emptyViewIndex),this._isShown&&e.triggerMethodOn(f,"show")},getChildView:function(a){var b=this.getOption("childView");if(!b)throw new e.Error({name:"NoChildViewError",message:'A "childView" must be specified'});return b},addChild:function(a,b,c){var d=this.getOption("childViewOptions");d=e._getValue(d,this,[a,c]);var f=this.buildChildView(a,b,d);return this._updateIndices(f,!0,c),this._addChildView(f,c),f._parent=this,f},_updateIndices:function(a,b,c){this.sort&&(b&&(a._index=c),this.children.each(function(c){c._index>=a._index&&(c._index+=b?1:-1)}))},_addChildView:function(a,b){this.proxyChildEvents(a),this.triggerMethod("before:add:child",a),this.children.add(a),this.renderChildView(a,b),this._isShown&&!this.isBuffering&&e.triggerMethodOn(a,"show"),this.triggerMethod("add:child",a)},renderChildView:function(a,b){return a.render(),this.attachHtml(this,a,b),a},buildChildView:function(a,b,d){var e=c.extend({model:a},d);return new b(e)},removeChildView:function(a){return a&&(this.triggerMethod("before:remove:child",a),a.destroy?a.destroy():a.remove&&a.remove(),delete a._parent,this.stopListening(a),this.children.remove(a),this.triggerMethod("remove:child",a),this._updateIndices(a,!1)),a},isEmpty:function(){return!this.collection||0===this.collection.length},checkEmpty:function(){this.isEmpty(this.collection)&&this.showEmptyView()},attachBuffer:function(a,b){a.$el.append(b)},attachHtml:function(a,b,c){a.isBuffering?(a.elBuffer.appendChild(b.el),a._bufferedChildren.push(b)):a._insertBefore(b,c)||a._insertAfter(b)},_insertBefore:function(a,b){var c,d=this.sort&&b<this.children.length-1;return d&&(c=this.children.find(function(a){return a._index===b+1})),c?(c.$el.before(a.el),!0):!1},_insertAfter:function(a){this.$el.append(a.el)},_initChildViewStorage:function(){this.children=new b.ChildViewContainer},destroy:function(){return this.isDestroyed?void 0:(this.triggerMethod("before:destroy:collection"),this.destroyChildren(),this.triggerMethod("destroy:collection"),e.View.prototype.destroy.apply(this,arguments))},destroyChildren:function(){var a=this.children.map(c.identity);return this.children.each(this.removeChildView,this),this.checkEmpty(),a},proxyChildEvents:function(a){var b=this.getOption("childViewEventPrefix");this.listenTo(a,"all",function(){var d=c.toArray(arguments),e=d[0],f=this.normalizeMethods(c.result(this,"childEvents"));d[0]=b+":"+e,d.splice(1,0,a),"undefined"!=typeof f&&c.isFunction(f[e])&&f[e].apply(this,d.slice(1)),this.triggerMethod.apply(this,d)},this)},_getImmediateChildren:function(){return c.values(this.children._views)}}),e.CompositeView=e.CollectionView.extend({constructor:function(){e.CollectionView.apply(this,arguments)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this._renderChildren),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},getChildView:function(a){var b=this.getOption("childView")||this.constructor;return b},serializeData:function(){var a={};return this.model&&(a=c.partial(this.serializeModel,this.model).apply(this,arguments)),a},render:function(){return this._ensureViewIsIntact(),this.isRendered=!0,this.resetChildViewContainer(),this.triggerMethod("before:render",this),this._renderTemplate(),this._renderChildren(),this.triggerMethod("render",this),this},_renderChildren:function(){this.isRendered&&e.CollectionView.prototype._renderChildren.call(this)},_renderTemplate:function(){var a={};a=this.serializeData(),a=this.mixinTemplateHelpers(a),this.triggerMethod("before:render:template");var b=this.getTemplate(),c=e.Renderer.render(b,a,this);this.attachElContent(c),this.bindUIElements(),this.triggerMethod("render:template")},attachElContent:function(a){return this.$el.html(a),this},attachBuffer:function(a,b){var c=this.getChildViewContainer(a);c.append(b)},_insertAfter:function(a){var b=this.getChildViewContainer(this,a);b.append(a.el)},getChildViewContainer:function(a,b){if("$childViewContainer"in a)return a.$childViewContainer;var c,d=e.getOption(a,"childViewContainer");if(d){var f=e._getValue(d,a);if(c="@"===f.charAt(0)&&a.ui?a.ui[f.substr(4)]:a.$(f),c.length<=0)throw new e.Error({name:"ChildViewContainerMissingError",message:'The specified "childViewContainer" was not found: '+a.childViewContainer})}else c=a.$el;return a.$childViewContainer=c,c},resetChildViewContainer:function(){this.$childViewContainer&&delete this.$childViewContainer}}),e.LayoutView=e.ItemView.extend({regionClass:e.Region,constructor:function(a){a=a||{},this._firstRender=!0,this._initializeRegions(a),e.ItemView.call(this,a)},render:function(){return this._ensureViewIsIntact(),this._firstRender?this._firstRender=!1:this._reInitializeRegions(),e.ItemView.prototype.render.apply(this,arguments)},destroy:function(){return this.isDestroyed?this:(this.regionManager.destroy(),e.ItemView.prototype.destroy.apply(this,arguments))},addRegion:function(a,b){var c={};return c[a]=b,this._buildRegions(c)[a]},addRegions:function(a){return this.regions=c.extend({},this.regions,a),this._buildRegions(a)},removeRegion:function(a){return delete this.regions[a],this.regionManager.removeRegion(a)},getRegion:function(a){return this.regionManager.get(a)},getRegions:function(){return this.regionManager.getRegions()},_buildRegions:function(a){var b={regionClass:this.getOption("regionClass"),parentEl:c.partial(c.result,this,"el")};return this.regionManager.addRegions(a,b)},_initializeRegions:function(a){var b;this._initRegionManager(),b=e._getValue(this.regions,this,[a])||{};var d=this.getOption.call(a,"regions");d=e._getValue(d,this,[a]),c.extend(b,d),b=this.normalizeUIValues(b),this.addRegions(b)},_reInitializeRegions:function(){this.regionManager.invoke("reset")},getRegionManager:function(){return new e.RegionManager},_initRegionManager:function(){this.regionManager=this.getRegionManager(),this.regionManager._parent=this,this.listenTo(this.regionManager,"before:add:region",function(a){this.triggerMethod("before:add:region",a)}),this.listenTo(this.regionManager,"add:region",function(a,b){this[a]=b,this.triggerMethod("add:region",a,b)}),this.listenTo(this.regionManager,"before:remove:region",function(a){this.triggerMethod("before:remove:region",a)}),this.listenTo(this.regionManager,"remove:region",function(a,b){delete this[a],this.triggerMethod("remove:region",a,b)})},_getImmediateChildren:function(){return c.chain(this.regionManager.getRegions()).pluck("currentView").compact().value()}}),e.Behavior=e.Object.extend({constructor:function(a,b){this.view=b,this.defaults=c.result(this,"defaults")||{},this.options=c.extend({},this.defaults,a),e.Object.apply(this,arguments)},$:function(){return this.view.$.apply(this.view,arguments)},destroy:function(){this.stopListening()},proxyViewProperties:function(a){this.$el=a.$el,this.el=a.el}}),e.Behaviors=function(a,b){function c(a,d){return b.isObject(a.behaviors)?(d=c.parseBehaviors(a,d||b.result(a,"behaviors")),c.wrap(a,d,b.keys(f)),d):{}}function d(a,c){this._view=a,this._viewUI=b.result(a,"ui"),this._behaviors=c,this._triggers={}}var e=/^(\S+)\s*(.*)$/,f={behaviorTriggers:function(a,b){var c=new d(this,b);return c.buildBehaviorTriggers()},behaviorEvents:function(c,d){var f={},g=this._uiBindings||b.result(this,"ui");return b.each(d,function(c,d){var h={},i=b.clone(b.result(c,"events"))||{},j=c._uiBindings||b.result(c,"ui"),k=b.extend({},g,j);i=a.normalizeUIKeys(i,k);var l=0;b.each(i,function(a,f){var g=f.match(e),i=g[1]+"."+[this.cid,d,l++," "].join(""),j=g[2],k=i+j,m=b.isFunction(a)?a:c[a];h[k]=b.bind(m,c)},this),f=b.extend(f,h)},this),f}};return b.extend(c,{behaviorsLookup:function(){throw new a.Error({message:"You must define where your behaviors are stored.",url:"marionette.behaviors.html#behaviorslookup"})},getBehaviorClass:function(b,d){return b.behaviorClass?b.behaviorClass:a._getValue(c.behaviorsLookup,this,[b,d])[d]},parseBehaviors:function(a,d){return b.chain(d).map(function(d,e){var f=c.getBehaviorClass(d,e),g=new f(d,a),h=c.parseBehaviors(a,b.result(g,"behaviors"));return[g].concat(h)}).flatten().value()},wrap:function(a,c,d){b.each(d,function(d){a[d]=b.partial(f[d],a[d],c)})}}),b.extend(d.prototype,{buildBehaviorTriggers:function(){return b.each(this._behaviors,this._buildTriggerHandlersForBehavior,this),this._triggers},_buildTriggerHandlersForBehavior:function(c,d){var e=b.extend({},this._viewUI,b.result(c,"ui")),f=b.clone(b.result(c,"triggers"))||{};f=a.normalizeUIKeys(f,e),b.each(f,b.bind(this._setHandlerForBehavior,this,c,d))},_setHandlerForBehavior:function(a,b,c,d){var e=d.replace(/^\S+/,function(a){return a+".behaviortriggers"+b});this._triggers[e]=this._view._buildViewTrigger(c)}}),c}(e,c),e.AppRouter=b.Router.extend({constructor:function(a){this.options=a||{},b.Router.apply(this,arguments);var c=this.getOption("appRoutes"),d=this._getController();this.processAppRoutes(d,c),this.on("route",this._processOnRoute,this)},appRoute:function(a,b){var c=this._getController();this._addAppRoute(c,a,b)},_processOnRoute:function(a,b){if(c.isFunction(this.onRoute)){var d=c.invert(this.getOption("appRoutes"))[a];this.onRoute(a,d,b)}},processAppRoutes:function(a,b){if(b){var d=c.keys(b).reverse();c.each(d,function(c){this._addAppRoute(a,c,b[c])},this)}},_getController:function(){return this.getOption("controller")},_addAppRoute:function(a,b,d){var f=a[d];if(!f)throw new e.Error('Method "'+d+'" was not found on the controller');this.route(b,d,c.bind(f,a))},getOption:e.proxyGetOption,triggerMethod:e.triggerMethod,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.Application=e.Object.extend({constructor:function(a){this._initializeRegions(a),this._initCallbacks=new e.Callbacks,this.submodules={},c.extend(this,a),this._initChannel(),e.Object.call(this,a)},execute:function(){this.commands.execute.apply(this.commands,arguments)},request:function(){return this.reqres.request.apply(this.reqres,arguments)},addInitializer:function(a){this._initCallbacks.add(a)},start:function(a){this.triggerMethod("before:start",a),this._initCallbacks.run(a,this),this.triggerMethod("start",a)},addRegions:function(a){return this._regionManager.addRegions(a)},emptyRegions:function(){return this._regionManager.emptyRegions()},removeRegion:function(a){return this._regionManager.removeRegion(a)},getRegion:function(a){return this._regionManager.get(a)},getRegions:function(){return this._regionManager.getRegions()},module:function(a,b){var d=e.Module.getClass(b),f=c.toArray(arguments);return f.unshift(this),d.create.apply(d,f)},getRegionManager:function(){return new e.RegionManager},_initializeRegions:function(a){var b=c.isFunction(this.regions)?this.regions(a):this.regions||{};this._initRegionManager();var d=e.getOption(a,"regions");return c.isFunction(d)&&(d=d.call(this,a)),c.extend(b,d),this.addRegions(b),this},_initRegionManager:function(){this._regionManager=this.getRegionManager(),this._regionManager._parent=this,this.listenTo(this._regionManager,"before:add:region",function(){e._triggerMethod(this,"before:add:region",arguments)}),this.listenTo(this._regionManager,"add:region",function(a,b){this[a]=b,e._triggerMethod(this,"add:region",arguments)}),this.listenTo(this._regionManager,"before:remove:region",function(){e._triggerMethod(this,"before:remove:region",arguments)}),this.listenTo(this._regionManager,"remove:region",function(a){delete this[a],e._triggerMethod(this,"remove:region",arguments)})},_initChannel:function(){this.channelName=c.result(this,"channelName")||"global",this.channel=c.result(this,"channel")||b.Wreqr.radio.channel(this.channelName),this.vent=c.result(this,"vent")||this.channel.vent,this.commands=c.result(this,"commands")||this.channel.commands,this.reqres=c.result(this,"reqres")||this.channel.reqres}}),e.Module=function(a,b,d){this.moduleName=a,this.options=c.extend({},this.options,d),this.initialize=d.initialize||this.initialize,this.submodules={},this._setupInitializersAndFinalizers(),this.app=b,c.isFunction(this.initialize)&&this.initialize(a,b,this.options)},e.Module.extend=e.extend,c.extend(e.Module.prototype,b.Events,{startWithParent:!0,initialize:function(){},addInitializer:function(a){this._initializerCallbacks.add(a)},addFinalizer:function(a){this._finalizerCallbacks.add(a)},start:function(a){this._isInitialized||(c.each(this.submodules,function(b){b.startWithParent&&b.start(a)}),this.triggerMethod("before:start",a),this._initializerCallbacks.run(a,this),this._isInitialized=!0,this.triggerMethod("start",a))},stop:function(){this._isInitialized&&(this._isInitialized=!1,this.triggerMethod("before:stop"),c.invoke(this.submodules,"stop"),this._finalizerCallbacks.run(void 0,this),this._initializerCallbacks.reset(),this._finalizerCallbacks.reset(),this.triggerMethod("stop"))},addDefinition:function(a,b){this._runModuleDefinition(a,b)},_runModuleDefinition:function(a,d){if(a){var f=c.flatten([this,this.app,b,e,b.$,c,d]);a.apply(this,f)}},_setupInitializersAndFinalizers:function(){this._initializerCallbacks=new e.Callbacks,this._finalizerCallbacks=new e.Callbacks},triggerMethod:e.triggerMethod}),c.extend(e.Module,{create:function(a,b,d){var e=a,f=c.rest(arguments,3);b=b.split(".");var g=b.length,h=[];return h[g-1]=d,c.each(b,function(b,c){var g=e;e=this._getModule(g,b,a,d),this._addModuleDefinition(g,e,h[c],f)},this),e},_getModule:function(a,b,d,e,f){var g=c.extend({},e),h=this.getClass(e),i=a[b];return i||(i=new h(b,d,g),a[b]=i,a.submodules[b]=i),i},getClass:function(a){var b=e.Module;return a?a.prototype instanceof b?a:a.moduleClass||b:b},_addModuleDefinition:function(a,b,c,d){var e=this._getDefine(c),f=this._getStartWithParent(c,b);e&&b.addDefinition(e,d),this._addStartWithParent(a,b,f)},_getStartWithParent:function(a,b){var d;return c.isFunction(a)&&a.prototype instanceof e.Module?(d=b.constructor.prototype.startWithParent,c.isUndefined(d)?!0:d):c.isObject(a)?(d=a.startWithParent,c.isUndefined(d)?!0:d):!0},_getDefine:function(a){return!c.isFunction(a)||a.prototype instanceof e.Module?c.isObject(a)?a.define:null:a},_addStartWithParent:function(a,b,c){b.startWithParent=b.startWithParent&&c,b.startWithParent&&!b.startWithParentIsConfigured&&(b.startWithParentIsConfigured=!0,a.addInitializer(function(a){b.startWithParent&&b.start(a)}))}}),e}),function(a){"function"==typeof define&&define.amd?define(["backbone","underscore"],a):"object"==typeof exports?module.exports=a(require("backbone"),require("underscore")):a(window.Backbone,window._)}(function(a,b){var c=a.Router.prototype.route,d=function(){};b.extend(a.Router.prototype,{before:d,after:d,route:function(a,e,f){f||(f=this[e]);var g=b.bind(function(){ -var c,e=[a,b.toArray(arguments)];if(c=b.isFunction(this.before)?this.before:"undefined"!=typeof this.before[a]?this.before[a]:d,c.apply(this,e)!==!1){f&&f.apply(this,arguments);var g;g=b.isFunction(this.after)?this.after:"undefined"!=typeof this.after[a]?this.after[a]:d,g.apply(this,e)}},this);return c.call(this,a,e,g)}})}),function(a,b,c,d,e,f,g){"use strict";"object"==typeof d?e.exports=f(c("underscore"),c("backbone"),c("jquery")):"function"==typeof b&&b.amd?b(["underscore","backbone","jquery"],function(b,c,d){return b=b===g?a._:b,c=c===g?a.Backbone:c,d=d===g?a.$:d,a.Backbone=f(b,c,d)}):a.returnExportsGlobal=f(a._,a.Backbone,a.$)}(this,this.define,this.require,this.exports,this.module,function(a,b,c,d){"use strict";var e=function(b){this.options=b!==d?b:{},this.namespaceDelimiter=b!==d&&b.namespaceDelimiter!==d?b.namespaceDelimiter:this.namespaceDelimiter,this.contentType=b!==d&&b.contentType!==d?b.contentType:this.contentType,a.bindAll(this)},f=b.Model.prototype.constructor,g=b.sync,h={};return e.prototype={options:{},charset:"iso-8859-1",namespace:"",namespaceDelimiter:"/",contentType:"application/json",url:null,responseID:null,exceptions:{404:{code:-1,message:"404"},500:{code:-2,message:"500"},typeMissmatch:{code:-3,message:"Type missmatch"},badResponseId:{code:-4,message:"Bad response ID"},noResponse:{code:-5,message:"No response"},noDefError:{code:-6,message:"No error defined"},renderError:function(a,b){return{code:b!==d?-7:b,message:a?"No error defined":a}}},onSuccess:function(b,c,e){if(a.isFunction(b)===!0){if(null===e||e===d)return this.handleExceptions(this.exceptions.noResponse),this;null!==e&&c!==String(e.id)&&this.handleExceptions(this.exceptions.badResponseId),b.apply(this,[e.result,e.error])}else this.onError(e)},onError:function(a,b){return null===b||b===d?(this.handleExceptions(this.exceptions.noResponse),this):void(null!==b.error&&d!==b.error?this.handleExceptions(b.error):this.handleExceptions(this.exceptions.noDefError))},query:function(b,e,f){var g=String((new Date).getTime()),h=null;return this.responseID=g,h=(a.isArray(e)||a.isObject(e))&&a.isString(b)?c.ajax({contentType:this.contentType+"; charset="+this.charset,type:"POST",dataType:"json",url:this.url,data:JSON.stringify({jsonrpc:"2.0",method:this.namespace+this.namespaceDelimiter+b,id:g,params:e}),statusCode:{404:a.bind(function(){this.handleExceptions(this.exceptions[404])},this),500:a.bind(function(){this.handleExceptions(this.exceptions[500])},this)},success:a.bind(function(a,b,c){null!==a&&a.error!==d?this.onError(f,a,b,c):this.onSuccess(f,g,a,b,c)},this),error:a.bind(function(a,b,c){404!==a.status&&500!==a.status&&this.onError(f,a,b,c)},this)}):this.handleExceptions(this.exceptions.typeMissmatch)},checkMethods:function(c,e,f,g,i,j,k){var l=this,m=this.options&&this.options.useNamedParameters===!0,n=null,o=!1,p=null,q=[],r={},s=null,t=f;return m=f.options&&f.options.useNamedParameters?f.options.useNamedParameters:m,m&&(q={},a.isFunction(f.args)&&(t=f.args())),g="delete"===g?"remove":g,a.isArray(f.methods[g])||a.isFunction(f.methods[g])?(a.isFunction(f.methods[g])?(a.isString(h[f.get("_rpcId")])||a.each(h[f.get("_rpcId")],function(a,b){f.get(b)!==a&&(r[b]=!0)}),h[f.get("_rpcId")]=f.toJSON(),n=a.bind(f.methods[g],f)(r,i)):n=f.methods[g],a.isArray(n[0])&&(o=!0),o!==!0?(s=a.clone(n),p=s.shift(),s.length>0?a.each(s,function(c){""===c?a.isArray(q)&&q.push(""):f instanceof b.Collection?t!==d&&t[c]!==d?q=l.addParam(q,t,c,a.isFunction(t[c]),!1):i[c]!==d&&(q=l.addParam(q,i,c,!1,!1)):f.get(c)!==d?q=l.addParam(q,f,c,!1,!0):i[c]!==d&&(q=l.addParam(q,i,c,!1,!1))}):q=a.isArray(q)?[]:{},c(p,q,j,k)):(a.each(n,function(b){var d=a.clone(b);return p=null,q=[],p=d.shift(),a.each(d,function(a){q.push(f.get(a))}),c(p,q,j,k)}),null)):this.handleExceptions(this.exceptions.typeMissmatch)},addParam:function(b,c,e,f,g){var h;return h=g?c.get(e):f?c[e]():c[e],a.isArray(b)?b.push(h):h!==d&&(b[e]=h),b},invoke:function(c,e,f){var g={success:function(b){e.trigger("called:"+c,e,b),f!==d&&a.isFunction(f.success)&&f.success(e,b)},error:function(b,e){b.trigger("error",b,e),b.trigger("error:"+c,b,e),f!==d&&a.isFunction(f.error)&&f.error(b,e)}};return b.sync(c,e,g),this},defaultExceptionHandler:function(a){throw"Error code: "+a.code+" - message: "+a.message},handleExceptions:function(b){var c=a.isFunction(this.options.exceptionHandler)?this.options.exceptionHandler:this.defaultExceptionHandler;return c.call(this,b),this}},b.Rpc=e,b.Model=b.Model.extend({constructor:function(b){this.rpc!==d&&a.isFunction(this.rpc.invoke)===!0&&this.methods!==d&&a.each(this.methods,a.bind(function(b,c){1!=={read:1,create:1,remove:1,update:1}[c]&&(this[c]=a.bind(function(a){return this.rpc.invoke(c,this,a),this},this))},this)),f.apply(this,arguments)}}),b.sync=function(c){var e=null,f=function(g,i,j){var k=function(c,e){return null!==e&&e!==d?(j.error(i,e),this):(i instanceof b.Collection&&c!==d&&null!==c&&("object"==typeof c[0]?a.each(c,function(b,d){b._rpcId=a.uniqueId("rpc_"),c[d]=b,h[b._rpcId]=b}):a.each(c,function(a,b){h[b]=a})),i instanceof b.Model&&c!==d&&null!==c&&(c._rpcId=a.uniqueId("rpc_"),h[c._rpcId]=c),(c===d||null===c)&&(c=[]),i.parsers!==d&&i.parsers[g]!==d&&a.isFunction(i.parsers[g])&&i.parsers[g].apply(i,[c]),void j.success(c))},l=function(a){j.error(i,a)};if(i.rpc instanceof c){if(e=i.rpc,e.url=a.isFunction(i.url)?i.url():i.url,a.isString(i.namespace)===!0&&(e.namespace=i.namespace),i.methods===d)throw"Backbone.Rpc Error: No Method(s) given!";return"object"!=typeof i.params&&(i.params={}),e.checkMethods(e.query,i.params,i,g,j,k,l)}return f.previous.apply(i,arguments)};return f.previous=g,f}(e),b}),function(a,b){if("function"==typeof define&&define.amd)define(["underscore","backbone","jquery"],function(a,c,d){return b(a,c,d)});else if("undefined"!=typeof exports){var c=require("underscore"),d=require("backbone"),e=require("jquery");module.exports=b(c,d,e)}else b(a._,a.Backbone,a.jQuery)}(this,function(a,b,c){"use strict";var d=b.Syphon,e=b.Syphon={};e.VERSION="0.5.0",e.noConflict=function(){return b.Syphon=d,this},e.ignoredTypes=["button","submit","reset","fieldset"],e.serialize=function(b,d){var e={},h=i(d),k=f(b,h);return a.each(k,function(a){var b=c(a),d=g(b),f=h.keyExtractors.get(d),i=f(b),k=h.inputReaders.get(d),l=k(b),m=h.keyAssignmentValidators.get(d);if(m(b,i,l)){var n=h.keySplitter(i);e=j(e,n,l)}}),e},e.deserialize=function(b,d,e){var h=i(e),j=f(b,h),l=k(h,d);a.each(j,function(a){var b=c(a),d=g(b),e=h.keyExtractors.get(d),f=e(b),i=h.inputWriters.get(d),j=l[f];i(b,j)})};var f=function(b,d){var e=h(b),f=e.elements;return f=a.reject(f,function(b){var e,f=g(b),h=d.keyExtractors.get(f),i=h(c(b)),j=a.include(d.ignoredTypes,f),k=a.include(d.include,i),l=a.include(d.exclude,i);return e=k?!1:d.include?!0:l||j})},g=function(a){var b,d=c(a),e=d[0].tagName,f=e;return"input"===e.toLowerCase()&&(b=d.attr("type"),f=b?b:"text"),f.toLowerCase()},h=function(b){return a.isUndefined(b.$el)&&"form"===b.tagName.toLowerCase()?b:b.$el.is("form")?b.el:b.$("form")[0]},i=function(b){var c=a.clone(b)||{};return c.ignoredTypes=a.clone(e.ignoredTypes),c.inputReaders=c.inputReaders||e.InputReaders,c.inputWriters=c.inputWriters||e.InputWriters,c.keyExtractors=c.keyExtractors||e.KeyExtractors,c.keySplitter=c.keySplitter||e.KeySplitter,c.keyJoiner=c.keyJoiner||e.KeyJoiner,c.keyAssignmentValidators=c.keyAssignmentValidators||e.KeyAssignmentValidators,c},j=function(b,c,d){if(!c)return b;var e=c.shift();return b[e]||(b[e]=a.isArray(e)?[]:{}),0===c.length&&(a.isArray(b[e])?b[e].push(d):b[e]=d),c.length>0&&j(b[e],c,d),b},k=function(b,c,d){var e={};return a.each(c,function(c,f){var g={};d&&(f=b.keyJoiner(d,f)),a.isArray(c)?(f+="[]",g[f]=c):a.isObject(c)?g=k(b,c,f):g[f]=c,a.extend(e,g)}),e},l=e.TypeRegistry=function(){this.registeredTypes={}};l.extend=b.Model.extend,a.extend(l.prototype,{get:function(a){return this.registeredTypes[a]||this.registeredTypes["default"]},register:function(a,b){this.registeredTypes[a]=b},registerDefault:function(a){this.registeredTypes["default"]=a},unregister:function(a){this.registeredTypes[a]&&delete this.registeredTypes[a]}});var m=e.KeyExtractorSet=l.extend(),n=e.KeyExtractors=new m;n.registerDefault(function(a){return a.prop("name")||""});var o=e.InputReaderSet=l.extend(),p=e.InputReaders=new o;p.registerDefault(function(a){return a.val()}),p.register("checkbox",function(a){return a.prop("checked")});var q=e.InputWriterSet=l.extend(),r=e.InputWriters=new q;r.registerDefault(function(a,b){a.val(b)}),r.register("checkbox",function(a,b){a.prop("checked",b)}),r.register("radio",function(a,b){a.prop("checked",a.val()===b.toString())});var s=e.KeyAssignmentValidatorSet=l.extend(),t=e.KeyAssignmentValidators=new s;return t.registerDefault(function(){return!0}),t.register("radio",function(a,b,c){return a.prop("checked")}),e.KeySplitter=function(a){var b,c=a.match(/[^\[\]]+/g);return a.indexOf("[]")===a.length-2&&(b=c.pop(),c.push([b])),c},e.KeyJoiner=function(a,b){return a+"["+b+"]"},b.Syphon}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.Wreqr,d=a.Wreqr={};return a.Wreqr.VERSION="1.3.2",a.Wreqr.noConflict=function(){return a.Wreqr=c,this},d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this)},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(b)return function(){return b.callback.apply(b.context,arguments)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,b),d.CommandStorage=function(){var c=function(a){this.options=a,this._commands={},b.isFunction(this.initialize)&&this.initialize(a)};return b.extend(c.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),c}(),d.Commands=function(a,b){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this),a.Handlers.prototype.constructor.apply(this,arguments)},execute:function(a){a=arguments[0];var c=b.rest(arguments);this.hasHandler(a)?this.getHandler(a).apply(this,c):this.storage.addCommand(a,c)},_executeCommands:function(a,c,d){var e=this.storage.getCommands(a);b.each(e.instances,function(a){c.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var c,d=a.storageType||this.storageType;c=b.isFunction(d)?new d:d,this.storage=c}})}(d,b),d.RequestResponse=function(a,b){return a.Handlers.extend({request:function(a){return this.hasHandler(a)?this.getHandler(a).apply(this,b.rest(arguments)):void 0}})}(d,b),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,b),d.Channel=function(c){var d=function(b){this.vent=new a.Wreqr.EventAggregator,this.reqres=new a.Wreqr.RequestResponse,this.commands=new a.Wreqr.Commands,this.channelName=b};return b.extend(d.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(a,b){return this._connect("vent",a,b),this},connectCommands:function(a,b){return this._connect("commands",a,b),this},connectRequests:function(a,b){return this._connect("reqres",a,b),this},_connect:function(a,c,d){if(c){d=d||this;var e="vent"===a?"on":"setHandler";b.each(c,function(c,f){this[a][e](f,b.bind(c,d))},this)}}}),d}(d),d.radio=function(a,b){var c=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};b.extend(c.prototype,{channel:function(a){if(!a)throw new Error("Channel must receive a name");return this._getChannel(a)},_getChannel:function(b){var c=this._channels[b];return c||(c=new a.Channel(b),this._channels[b]=c),c},_proxyMethods:function(){b.each(["vent","commands","reqres"],function(a){b.each(d[a],function(b){this[a][b]=e(this,a,b)},this)},this)}});var d={vent:["on","off","trigger","once","stopListening","listenTo","listenToOnce"],commands:["execute","setHandler","setHandlers","removeHandler","removeAllHandlers"],reqres:["request","setHandler","setHandlers","removeHandler","removeAllHandlers"]},e=function(a,c,d){return function(e){var f=a._getChannel(e)[c];return f[d].apply(f,b.rest(arguments))}};return new c}(d,b),a.Wreqr});var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(a){var b,c,d,e,f,g,h,i="",j=0;for(a=Base64._utf8_encode(a);j<a.length;)b=a.charCodeAt(j++),c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=b>>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i=i+this._keyStr.charAt(e)+this._keyStr.charAt(f)+this._keyStr.charAt(g)+this._keyStr.charAt(h);return i},decode:function(a){var b,c,d,e,f,g,h,i="",j=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");j<a.length;)e=this._keyStr.indexOf(a.charAt(j++)),f=this._keyStr.indexOf(a.charAt(j++)),g=this._keyStr.indexOf(a.charAt(j++)),h=this._keyStr.indexOf(a.charAt(j++)),b=e<<2|f>>4,c=(15&f)<<4|g>>2,d=(3&g)<<6|h,i+=String.fromCharCode(b),64!=g&&(i+=String.fromCharCode(c)),64!=h&&(i+=String.fromCharCode(d));return i=Base64._utf8_decode(i)},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b="",c=0,d=c1=c2=0;c<a.length;)d=a.charCodeAt(c),128>d?(b+=String.fromCharCode(d),c++):d>191&&224>d?(c2=a.charCodeAt(c+1),b+=String.fromCharCode((31&d)<<6|63&c2),c+=2):(c2=a.charCodeAt(c+1),c3=a.charCodeAt(c+2),b+=String.fromCharCode((15&d)<<12|(63&c2)<<6|63&c3),c+=3);return b}};!function(a){var b={onBeforeRender:function(){this._isRendering=!0},onRender:function(){this.footer?this.footerElement=this.$el.find(this.footer)[0]:this.footerElement=null,delete this._isRendering},appendHtml:function(a,b,c){function d(b){for(var c=1,d=e(b+1);!d&&b+c+1<a.collection.length-1;)c+=1,d=e(b+c);return d}function e(b){if(!(b>=a.collection.length)){var c=a.children.findByModel(a.collection.at(b));return c}}var f=this.footerElement,g=a.itemViewContainer||a.el,h=a.itemViewContainer?$(a.itemViewContainer):a.$el;if(this._isRendering)return void(f?b.$el.insertBefore(f):h.append(b.el));var i;return 0===c?(i=d(0),void(i?b.$el.insertBefore(i.el):f?b.$el.insertBefore(f):b.$el.appendTo(g))):c==a.collection.length-1?void(f?b.$el.insertBefore(f):b.$el.appendTo(g)):(i=e(c-1),void(i?b.$el.insertAfter(i.$el):(i=d(c),i?b.$el.insertBefore(i.el):f?b.$el.insertBefore(f):b.$el.appendTo(g))))}};return a.SortedMixin=b,"function"==typeof define&&define.amd&&define([],function(){return b}),b}(window),Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|aft(er)?|from|hence)/i,subtract:/^(\-|bef(ore)?|ago)/i,yesterday:/^yes(terday)?/i,today:/^t(od(ay)?)?/i,tomorrow:/^tom(orrow)?/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^mn|min(ute)?s?/i,hour:/^h(our)?s?/i,week:/^w(eek)?s?/i,month:/^m(onth)?s?/i,day:/^d(ay)?s?/i,year:/^y(ear)?s?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a(?!u|p)|p)/i},timezones:[{name:"UTC",offset:"-000"},{name:"GMT",offset:"-000"},{name:"EST",offset:"-0500"},{name:"EDT",offset:"-0400"},{name:"CST",offset:"-0600"},{name:"CDT",offset:"-0500"},{name:"MST",offset:"-0700"},{name:"MDT",offset:"-0600"},{name:"PST",offset:"-0800"},{name:"PDT",offset:"-0700"}]},function(){var a=Date,b=a.prototype,c=a.CultureInfo,d=function(a,b){return b||(b=2),("000"+a).slice(-1*b)};b.clearTime=function(){return this.setHours(0),this.setMinutes(0),this.setSeconds(0),this.setMilliseconds(0),this},b.setTimeToNow=function(){var a=new Date;return this.setHours(a.getHours()),this.setMinutes(a.getMinutes()),this.setSeconds(a.getSeconds()),this.setMilliseconds(a.getMilliseconds()),this},a.today=function(){return(new Date).clearTime()},a.compare=function(a,b){if(isNaN(a)||isNaN(b))throw new Error(a+" - "+b);if(a instanceof Date&&b instanceof Date)return b>a?-1:a>b?1:0;throw new TypeError(a+" - "+b)},a.equals=function(a,b){return 0===a.compareTo(b)},a.getDayNumberFromName=function(a){for(var b=c.dayNames,d=c.abbreviatedDayNames,e=c.shortestDayNames,f=a.toLowerCase(),g=0;g<b.length;g++)if(b[g].toLowerCase()==f||d[g].toLowerCase()==f||e[g].toLowerCase()==f)return g;return-1},a.getMonthNumberFromName=function(a){for(var b=c.monthNames,d=c.abbreviatedMonthNames,e=a.toLowerCase(),f=0;f<b.length;f++)if(b[f].toLowerCase()==e||d[f].toLowerCase()==e)return f;return-1},a.isLeapYear=function(a){return a%4===0&&a%100!==0||a%400===0},a.getDaysInMonth=function(b,c){return[31,a.isLeapYear(b)?29:28,31,30,31,30,31,31,30,31,30,31][c]},a.getTimezoneAbbreviation=function(a){for(var b=c.timezones,d=0;d<b.length;d++)if(b[d].offset===a)return b[d].name;return null},a.getTimezoneOffset=function(a){for(var b=c.timezones,d=0;d<b.length;d++)if(b[d].name===a.toUpperCase())return b[d].offset;return null},b.clone=function(){return new Date(this.getTime())},b.compareTo=function(a){return Date.compare(this,a)},b.equals=function(a){return Date.equals(this,a||new Date)},b.between=function(a,b){return this.getTime()>=a.getTime()&&this.getTime()<=b.getTime()},b.isAfter=function(a){return 1===this.compareTo(a||new Date)},b.isBefore=function(a){return-1===this.compareTo(a||new Date)},b.isToday=function(){return this.isSameDay(new Date)},b.isSameDay=function(a){return this.clone().clearTime().equals(a.clone().clearTime())},b.addMilliseconds=function(a){return this.setMilliseconds(this.getMilliseconds()+a),this},b.addSeconds=function(a){return this.addMilliseconds(1e3*a)},b.addMinutes=function(a){return this.addMilliseconds(6e4*a)},b.addHours=function(a){return this.addMilliseconds(36e5*a)},b.addDays=function(a){return this.setDate(this.getDate()+a),this},b.addWeeks=function(a){return this.addDays(7*a)},b.addMonths=function(b){var c=this.getDate();return this.setDate(1),this.setMonth(this.getMonth()+b),this.setDate(Math.min(c,a.getDaysInMonth(this.getFullYear(),this.getMonth()))),this},b.addYears=function(a){return this.addMonths(12*a)},b.add=function(a){if("number"==typeof a)return this._orient=a,this;var b=a;return b.milliseconds&&this.addMilliseconds(b.milliseconds),b.seconds&&this.addSeconds(b.seconds),b.minutes&&this.addMinutes(b.minutes),b.hours&&this.addHours(b.hours),b.weeks&&this.addWeeks(b.weeks),b.months&&this.addMonths(b.months),b.years&&this.addYears(b.years),b.days&&this.addDays(b.days),this};var e,f,g;b.getWeek=function(){var a,b,c,d,h,i,j,k,l,m;return e=e?e:this.getFullYear(),f=f?f:this.getMonth()+1,g=g?g:this.getDate(),2>=f?(a=e-1,b=(a/4|0)-(a/100|0)+(a/400|0),c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0),l=b-c,h=0,i=g-1+31*(f-1)):(a=e,b=(a/4|0)-(a/100|0)+(a/400|0),c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0),l=b-c,h=l+1,i=g+(153*(f-3)+2)/5+58+l),j=(a+b)%7,d=(i+j-h)%7,k=i+3-d|0,m=0>k?53-((j-l)/5|0):k>364+l?1:(k/7|0)+1,e=f=g=null,m},b.getISOWeek=function(){return e=this.getUTCFullYear(),f=this.getUTCMonth()+1,g=this.getUTCDate(),d(this.getWeek())},b.setWeek=function(a){return this.moveToDayOfWeek(1).addWeeks(a-this.getWeek())},a._validate=function(a,b,c,d){if("undefined"==typeof a)return!1;if("number"!=typeof a)throw new TypeError(a+" is not a Number.");if(b>a||a>c)throw new RangeError(a+" is not a valid value for "+d+".");return!0},a.validateMillisecond=function(b){return a._validate(b,0,999,"millisecond")},a.validateSecond=function(b){return a._validate(b,0,59,"second")},a.validateMinute=function(b){return a._validate(b,0,59,"minute")},a.validateHour=function(b){return a._validate(b,0,23,"hour")},a.validateDay=function(b,c,d){return a._validate(b,1,a.getDaysInMonth(c,d),"day")},a.validateMonth=function(b){return a._validate(b,0,11,"month")},a.validateYear=function(b){return a._validate(b,0,9999,"year")},b.set=function(b){return a.validateMillisecond(b.millisecond)&&this.addMilliseconds(b.millisecond-this.getMilliseconds()),a.validateSecond(b.second)&&this.addSeconds(b.second-this.getSeconds()),a.validateMinute(b.minute)&&this.addMinutes(b.minute-this.getMinutes()),a.validateHour(b.hour)&&this.addHours(b.hour-this.getHours()),a.validateMonth(b.month)&&this.addMonths(b.month-this.getMonth()),a.validateYear(b.year)&&this.addYears(b.year-this.getFullYear()),a.validateDay(b.day,this.getFullYear(),this.getMonth())&&this.addDays(b.day-this.getDate()),b.timezone&&this.setTimezone(b.timezone),b.timezoneOffset&&this.setTimezoneOffset(b.timezoneOffset),b.week&&a._validate(b.week,0,53,"week")&&this.setWeek(b.week),this},b.moveToFirstDayOfMonth=function(){return this.set({day:1})},b.moveToLastDayOfMonth=function(){return this.set({day:a.getDaysInMonth(this.getFullYear(),this.getMonth())})},b.moveToNthOccurrence=function(a,b){var c=0;if(b>0)c=b-1;else if(-1===b)return this.moveToLastDayOfMonth(),this.getDay()!==a&&this.moveToDayOfWeek(a,-1),this;return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(a,1).addWeeks(c)},b.moveToDayOfWeek=function(a,b){var c=(a-this.getDay()+7*(b||1))%7;return this.addDays(0===c?c+=7*(b||1):c)},b.moveToMonth=function(a,b){var c=(a-this.getMonth()+12*(b||1))%12;return this.addMonths(0===c?c+=12*(b||1):c)},b.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/864e5)+1},b.getTimezone=function(){return a.getTimezoneAbbreviation(this.getUTCOffset())},b.setTimezoneOffset=function(a){var b=this.getTimezoneOffset(),c=-6*Number(a)/10;return this.addMinutes(c-b)},b.setTimezone=function(b){return this.setTimezoneOffset(a.getTimezoneOffset(b))},b.hasDaylightSavingTime=function(){return Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset()},b.isDaylightSavingTime=function(){return this.hasDaylightSavingTime()&&(new Date).getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset()},b.getUTCOffset=function(){var a,b=-10*this.getTimezoneOffset()/6;return 0>b?(a=(b-1e4).toString(),a.charAt(0)+a.substr(2)):(a=(b+1e4).toString(),"+"+a.substr(1))},b.getElapsed=function(a){return(a||new Date)-this},b.toISOString||(b.toISOString=function(){function a(a){return 10>a?"0"+a:a}return'"'+this.getUTCFullYear()+"-"+a(this.getUTCMonth()+1)+"-"+a(this.getUTCDate())+"T"+a(this.getUTCHours())+":"+a(this.getUTCMinutes())+":"+a(this.getUTCSeconds())+'Z"'}),b._toString=b.toString,b.toString=function(a){var b=this;if(a&&1==a.length){var e=c.formatPatterns;switch(b.t=b.toString,a){case"d":return b.t(e.shortDate);case"D":return b.t(e.longDate);case"F":return b.t(e.fullDateTime);case"m":return b.t(e.monthDay);case"r":return b.t(e.rfc1123);case"s":return b.t(e.sortableDateTime);case"t":return b.t(e.shortTime);case"T":return b.t(e.longTime);case"u":return b.t(e.universalSortableDateTime);case"y":return b.t(e.yearMonth)}}var f=function(a){switch(1*a){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th"}};return a?a.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(a){if("\\"===a.charAt(0))return a.replace("\\","");switch(b.h=b.getHours,a){case"hh":return d(b.h()<13?0===b.h()?12:b.h():b.h()-12);case"h":return b.h()<13?0===b.h()?12:b.h():b.h()-12;case"HH":return d(b.h());case"H":return b.h();case"mm":return d(b.getMinutes());case"m":return b.getMinutes();case"ss":return d(b.getSeconds());case"s":return b.getSeconds();case"yyyy":return d(b.getFullYear(),4);case"yy":return d(b.getFullYear());case"dddd":return c.dayNames[b.getDay()];case"ddd":return c.abbreviatedDayNames[b.getDay()];case"dd":return d(b.getDate());case"d":return b.getDate();case"MMMM":return c.monthNames[b.getMonth()];case"MMM":return c.abbreviatedMonthNames[b.getMonth()];case"MM":return d(b.getMonth()+1);case"M":return b.getMonth()+1;case"t":return b.h()<12?c.amDesignator.substring(0,1):c.pmDesignator.substring(0,1);case"tt":return b.h()<12?c.amDesignator:c.pmDesignator;case"S":return f(b.getDate());default:return a}}):this._toString()}}(),function(){var a=Date,b=a.prototype,c=a.CultureInfo,d=Number.prototype;b._orient=1,b._nth=null,b._is=!1,b._same=!1,b._isSecond=!1,d._dateElement="day",b.next=function(){return this._orient=1,this},a.next=function(){return a.today().next()},b.last=b.prev=b.previous=function(){return this._orient=-1,this},a.last=a.prev=a.previous=function(){return a.today().last()},b.is=function(){return this._is=!0,this},b.same=function(){return this._same=!0,this._isSecond=!1,this},b.today=function(){return this.same().day()},b.weekday=function(){return this._is?(this._is=!1,!this.is().sat()&&!this.is().sun()):!1},b.at=function(b){return"string"==typeof b?a.parse(this.toString("d")+" "+b):this.set(b)},d.fromNow=d.after=function(a){var b={};return b[this._dateElement]=this,(a?a.clone():new Date).add(b)},d.ago=d.before=function(a){var b={};return b[this._dateElement]=-1*this,(a?a.clone():new Date).add(b)};var e,f="sunday monday tuesday wednesday thursday friday saturday".split(/\s/),g="january february march april may june july august september october november december".split(/\s/),h="Millisecond Second Minute Hour Day Week Month Year".split(/\s/),i="Milliseconds Seconds Minutes Hours Date Week Month FullYear".split(/\s/),j="final first second third fourth fifth".split(/\s/);b.toObject=function(){for(var a={},b=0;b<h.length;b++)a[h[b].toLowerCase()]=this["get"+i[b]]();return a},a.fromObject=function(a){return a.week=null,Date.today().set(a)};for(var k=function(b){return function(){if(this._is)return this._is=!1,this.getDay()==b;if(null!==this._nth){this._isSecond&&this.addSeconds(-1*this._orient),this._isSecond=!1;var c=this._nth;this._nth=null;var d=this.clone().moveToLastDayOfMonth();if(this.moveToNthOccurrence(b,c),this>d)throw new RangeError(a.getDayName(b)+" does not occur "+c+" times in the month of "+a.getMonthName(d.getMonth())+" "+d.getFullYear()+".");return this}return this.moveToDayOfWeek(b,this._orient)}},l=function(b){return function(){var d=a.today(),e=b-d.getDay();return 0===b&&1===c.firstDayOfWeek&&0!==d.getDay()&&(e+=7),d.addDays(e)}},m=0;m<f.length;m++)a[f[m].toUpperCase()]=a[f[m].toUpperCase().substring(0,3)]=m,a[f[m]]=a[f[m].substring(0,3)]=l(m),b[f[m]]=b[f[m].substring(0,3)]=k(m);for(var n=function(a){return function(){return this._is?(this._is=!1,this.getMonth()===a):this.moveToMonth(a,this._orient)}},o=function(b){return function(){return a.today().set({month:b,day:1})}},p=0;p<g.length;p++)a[g[p].toUpperCase()]=a[g[p].toUpperCase().substring(0,3)]=p,a[g[p]]=a[g[p].substring(0,3)]=o(p),b[g[p]]=b[g[p].substring(0,3)]=n(p);for(var q=function(a){return function(){if(this._isSecond)return this._isSecond=!1,this;if(this._same){this._same=this._is=!1;for(var b=this.toObject(),c=(arguments[0]||new Date).toObject(),d="",e=a.toLowerCase(),f=h.length-1;f>-1;f--){if(d=h[f].toLowerCase(),b[d]!=c[d])return!1;if(e==d)break}return!0}return"s"!=a.substring(a.length-1)&&(a+="s"),this["add"+a](this._orient)}},r=function(a){return function(){return this._dateElement=a,this}},s=0;s<h.length;s++)e=h[s].toLowerCase(),b[e]=b[e+"s"]=q(h[s]),d[e]=d[e+"s"]=r(e);b._ss=q("Second");for(var t=function(a){return function(b){return this._same?this._ss(arguments[0]):b||0===b?this.moveToNthOccurrence(b,a):(this._nth=a,2!==a||void 0!==b&&null!==b?this:(this._isSecond=!0,this.addSeconds(this._orient)))}},u=0;u<j.length;u++)b[j[u]]=t(0===u?-1:u)}(),function(){Date.Parsing={Exception:function(a){this.message="Parse error at '"+a.substring(0,10)+" ...'"}};for(var a=Date.Parsing,b=a.Operators={rtoken:function(b){return function(c){var d=c.match(b);if(d)return[d[0],c.substring(d[0].length)];throw new a.Exception(c)}},token:function(a){return function(a){return b.rtoken(new RegExp("^s*"+a+"s*"))(a)}},stoken:function(a){return b.rtoken(new RegExp("^"+a))},until:function(a){return function(b){for(var c=[],d=null;b.length;){try{d=a.call(this,b)}catch(e){c.push(d[0]),b=d[1];continue}break}return[c,b]}},many:function(a){return function(b){for(var c=[],d=null;b.length;){try{d=a.call(this,b)}catch(e){return[c,b]}c.push(d[0]),b=d[1]}return[c,b]}},optional:function(a){return function(b){var c=null;try{c=a.call(this,b)}catch(d){return[null,b]}return[c[0],c[1]]}},not:function(b){return function(c){try{b.call(this,c)}catch(d){return[null,c]}throw new a.Exception(c)}},ignore:function(a){return a?function(b){var c=null;return c=a.call(this,b),[null,c[1]]}:null},product:function(){for(var a=arguments[0],c=Array.prototype.slice.call(arguments,1),d=[],e=0;e<a.length;e++)d.push(b.each(a[e],c));return d},cache:function(b){var c={},d=null;return function(e){try{d=c[e]=c[e]||b.call(this,e)}catch(f){d=c[e]=f}if(d instanceof a.Exception)throw d;return d}},any:function(){var b=arguments;return function(c){for(var d=null,e=0;e<b.length;e++)if(null!=b[e]){try{d=b[e].call(this,c)}catch(f){d=null}if(d)return d}throw new a.Exception(c)}},each:function(){var b=arguments;return function(c){for(var d=[],e=null,f=0;f<b.length;f++)if(null!=b[f]){try{e=b[f].call(this,c)}catch(g){throw new a.Exception(c)}d.push(e[0]),c=e[1]}return[d,c]}},all:function(){var a=arguments,b=b;return b.each(b.optional(a))},sequence:function(c,d,e){return d=d||b.rtoken(/^\s*/),e=e||null,1==c.length?c[0]:function(b){for(var f=null,g=null,h=[],i=0;i<c.length;i++){try{f=c[i].call(this,b)}catch(j){break}h.push(f[0]);try{g=d.call(this,f[1])}catch(k){g=null;break}b=g[1]}if(!f)throw new a.Exception(b);if(g)throw new a.Exception(g[1]);if(e)try{f=e.call(this,f[1])}catch(l){throw new a.Exception(f[1])}return[h,f?f[1]:b]}},between:function(a,c,d){d=d||a;var e=b.each(b.ignore(a),c,b.ignore(d)); -return function(a){var b=e.call(this,a);return[[b[0][0],r[0][2]],b[1]]}},list:function(a,c,d){return c=c||b.rtoken(/^\s*/),d=d||null,a instanceof Array?b.each(b.product(a.slice(0,-1),b.ignore(c)),a.slice(-1),b.ignore(d)):b.each(b.many(b.each(a,b.ignore(c))),px,b.ignore(d))},set:function(c,d,e){return d=d||b.rtoken(/^\s*/),e=e||null,function(f){for(var g=null,h=null,i=null,j=null,k=[[],f],l=!1,m=0;m<c.length;m++){i=null,h=null,g=null,l=1==c.length;try{g=c[m].call(this,f)}catch(n){continue}if(j=[[g[0]],g[1]],g[1].length>0&&!l)try{i=d.call(this,g[1])}catch(o){l=!0}else l=!0;if(l||0!==i[1].length||(l=!0),!l){for(var p=[],q=0;q<c.length;q++)m!=q&&p.push(c[q]);h=b.set(p,d).call(this,i[1]),h[0].length>0&&(j[0]=j[0].concat(h[0]),j[1]=h[1])}if(j[1].length<k[1].length&&(k=j),0===k[1].length)break}if(0===k[0].length)return k;if(e){try{i=e.call(this,k[1])}catch(r){throw new a.Exception(k[1])}k[1]=i[1]}return k}},forward:function(a,b){return function(c){return a[b].call(this,c)}},replace:function(a,b){return function(c){var d=a.call(this,c);return[b,d[1]]}},process:function(a,b){return function(c){var d=a.call(this,c);return[b.call(this,d[0]),d[1]]}},min:function(b,c){return function(d){var e=c.call(this,d);if(e[0].length<b)throw new a.Exception(d);return e}}},c=function(a){return function(){var b=null,c=[];if(arguments.length>1?b=Array.prototype.slice.call(arguments):arguments[0]instanceof Array&&(b=arguments[0]),!b)return a.apply(null,arguments);for(var d=0,e=b.shift();d<e.length;d++)return b.unshift(e[d]),c.push(a.apply(null,b)),b.shift(),c}},d="optional not ignore cache".split(/\s/),e=0;e<d.length;e++)b[d[e]]=c(b[d[e]]);for(var f=function(a){return function(){return arguments[0]instanceof Array?a.apply(null,arguments[0]):a.apply(null,arguments)}},g="each any all".split(/\s/),h=0;h<g.length;h++)b[g[h]]=f(b[g[h]])}(),function(){var a=Date,b=(a.prototype,a.CultureInfo),c=function(a){for(var b=[],d=0;d<a.length;d++)a[d]instanceof Array?b=b.concat(c(a[d])):a[d]&&b.push(a[d]);return b};a.Grammar={},a.Translator={hour:function(a){return function(){this.hour=Number(a)}},minute:function(a){return function(){this.minute=Number(a)}},second:function(a){return function(){this.second=Number(a)}},meridian:function(a){return function(){this.meridian=a.slice(0,1).toLowerCase()}},timezone:function(a){return function(){var b=a.replace(/[^\d\+\-]/g,"");b.length?this.timezoneOffset=Number(b):this.timezone=a.toLowerCase()}},day:function(a){var b=a[0];return function(){this.day=Number(b.match(/\d+/)[0])}},month:function(a){return function(){this.month=3==a.length?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(a)/4:Number(a)-1}},year:function(a){return function(){var c=Number(a);this.year=a.length>2?c:c+(c+2e3<b.twoDigitYearMax?2e3:1900)}},rday:function(a){return function(){switch(a){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0,this.now=!0}}},finishExact:function(b){b=b instanceof Array?b:[b];for(var c=0;c<b.length;c++)b[c]&&b[c].call(this);var d=new Date;if(!this.hour&&!this.minute||this.month||this.year||this.day||(this.day=d.getDate()),this.year||(this.year=d.getFullYear()),this.month||0===this.month||(this.month=d.getMonth()),this.day||(this.day=1),this.hour||(this.hour=0),this.minute||(this.minute=0),this.second||(this.second=0),this.meridian&&this.hour&&("p"==this.meridian&&this.hour<12?this.hour=this.hour+12:"a"==this.meridian&&12==this.hour&&(this.hour=0)),this.day>a.getDaysInMonth(this.year,this.month))throw new RangeError(this.day+" is not a valid value for days.");var e=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);return this.timezone?e.set({timezone:this.timezone}):this.timezoneOffset&&e.set({timezoneOffset:this.timezoneOffset}),e},finish:function(b){if(b=b instanceof Array?c(b):[b],0===b.length)return null;for(var d=0;d<b.length;d++)"function"==typeof b[d]&&b[d].call(this);var e=a.today();if(this.now&&!this.unit&&!this.operator)return new Date;this.now&&(e=new Date);var f,g,h,i=!!(this.days&&null!==this.days||this.orient||this.operator);if(h="past"==this.orient||"subtract"==this.operator?-1:1,this.now||-1=="hour minute second".indexOf(this.unit)||e.setTimeToNow(),(this.month||0===this.month)&&-1!="year day hour minute second".indexOf(this.unit)&&(this.value=this.month+1,this.month=null,i=!0),!i&&this.weekday&&!this.day&&!this.days){var j=Date[this.weekday]();this.day=j.getDate(),this.month||(this.month=j.getMonth()),this.year=j.getFullYear()}if(i&&this.weekday&&"month"!=this.unit&&(this.unit="day",f=a.getDayNumberFromName(this.weekday)-e.getDay(),g=7,this.days=f?(f+h*g)%g:h*g),this.month&&"day"==this.unit&&this.operator&&(this.value=this.month+1,this.month=null),null!=this.value&&null!=this.month&&null!=this.year&&(this.day=1*this.value),this.month&&!this.day&&this.value&&(e.set({day:1*this.value}),i||(this.day=1*this.value)),this.month||!this.value||"month"!=this.unit||this.now||(this.month=this.value,i=!0),i&&(this.month||0===this.month)&&"year"!=this.unit&&(this.unit="month",f=this.month-e.getMonth(),g=12,this.months=f?(f+h*g)%g:h*g,this.month=null),this.unit||(this.unit="day"),!this.value&&this.operator&&null!==this.operator&&this[this.unit+"s"]&&null!==this[this.unit+"s"]?this[this.unit+"s"]=this[this.unit+"s"]+("add"==this.operator?1:-1)+(this.value||0)*h:(null==this[this.unit+"s"]||null!=this.operator)&&(this.value||(this.value=1),this[this.unit+"s"]=this.value*h),this.meridian&&this.hour&&("p"==this.meridian&&this.hour<12?this.hour=this.hour+12:"a"==this.meridian&&12==this.hour&&(this.hour=0)),this.weekday&&!this.day&&!this.days){var j=Date[this.weekday]();this.day=j.getDate(),j.getMonth()!==e.getMonth()&&(this.month=j.getMonth())}return!this.month&&0!==this.month||this.day||(this.day=1),this.orient||this.operator||"week"!=this.unit||!this.value||this.day||this.month?(i&&this.timezone&&this.day&&this.days&&(this.day=this.days),i?e.add(this):e.set(this)):Date.today().setWeek(this.value)}};var d,e=a.Parsing.Operators,f=a.Grammar,g=a.Translator;f.datePartDelimiter=e.rtoken(/^([\s\-\.\,\/\x27]+)/),f.timePartDelimiter=e.stoken(":"),f.whiteSpace=e.rtoken(/^\s*/),f.generalDelimiter=e.rtoken(/^(([\s\,]|at|@|on)+)/);var h={};f.ctoken=function(a){var c=h[a];if(!c){for(var d=b.regexPatterns,f=a.split(/\s+/),g=[],i=0;i<f.length;i++)g.push(e.replace(e.rtoken(d[f[i]]),f[i]));c=h[a]=e.any.apply(null,g)}return c},f.ctoken2=function(a){return e.rtoken(b.regexPatterns[a])},f.h=e.cache(e.process(e.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),g.hour)),f.hh=e.cache(e.process(e.rtoken(/^(0[0-9]|1[0-2])/),g.hour)),f.H=e.cache(e.process(e.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),g.hour)),f.HH=e.cache(e.process(e.rtoken(/^([0-1][0-9]|2[0-3])/),g.hour)),f.m=e.cache(e.process(e.rtoken(/^([0-5][0-9]|[0-9])/),g.minute)),f.mm=e.cache(e.process(e.rtoken(/^[0-5][0-9]/),g.minute)),f.s=e.cache(e.process(e.rtoken(/^([0-5][0-9]|[0-9])/),g.second)),f.ss=e.cache(e.process(e.rtoken(/^[0-5][0-9]/),g.second)),f.hms=e.cache(e.sequence([f.H,f.m,f.s],f.timePartDelimiter)),f.t=e.cache(e.process(f.ctoken2("shortMeridian"),g.meridian)),f.tt=e.cache(e.process(f.ctoken2("longMeridian"),g.meridian)),f.z=e.cache(e.process(e.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),g.timezone)),f.zz=e.cache(e.process(e.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),g.timezone)),f.zzz=e.cache(e.process(f.ctoken2("timezone"),g.timezone)),f.timeSuffix=e.each(e.ignore(f.whiteSpace),e.set([f.tt,f.zzz])),f.time=e.each(e.optional(e.ignore(e.stoken("T"))),f.hms,f.timeSuffix),f.d=e.cache(e.process(e.each(e.rtoken(/^([0-2]\d|3[0-1]|\d)/),e.optional(f.ctoken2("ordinalSuffix"))),g.day)),f.dd=e.cache(e.process(e.each(e.rtoken(/^([0-2]\d|3[0-1])/),e.optional(f.ctoken2("ordinalSuffix"))),g.day)),f.ddd=f.dddd=e.cache(e.process(f.ctoken("sun mon tue wed thu fri sat"),function(a){return function(){this.weekday=a}})),f.M=e.cache(e.process(e.rtoken(/^(1[0-2]|0\d|\d)/),g.month)),f.MM=e.cache(e.process(e.rtoken(/^(1[0-2]|0\d)/),g.month)),f.MMM=f.MMMM=e.cache(e.process(f.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),g.month)),f.y=e.cache(e.process(e.rtoken(/^(\d\d?)/),g.year)),f.yy=e.cache(e.process(e.rtoken(/^(\d\d)/),g.year)),f.yyy=e.cache(e.process(e.rtoken(/^(\d\d?\d?\d?)/),g.year)),f.yyyy=e.cache(e.process(e.rtoken(/^(\d\d\d\d)/),g.year)),d=function(){return e.each(e.any.apply(null,arguments),e.not(f.ctoken2("timeContext")))},f.day=d(f.d,f.dd),f.month=d(f.M,f.MMM),f.year=d(f.yyyy,f.yy),f.orientation=e.process(f.ctoken("past future"),function(a){return function(){this.orient=a}}),f.operator=e.process(f.ctoken("add subtract"),function(a){return function(){this.operator=a}}),f.rday=e.process(f.ctoken("yesterday tomorrow today now"),g.rday),f.unit=e.process(f.ctoken("second minute hour day week month year"),function(a){return function(){this.unit=a}}),f.value=e.process(e.rtoken(/^\d\d?(st|nd|rd|th)?/),function(a){return function(){this.value=a.replace(/\D/g,"")}}),f.expression=e.set([f.rday,f.operator,f.value,f.unit,f.orientation,f.ddd,f.MMM]),d=function(){return e.set(arguments,f.datePartDelimiter)},f.mdy=d(f.ddd,f.month,f.day,f.year),f.ymd=d(f.ddd,f.year,f.month,f.day),f.dmy=d(f.ddd,f.day,f.month,f.year),f.date=function(a){return(f[b.dateElementOrder]||f.mdy).call(this,a)},f.format=e.process(e.many(e.any(e.process(e.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(b){if(f[b])return f[b];throw a.Parsing.Exception(b)}),e.process(e.rtoken(/^[^dMyhHmstz]+/),function(a){return e.ignore(e.stoken(a))}))),function(a){return e.process(e.each.apply(null,a),g.finishExact)});var i={},j=function(a){return i[a]=i[a]||f.format(a)[0]};f.formats=function(a){if(a instanceof Array){for(var b=[],c=0;c<a.length;c++)b.push(j(a[c]));return e.any.apply(null,b)}return j(a)},f._formats=f.formats(['"yyyy-MM-ddTHH:mm:ssZ"',"yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-ddTHH:mm:ssz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mmZ","yyyy-MM-ddTHH:mmz","yyyy-MM-ddTHH:mm","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","MMddyyyy","ddMMyyyy","Mddyyyy","ddMyyyy","Mdyyyy","dMyyyy","yyyy","Mdyy","dMyy","d"]),f._start=e.process(e.set([f.date,f.time,f.expression],f.generalDelimiter,f.whiteSpace),g.finish),f.start=function(a){try{var b=f._formats.call({},a);if(0===b[1].length)return b}catch(c){}return f._start.call({},a)},a._parse=a.parse,a.parse=function(b){var c=null;if(!b)return null;if(b instanceof Date)return b;try{c=a.Grammar.start.call({},b.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"))}catch(d){return null}return 0===c[1].length?c[0]:null},a.getParseFunction=function(b){var c=a.Grammar.formats(b);return function(a){var b=null;try{b=c.call({},a)}catch(d){return null}return 0===b[1].length?b[0]:null}},a.parseExact=function(b,c){return a.getParseFunction(c)(b)}}(),function(a,b){function c(a){return l.PF.compile(a||"nplurals=2; plural=(n != 1);")}function d(a,b){this._key=a,this._i18n=b}var e=Array.prototype,f=Object.prototype,g=e.slice,h=f.hasOwnProperty,i=e.forEach,j={},k={forEach:function(a,b,c){var d,e,f;if(null!==a)if(i&&a.forEach===i)a.forEach(b,c);else if(a.length===+a.length){for(d=0,e=a.length;e>d;d++)if(d in a&&b.call(c,a[d],d,a)===j)return}else for(f in a)if(h.call(a,f)&&b.call(c,a[f],f,a)===j)return},extend:function(a){return this.forEach(g.call(arguments,1),function(b){for(var c in b)a[c]=b[c]}),a}},l=function(a){if(this.defaults={locale_data:{messages:{"":{domain:"messages",lang:"en",plural_forms:"nplurals=2; plural=(n != 1);"}}},domain:"messages",debug:!1},this.options=k.extend({},this.defaults,a),this.textdomain(this.options.domain),a.domain&&!this.options.locale_data[this.options.domain])throw new Error("Text domain set to non-existent domain: `"+a.domain+"`")};l.context_delimiter=String.fromCharCode(4),k.extend(d.prototype,{onDomain:function(a){return this._domain=a,this},withContext:function(a){return this._context=a,this},ifPlural:function(a,b){return this._val=a,this._pkey=b,this},fetch:function(a){return"[object Array]"!={}.toString.call(a)&&(a=[].slice.call(arguments,0)),(a&&a.length?l.sprintf:function(a){return a})(this._i18n.dcnpgettext(this._domain,this._context,this._key,this._pkey,this._val),a)}}),k.extend(l.prototype,{translate:function(a){return new d(a,this)},textdomain:function(a){return a?void(this._textdomain=a):this._textdomain},gettext:function(a){return this.dcnpgettext.call(this,b,b,a)},dgettext:function(a,c){return this.dcnpgettext.call(this,a,b,c)},dcgettext:function(a,c){return this.dcnpgettext.call(this,a,b,c)},ngettext:function(a,c,d){return this.dcnpgettext.call(this,b,b,a,c,d)},dngettext:function(a,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},dcngettext:function(a,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},pgettext:function(a,c){return this.dcnpgettext.call(this,b,a,c)},dpgettext:function(a,b,c){return this.dcnpgettext.call(this,a,b,c)},dcpgettext:function(a,b,c){return this.dcnpgettext.call(this,a,b,c)},npgettext:function(a,c,d,e){return this.dcnpgettext.call(this,b,a,c,d,e)},dnpgettext:function(a,b,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},dcnpgettext:function(a,b,d,e,f){e=e||d,a=a||this._textdomain;var g;if(!this.options)return g=new l,g.dcnpgettext.call(g,void 0,void 0,d,e,f);if(!this.options.locale_data)throw new Error("No locale data provided.");if(!this.options.locale_data[a])throw new Error("Domain `"+a+"` was not found.");if(!this.options.locale_data[a][""])throw new Error("No locale meta information provided.");if(!d)throw new Error("No translation key found.");var h,i,j,k=b?b+l.context_delimiter+d:d,m=this.options.locale_data,n=m[a],o=(m.messages||this.defaults.locale_data.messages)[""],p=n[""].plural_forms||n[""]["Plural-Forms"]||n[""]["plural-forms"]||o.plural_forms||o["Plural-Forms"]||o["plural-forms"];if(void 0===f)j=0;else{if("number"!=typeof f&&(f=parseInt(f,10),isNaN(f)))throw new Error("The number that was passed in is not a number.");j=c(p)(f)}if(!n)throw new Error("No domain named `"+a+"` could be found.");return h=n[k],!h||j>h.length?(this.options.missing_key_callback&&this.options.missing_key_callback(k,a),i=[d,e],this.options.debug===!0&&console.log(i[c(p)(f)]),i[c()(f)]):(i=h[j],i?i:(i=[d,e],i[c()(f)]))}});var m=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function b(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")}var c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e,f,g,h,i,j,k,l=1,n=c.length,o="",p=[];for(f=0;n>f;f++)if(o=a(c[f]),"string"===o)p.push(c[f]);else if("array"===o){if(h=c[f],h[2])for(e=d[l],g=0;g<h[2].length;g++){if(!e.hasOwnProperty(h[2][g]))throw m('[sprintf] property "%s" does not exist',h[2][g]);e=e[h[2][g]]}else e=h[1]?d[h[1]]:d[l++];if(/[^s]/.test(h[8])&&"number"!=a(e))throw m("[sprintf] expecting number but found %s",a(e));switch(("undefined"==typeof e||null===e)&&(e=""),h[8]){case"b":e=e.toString(2);break;case"c":e=String.fromCharCode(e);break;case"d":e=parseInt(e,10);break;case"e":e=h[7]?e.toExponential(h[7]):e.toExponential();break;case"f":e=h[7]?parseFloat(e).toFixed(h[7]):parseFloat(e);break;case"o":e=e.toString(8);break;case"s":e=(e=String(e))&&h[7]?e.substring(0,h[7]):e;break;case"u":e=Math.abs(e);break;case"x":e=e.toString(16);break;case"X":e=e.toString(16).toUpperCase()}e=/[def]/.test(h[8])&&h[3]&&e>=0?"+"+e:e,j=h[4]?"0"==h[4]?"0":h[4].charAt(1):" ",k=h[6]-String(e).length,i=h[6]?b(j,k):"",p.push(h[5]?e+i:i+e)}return p.join("")},c.cache={},c.parse=function(a){for(var b=a,c=[],d=[],e=0;b;){if(null!==(c=/^[^\x25]+/.exec(b)))d.push(c[0]);else if(null!==(c=/^\x25{2}/.exec(b)))d.push("%");else{if(null===(c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b)))throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if(null===(h=/^([a-z_][a-z_\d]*)/i.exec(g)))throw"[sprintf] huh?";for(f.push(h[1]);""!==(g=g.substring(h[0].length));)if(null!==(h=/^\.([a-z_][a-z_\d]*)/i.exec(g)))f.push(h[1]);else{if(null===(h=/^\[(\d+)\]/.exec(g)))throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(3===e)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},c}(),n=function(a,b){return b.unshift(a),m.apply(null,b)};l.parse_plural=function(a,b){return a=a.replace(/n/g,b),l.parse_expression(a)},l.sprintf=function(a,b){return"[object Array]"=={}.toString.call(b)?n(a,[].slice.call(b)):m.apply(this,[].slice.call(arguments))},l.prototype.sprintf=function(){return l.sprintf.apply(this,arguments)},l.PF={},l.PF.parse=function(a){var b=l.PF.extractPluralExpr(a);return l.PF.parser.parse.call(l.PF.parser,b)},l.PF.compile=function(a){function b(a){return a===!0?1:a?a:0}var c=l.PF.parse(a);return function(a){return b(l.PF.interpreter(c)(a))}},l.PF.interpreter=function(a){return function(b){switch(a.type){case"GROUP":return l.PF.interpreter(a.expr)(b);case"TERNARY":return l.PF.interpreter(a.expr)(b)?l.PF.interpreter(a.truthy)(b):l.PF.interpreter(a.falsey)(b);case"OR":return l.PF.interpreter(a.left)(b)||l.PF.interpreter(a.right)(b);case"AND":return l.PF.interpreter(a.left)(b)&&l.PF.interpreter(a.right)(b);case"LT":return l.PF.interpreter(a.left)(b)<l.PF.interpreter(a.right)(b);case"GT":return l.PF.interpreter(a.left)(b)>l.PF.interpreter(a.right)(b);case"LTE":return l.PF.interpreter(a.left)(b)<=l.PF.interpreter(a.right)(b);case"GTE":return l.PF.interpreter(a.left)(b)>=l.PF.interpreter(a.right)(b);case"EQ":return l.PF.interpreter(a.left)(b)==l.PF.interpreter(a.right)(b);case"NEQ":return l.PF.interpreter(a.left)(b)!=l.PF.interpreter(a.right)(b);case"MOD":return l.PF.interpreter(a.left)(b)%l.PF.interpreter(a.right)(b);case"VAR":return b;case"NUM":return a.val;default:throw new Error("Invalid Token found.")}}},l.PF.extractPluralExpr=function(a){a=a.replace(/^\s\s*/,"").replace(/\s\s*$/,""),/;\s*$/.test(a)||(a=a.concat(";"));var b,c=/nplurals\=(\d+);/,d=/plural\=(.*);/,e=a.match(c),f={};if(!(e.length>1))throw new Error("nplurals not found in plural_forms string: "+a);if(f.nplurals=e[1],a=a.replace(c,""),b=a.match(d),!(b&&b.length>1))throw new Error("`plural` expression not found: "+a);return b[1]},l.PF.parser=function(){var a={trace:function(){},yy:{},symbols_:{error:2,expressions:3,e:4,EOF:5,"?":6,":":7,"||":8,"&&":9,"<":10,"<=":11,">":12,">=":13,"!=":14,"==":15,"%":16,"(":17,")":18,n:19,NUMBER:20,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",6:"?",7:":",8:"||",9:"&&",10:"<",11:"<=",12:">",13:">=",14:"!=",15:"==",16:"%",17:"(",18:")",19:"n",20:"NUMBER"},productions_:[0,[3,2],[4,5],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,1],[4,1]],performAction:function(a,b,c,d,e,f,g){var h=f.length-1;switch(e){case 1:return{type:"GROUP",expr:f[h-1]};case 2:this.$={type:"TERNARY",expr:f[h-4],truthy:f[h-2],falsey:f[h]};break;case 3:this.$={type:"OR",left:f[h-2],right:f[h]};break;case 4:this.$={type:"AND",left:f[h-2],right:f[h]};break;case 5:this.$={type:"LT",left:f[h-2],right:f[h]};break;case 6:this.$={type:"LTE",left:f[h-2],right:f[h]};break;case 7:this.$={type:"GT",left:f[h-2],right:f[h]};break;case 8:this.$={type:"GTE",left:f[h-2],right:f[h]};break;case 9:this.$={type:"NEQ",left:f[h-2],right:f[h]};break;case 10:this.$={type:"EQ",left:f[h-2],right:f[h]};break;case 11:this.$={type:"MOD",left:f[h-2],right:f[h]};break;case 12:this.$={type:"GROUP",expr:f[h-1]};break;case 13:this.$={type:"VAR"};break;case 14:this.$={type:"NUM",val:Number(a)}}},table:[{3:1,4:2,17:[1,3],19:[1,4],20:[1,5]},{1:[3]},{5:[1,6],6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{4:17,17:[1,3],19:[1,4],20:[1,5]},{5:[2,13],6:[2,13],7:[2,13],8:[2,13],9:[2,13],10:[2,13],11:[2,13],12:[2,13],13:[2,13],14:[2,13],15:[2,13],16:[2,13],18:[2,13]},{5:[2,14],6:[2,14],7:[2,14],8:[2,14],9:[2,14],10:[2,14],11:[2,14],12:[2,14],13:[2,14],14:[2,14],15:[2,14],16:[2,14],18:[2,14]},{1:[2,1]},{4:18,17:[1,3],19:[1,4],20:[1,5]},{4:19,17:[1,3],19:[1,4],20:[1,5]},{4:20,17:[1,3],19:[1,4],20:[1,5]},{4:21,17:[1,3],19:[1,4],20:[1,5]},{4:22,17:[1,3],19:[1,4],20:[1,5]},{4:23,17:[1,3],19:[1,4],20:[1,5]},{4:24,17:[1,3],19:[1,4],20:[1,5]},{4:25,17:[1,3],19:[1,4],20:[1,5]},{4:26,17:[1,3],19:[1,4],20:[1,5]},{4:27,17:[1,3],19:[1,4],20:[1,5]},{6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[1,28]},{6:[1,7],7:[1,29],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{5:[2,3],6:[2,3],7:[2,3],8:[2,3],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,3]},{5:[2,4],6:[2,4],7:[2,4],8:[2,4],9:[2,4],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,4]},{5:[2,5],6:[2,5],7:[2,5],8:[2,5],9:[2,5],10:[2,5],11:[2,5],12:[2,5],13:[2,5],14:[2,5],15:[2,5],16:[1,16],18:[2,5]},{5:[2,6],6:[2,6],7:[2,6],8:[2,6],9:[2,6],10:[2,6],11:[2,6],12:[2,6],13:[2,6],14:[2,6],15:[2,6],16:[1,16],18:[2,6]},{5:[2,7],6:[2,7],7:[2,7],8:[2,7],9:[2,7],10:[2,7],11:[2,7],12:[2,7],13:[2,7],14:[2,7],15:[2,7],16:[1,16],18:[2,7]},{5:[2,8],6:[2,8],7:[2,8],8:[2,8],9:[2,8],10:[2,8],11:[2,8],12:[2,8],13:[2,8],14:[2,8],15:[2,8],16:[1,16],18:[2,8]},{5:[2,9],6:[2,9],7:[2,9],8:[2,9],9:[2,9],10:[2,9],11:[2,9],12:[2,9],13:[2,9],14:[2,9],15:[2,9],16:[1,16],18:[2,9]},{5:[2,10],6:[2,10],7:[2,10],8:[2,10],9:[2,10],10:[2,10],11:[2,10],12:[2,10],13:[2,10],14:[2,10],15:[2,10],16:[1,16],18:[2,10]},{5:[2,11],6:[2,11],7:[2,11],8:[2,11],9:[2,11],10:[2,11],11:[2,11],12:[2,11],13:[2,11],14:[2,11],15:[2,11],16:[2,11],18:[2,11]},{5:[2,12],6:[2,12],7:[2,12],8:[2,12],9:[2,12],10:[2,12],11:[2,12],12:[2,12],13:[2,12],14:[2,12],15:[2,12],16:[2,12],18:[2,12]},{4:30,17:[1,3],19:[1,4],20:[1,5]},{5:[2,2],6:[1,7],7:[2,2],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,2]}],defaultActions:{6:[2,1]},parseError:function(a,b){throw new Error(a)},parse:function(a){function b(a){e.length=e.length-2*a,f.length=f.length-a,g.length=g.length-a}function c(){var a;return a=d.lexer.lex()||1,"number"!=typeof a&&(a=d.symbols_[a]||a),a}var d=this,e=[0],f=[null],g=[],h=this.table,i="",j=0,k=0,l=0,m=2,n=1;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var o=this.lexer.yylloc;g.push(o),"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var p,q,r,s,t,u,v,w,x,y={};;){if(r=e[e.length-1],this.defaultActions[r]?s=this.defaultActions[r]:(null==p&&(p=c()),s=h[r]&&h[r][p]),"undefined"==typeof s||!s.length||!s[0]){if(!l){x=[];for(u in h[r])this.terminals_[u]&&u>2&&x.push("'"+this.terminals_[u]+"'");var z="";z=this.lexer.showPosition?"Parse error on line "+(j+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+x.join(", ")+", got '"+this.terminals_[p]+"'":"Parse error on line "+(j+1)+": Unexpected "+(1==p?"end of input":"'"+(this.terminals_[p]||p)+"'"),this.parseError(z,{text:this.lexer.match,token:this.terminals_[p]||p,line:this.lexer.yylineno,loc:o,expected:x})}if(3==l){if(p==n)throw new Error(z||"Parsing halted.");k=this.lexer.yyleng,i=this.lexer.yytext,j=this.lexer.yylineno,o=this.lexer.yylloc,p=c()}for(;;){if(m.toString()in h[r])break;if(0==r)throw new Error(z||"Parsing halted.");b(1),r=e[e.length-1]}q=p,p=m,r=e[e.length-1],s=h[r]&&h[r][m],l=3}if(s[0]instanceof Array&&s.length>1)throw new Error("Parse Error: multiple actions possible at state: "+r+", token: "+p);switch(s[0]){case 1:e.push(p),f.push(this.lexer.yytext),g.push(this.lexer.yylloc),e.push(s[1]),p=null,q?(p=q,q=null):(k=this.lexer.yyleng,i=this.lexer.yytext,j=this.lexer.yylineno,o=this.lexer.yylloc,l>0&&l--);break;case 2:if(v=this.productions_[s[1]][1],y.$=f[f.length-v],y._$={first_line:g[g.length-(v||1)].first_line,last_line:g[g.length-1].last_line,first_column:g[g.length-(v||1)].first_column,last_column:g[g.length-1].last_column},t=this.performAction.call(y,i,k,j,this.yy,s[1],f,g),"undefined"!=typeof t)return t;v&&(e=e.slice(0,-1*v*2),f=f.slice(0,-1*v),g=g.slice(0,-1*v)),e.push(this.productions_[s[1]][0]),f.push(y.$),g.push(y._$),w=h[e[e.length-2]][e[e.length-1]],e.push(w);break;case 3:return!0}}return!0}},b=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parseError)throw new Error(a);this.yy.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.match+=a,this.matched+=a;var b=a.match(/\n/);return b&&this.yylineno++,this._input=this._input.slice(1),a},unput:function(a){return this._input=a+this._input,this},more:function(){return this._more=!0,this},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c;this._more||(this.yytext="",this.match="");for(var d=this._currentRules(),e=0;e<d.length;e++)if(b=this._input.match(this.rules[d[e]]))return c=b[0].match(/\n.*/g),c&&(this.yylineno+=c.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:c?c[c.length-1].length-1:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,d[e],this.conditionStack[this.conditionStack.length-1]),a?a:void 0;return""===this._input?this.EOF:void this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.performAction=function(a,b,c,d){switch(c){case 0:break;case 1:return 20;case 2:return 19;case 3:return 8;case 4:return 9;case 5:return 6;case 6:return 7;case 7:return 11;case 8:return 13;case 9:return 10;case 10:return 12;case 11:return 14;case 12:return 15;case 13:return 16;case 14:return 17;case 15:return 18;case 16:return 5;case 17:return"INVALID"}},a.rules=[/^\s+/,/^[0-9]+(\.[0-9]+)?\b/,/^n\b/,/^\|\|/,/^&&/,/^\?/,/^:/,/^<=/,/^>=/,/^</,/^>/,/^!=/,/^==/,/^%/,/^\(/,/^\)/,/^$/,/^./],a.conditions={INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],inclusive:!0}},a}();return a.lexer=b,a}(),"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=l),exports.Jed=l):("function"==typeof define&&define.amd&&define(function(){return l}),a.Jed=l)}(this),function(a){function b(a){return{jsonrpc:"2.0",method:a.method||"",params:a.params||{},id:g++}}function c(c){var d=a.isArray(c)?c.map(b):b(c);return JSON.stringify(d)}function d(a){return a.sort(e)}function e(a,b){return a.id<b.id?-1:1}function f(b,e){var f=new a.Deferred;e=e||{};var g=e.success||h,i=e.error||h;delete e.success,delete e.error;var j=a.isArray(b),k=a.extend({url:(j?b[0].url:b.url)||a.jsonrpc.defaultUrl,contentType:"application/json",dataType:"text",dataFilter:function(a,b){return JSON.parse(a)},type:"POST",processData:!1,data:c(b),success:function(a){if(j){var b=d(a);return g(b),void f.resolve(b)}if(a.hasOwnProperty("error"))return i(a.error),void f.reject(a.error);if(a.hasOwnProperty("result"))return g(a.result),void f.resolve(a.result);throw"Invalid response returned"},error:function(a,b,c){var d=null;if("timeout"===c)d={status:b,code:-32e3,message:"Request Timeout",data:null};else try{var e=JSON.parse(a.responseText);d=e.error}catch(g){d={status:b,code:-32603,message:c,data:a.responseText}}i(d),f.reject(d)}},e);return a.ajax(k),f.promise()}var g=1,h=function(){};a.extend({jsonrpc:f}),a.jsonrpc.defaultUrl="/jsonrpc"}(jQuery),!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document),function(a){"use strict";function b(a,b){return Math.round(a/b)*b}function c(a){return"number"==typeof a&&!isNaN(a)&&isFinite(a)}function d(a){ -var b=Math.pow(10,7);return Number((Math.round(a*b)/b).toFixed(7))}function e(a,b,c){a.addClass(b),setTimeout(function(){a.removeClass(b)},c)}function f(a){return Math.max(Math.min(a,100),0)}function g(b){return a.isArray(b)?b:[b]}function h(a){var b=a.split(".");return b.length>1?b[1].length:0}function i(a,b){return 100/(b-a)}function j(a,b){return 100*b/(a[1]-a[0])}function k(a,b){return j(a,a[0]<0?b+Math.abs(a[0]):b-a[0])}function l(a,b){return b*(a[1]-a[0])/100+a[0]}function m(a,b){for(var c=1;a>=b[c];)c+=1;return c}function n(a,b,c){if(c>=a.slice(-1)[0])return 100;var d,e,f,g,h=m(c,a);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],f+k([d,e],c)/i(f,g)}function o(a,b,c){if(c>=100)return a.slice(-1)[0];var d,e,f,g,h=m(c,b);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],l([d,e],(c-f)*i(f,g))}function p(a,c,d,e){if(100===e)return e;var f,g,h=m(e,a);return d?(f=a[h-1],g=a[h],e-f>(g-f)/2?g:f):c[h-1]?a[h-1]+b(e-a[h-1],c[h-1]):e}function q(a,b,d){var e;if("number"==typeof b&&(b=[b]),"[object Array]"!==Object.prototype.toString.call(b))throw new Error("noUiSlider: 'range' contains invalid value.");if(e="min"===a?0:"max"===a?100:parseFloat(a),!c(e)||!c(b[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");d.xPct.push(e),d.xVal.push(b[0]),e?d.xSteps.push(isNaN(b[1])?!1:b[1]):isNaN(b[1])||(d.xSteps[0]=b[1])}function r(a,b,c){return b?void(c.xSteps[a]=j([c.xVal[a],c.xVal[a+1]],b)/i(c.xPct[a],c.xPct[a+1])):!0}function s(a,b,c,d){this.xPct=[],this.xVal=[],this.xSteps=[d||!1],this.xNumSteps=[!1],this.snap=b,this.direction=c;var e,f=[];for(e in a)a.hasOwnProperty(e)&&f.push([a[e],e]);for(f.sort(function(a,b){return a[0]-b[0]}),e=0;e<f.length;e++)q(f[e][1],f[e][0],this);for(this.xNumSteps=this.xSteps.slice(0),e=0;e<this.xNumSteps.length;e++)r(e,this.xNumSteps[e],this)}function t(a,b){if(!c(b))throw new Error("noUiSlider: 'step' is not numeric.");a.singleStep=b}function u(b,c){if("object"!=typeof c||a.isArray(c))throw new Error("noUiSlider: 'range' is not an object.");if(void 0===c.min||void 0===c.max)throw new Error("noUiSlider: Missing 'min' or 'max' in 'range'.");b.spectrum=new s(c,b.snap,b.dir,b.singleStep)}function v(b,c){if(c=g(c),!a.isArray(c)||!c.length||c.length>2)throw new Error("noUiSlider: 'start' option is incorrect.");b.handles=c.length,b.start=c}function w(a,b){if(a.snap=b,"boolean"!=typeof b)throw new Error("noUiSlider: 'snap' option must be a boolean.")}function x(a,b){if(a.animate=b,"boolean"!=typeof b)throw new Error("noUiSlider: 'animate' option must be a boolean.")}function y(a,b){if("lower"===b&&1===a.handles)a.connect=1;else if("upper"===b&&1===a.handles)a.connect=2;else if(b===!0&&2===a.handles)a.connect=3;else{if(b!==!1)throw new Error("noUiSlider: 'connect' option doesn't match handle count.");a.connect=0}}function z(a,b){switch(b){case"horizontal":a.ort=0;break;case"vertical":a.ort=1;break;default:throw new Error("noUiSlider: 'orientation' option is invalid.")}}function A(a,b){if(!c(b))throw new Error("noUiSlider: 'margin' option must be numeric.");if(a.margin=a.spectrum.getMargin(b),!a.margin)throw new Error("noUiSlider: 'margin' option is only supported on linear sliders.")}function B(a,b){if(!c(b))throw new Error("noUiSlider: 'limit' option must be numeric.");if(a.limit=a.spectrum.getMargin(b),!a.limit)throw new Error("noUiSlider: 'limit' option is only supported on linear sliders.")}function C(a,b){switch(b){case"ltr":a.dir=0;break;case"rtl":a.dir=1,a.connect=[0,2,1,3][a.connect];break;default:throw new Error("noUiSlider: 'direction' option was not recognized.")}}function D(a,b){if("string"!=typeof b)throw new Error("noUiSlider: 'behaviour' must be a string containing options.");var c=b.indexOf("tap")>=0,d=b.indexOf("drag")>=0,e=b.indexOf("fixed")>=0,f=b.indexOf("snap")>=0;a.events={tap:c||f,drag:d,fixed:e,snap:f}}function E(a,b){if(a.format=b,"function"==typeof b.to&&"function"==typeof b.from)return!0;throw new Error("noUiSlider: 'format' requires 'to' and 'from' methods.")}function F(b){var c,d={margin:0,limit:0,animate:!0,format:V};return c={step:{r:!1,t:t},start:{r:!0,t:v},connect:{r:!0,t:y},direction:{r:!0,t:C},snap:{r:!1,t:w},animate:{r:!1,t:x},range:{r:!0,t:u},orientation:{r:!1,t:z},margin:{r:!1,t:A},limit:{r:!1,t:B},behaviour:{r:!0,t:D},format:{r:!1,t:E}},b=a.extend({connect:!1,direction:"ltr",behaviour:"tap",orientation:"horizontal"},b),a.each(c,function(a,c){if(void 0===b[a]){if(c.r)throw new Error("noUiSlider: '"+a+"' is required.");return!0}c.t(d,b[a])}),d.style=d.ort?"top":"left",d}function G(a,b,c){var d=a+b[0],e=a+b[1];return c?(0>d&&(e+=Math.abs(d)),e>100&&(d-=e-100),[f(d),f(e)]):[d,e]}function H(a){a.preventDefault();var b,c,d=0===a.type.indexOf("touch"),e=0===a.type.indexOf("mouse"),f=0===a.type.indexOf("pointer"),g=a;return 0===a.type.indexOf("MSPointer")&&(f=!0),a.originalEvent&&(a=a.originalEvent),d&&(b=a.changedTouches[0].pageX,c=a.changedTouches[0].pageY),(e||f)&&(f||void 0!==window.pageXOffset||(window.pageXOffset=document.documentElement.scrollLeft,window.pageYOffset=document.documentElement.scrollTop),b=a.clientX+window.pageXOffset,c=a.clientY+window.pageYOffset),g.points=[b,c],g.cursor=e,g}function I(b,c){var d=a("<div><div/></div>").addClass(U[2]),e=["-lower","-upper"];return b&&e.reverse(),d.children().addClass(U[3]+" "+U[3]+e[c]),d}function J(a,b,c){switch(a){case 1:b.addClass(U[7]),c[0].addClass(U[6]);break;case 3:c[1].addClass(U[6]);case 2:c[0].addClass(U[7]);case 0:b.addClass(U[6])}}function K(a,b,c){var d,e=[];for(d=0;a>d;d+=1)e.push(I(b,d).appendTo(c));return e}function L(b,c,d){return d.addClass([U[0],U[8+b],U[4+c]].join(" ")),a("<div/>").appendTo(d).addClass(U[1])}function M(b,c,d){function i(){return C[["width","height"][c.ort]]()}function j(a){var b,c=[E.val()];for(b=0;b<a.length;b+=1)E.trigger(a[b],c)}function k(a){return 1===a.length?a[0]:c.dir?a.reverse():a}function l(a){return function(b,c){E.val([a?null:c,a?c:null],!0)}}function m(b){var c=a.inArray(b,N);E[0].linkAPI&&E[0].linkAPI[b]&&E[0].linkAPI[b].change(M[c],D[c].children(),E)}function n(b,d){var e=a.inArray(b,N);return d&&d.appendTo(D[e].children()),c.dir&&c.handles>1&&(e=1===e?0:1),l(e)}function o(){var a,b;for(a=0;a<N.length;a+=1)this.linkAPI&&this.linkAPI[b=N[a]]&&this.linkAPI[b].reconfirm(b)}function p(a,b,d,e){return a=a.replace(/\s/g,S+" ")+S,b.on(a,function(a){return E.attr("disabled")?!1:E.hasClass(U[14])?!1:(a=H(a),a.calcPoint=a.points[c.ort],void d(a,e))})}function q(a,b){var c,d=b.handles||D,e=!1,f=100*(a.calcPoint-b.start)/i(),g=d[0][0]!==D[0][0]?1:0;c=G(f,b.positions,d.length>1),e=v(d[0],c[g],1===d.length),d.length>1&&(e=v(d[1],c[g?0:1],!1)||e),e&&j(["slide"])}function r(b){a("."+U[15]).removeClass(U[15]),b.cursor&&a("body").css("cursor","").off(S),Q.off(S),E.removeClass(U[12]),j(["set","change"])}function s(b,c){1===c.handles.length&&c.handles[0].children().addClass(U[15]),b.stopPropagation(),p(T.move,Q,q,{start:b.calcPoint,handles:c.handles,positions:[F[0],F[D.length-1]]}),p(T.end,Q,r,null),b.cursor&&(a("body").css("cursor",a(b.target).css("cursor")),D.length>1&&E.addClass(U[12]),a("body").on("selectstart"+S,!1))}function t(b){var d,f=b.calcPoint,g=0;b.stopPropagation(),a.each(D,function(){g+=this.offset()[c.style]}),g=g/2>f||1===D.length?0:1,f-=C.offset()[c.style],d=100*f/i(),c.events.snap||e(E,U[14],300),v(D[g],d),j(["slide","set","change"]),c.events.snap&&s(b,{handles:[D[g]]})}function u(a){var b,c;if(!a.fixed)for(b=0;b<D.length;b+=1)p(T.start,D[b].children(),s,{handles:[D[b]]});a.tap&&p(T.start,C,t,{handles:D}),a.drag&&(c=C.find("."+U[7]).addClass(U[10]),a.fixed&&(c=c.add(C.children().not(c).children())),p(T.start,c,s,{handles:D}))}function v(a,b,d){var e=a[0]!==D[0][0]?1:0,g=F[0]+c.margin,h=F[1]-c.margin,i=F[0]+c.limit,j=F[1]-c.limit;return D.length>1&&(b=e?Math.max(b,g):Math.min(b,h)),d!==!1&&c.limit&&D.length>1&&(b=e?Math.min(b,i):Math.max(b,j)),b=I.getStep(b),b=f(parseFloat(b.toFixed(7))),b===F[e]?!1:(a.css(c.style,b+"%"),a.is(":first-child")&&a.toggleClass(U[17],b>50),F[e]=b,M[e]=I.fromStepping(b),m(N[e]),!0)}function w(a,b){var d,e,f;for(c.limit&&(a+=1),d=0;a>d;d+=1)e=d%2,f=b[e],null!==f&&f!==!1&&("number"==typeof f&&(f=String(f)),f=c.format.from(f),(f===!1||isNaN(f)||v(D[e],I.toStepping(f),d===3-c.dir)===!1)&&m(N[e]))}function x(a){if(E[0].LinkIsEmitting)return this;var b,d=g(a);return c.dir&&c.handles>1&&d.reverse(),c.animate&&-1!==F[0]&&e(E,U[14],300),b=D.length>1?3:1,1===d.length&&(b=1),w(b,d),j(["set"]),this}function y(){var a,b=[];for(a=0;a<c.handles;a+=1)b[a]=c.format.to(M[a]);return k(b)}function z(){return a(this).off(S).removeClass(U.join(" ")).empty(),delete this.LinkUpdate,delete this.LinkConfirm,delete this.LinkDefaultFormatter,delete this.LinkDefaultFlag,delete this.reappend,delete this.vGet,delete this.vSet,delete this.getCurrentStep,delete this.getInfo,delete this.destroy,d}function A(){var b=a.map(F,function(a,b){var c=I.getApplicableStep(a),d=h(String(c[2])),e=M[b],f=100===a?null:c[2],g=Number((e-c[2]).toFixed(d)),i=0===a?null:g>=c[1]?c[2]:c[0]||!1;return[[i,f]]});return k(b)}function B(){return d}var C,D,E=a(b),F=[-1,-1],I=c.spectrum,M=[],N=["lower","upper"].slice(0,c.handles);if(c.dir&&N.reverse(),b.LinkUpdate=m,b.LinkConfirm=n,b.LinkDefaultFormatter=c.format,b.LinkDefaultFlag="lower",b.reappend=o,E.hasClass(U[0]))throw new Error("Slider was already initialized.");C=L(c.dir,c.ort,E),D=K(c.handles,c.dir,C),J(c.connect,E,D),u(c.events),b.vSet=x,b.vGet=y,b.destroy=z,b.getCurrentStep=A,b.getOriginalOptions=B,b.getInfo=function(){return[I,c.style,c.ort]},E.val(c.start)}function N(a){var b=F(a,this);return this.each(function(){M(this,b,a)})}function O(b){return this.each(function(){if(!this.destroy)return void a(this).noUiSlider(b);var c=a(this).val(),d=this.destroy(),e=a.extend({},d,b);a(this).noUiSlider(e),this.reappend(),d.start===e.start&&a(this).val(c)})}function P(){return this[0][arguments.length?"vSet":"vGet"].apply(this[0],arguments)}var Q=a(document),R=a.fn.val,S=".nui",T=window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"},U=["noUi-target","noUi-base","noUi-origin","noUi-handle","noUi-horizontal","noUi-vertical","noUi-background","noUi-connect","noUi-ltr","noUi-rtl","noUi-dragable","","noUi-state-drag","","noUi-state-tap","noUi-active","","noUi-stacking"];s.prototype.getMargin=function(a){return 2===this.xPct.length?j(this.xVal,a):!1},s.prototype.toStepping=function(a){return a=n(this.xVal,this.xPct,a),this.direction&&(a=100-a),a},s.prototype.fromStepping=function(a){return this.direction&&(a=100-a),d(o(this.xVal,this.xPct,a))},s.prototype.getStep=function(a){return this.direction&&(a=100-a),a=p(this.xPct,this.xSteps,this.snap,a),this.direction&&(a=100-a),a},s.prototype.getApplicableStep=function(a){var b=m(a,this.xPct),c=100===a?2:1;return[this.xNumSteps[b-2],this.xVal[b-c],this.xNumSteps[b-c]]},s.prototype.convert=function(a){return this.getStep(this.toStepping(a))};var V={to:function(a){return a.toFixed(2)},from:Number};a.fn.val=function(b){function c(a){return a.hasClass(U[0])?P:R}if(!arguments.length){var d=a(this[0]);return c(d).call(d)}var e=a.isFunction(b);return this.each(function(d){var f=b,g=a(this);e&&(f=b.call(this,d,g.val())),c(g).call(g,f)})},a.fn.noUiSlider=function(a,b){switch(a){case"step":return this[0].getCurrentStep();case"options":return this[0].getOriginalOptions()}return(b?O:N).call(this,a)}}(window.jQuery||window.Zepto),function(a){"use strict";"object"==typeof exports?a(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b=function(a){if(a=a||"once","string"!=typeof a)throw new Error("The jQuery Once id parameter must be a string");return a};a.fn.once=function(c){var d="jquery-once-"+b(c);return this.filter(function(){return a(this).data(d)!==!0}).data(d,!0)},a.fn.removeOnce=function(a){return this.findOnce(a).removeData("jquery-once-"+b(a))},a.fn.findOnce=function(c){var d="jquery-once-"+b(c);return this.filter(function(){return a(this).data(d)===!0})}}),function(a){var b=a(window);a.fn.visible=function(a,c,d){if(!(this.length<1)){var e=this.length>1?this.eq(0):this,f=e.get(0),g=b.width(),h=b.height(),d=d?d:"both",i=c===!0?f.offsetWidth*f.offsetHeight:!0;if("function"==typeof f.getBoundingClientRect){var j=f.getBoundingClientRect(),k=j.top>=0&&j.top<h,l=j.bottom>0&&j.bottom<=h,m=j.left>=0&&j.left<g,n=j.right>0&&j.right<=g,o=a?k||l:k&&l,p=a?m||n:m&&n;if("both"===d)return i&&o&&p;if("vertical"===d)return i&&o;if("horizontal"===d)return i&&p}else{var q=b.scrollTop(),r=q+h,s=b.scrollLeft(),t=s+g,u=e.offset(),v=u.top,w=v+e.height(),x=u.left,y=x+e.width(),z=a===!0?w:v,A=a===!0?v:w,B=a===!0?y:x,C=a===!0?x:y;if("both"===d)return!!i&&r>=A&&z>=q&&t>=C&&B>=s;if("vertical"===d)return!!i&&r>=A&&z>=q;if("horizontal"===d)return!!i&&t>=C&&B>=s}}}}(jQuery),window.JST||(window.JST={});var prettyPrint=function(){var a={el:function(b,c){var d,e=document.createElement(b);if(c=a.merge({},c),c&&c.style){c.style;a.applyCSS(e,c.style),delete c.style}for(d in c)c.hasOwnProperty(d)&&(e[d]=c[d]);return e},applyCSS:function(a,b){for(var c in b)if(b.hasOwnProperty(c))try{a.style[c]=b[c]}catch(d){}},txt:function(a){return document.createTextNode(a)},row:function(b,c,d){d=d||"td";var e,f=a.count(b,null)+1,g=a.el("tr"),h={style:a.getStyles(d,c),colSpan:f,onmouseover:function(){var b=this.parentNode.childNodes;a.forEach(b,function(b){"td"===b.nodeName.toLowerCase()&&a.applyCSS(b,a.getStyles("td_hover",c))})},onmouseout:function(){var b=this.parentNode.childNodes;a.forEach(b,function(b){"td"===b.nodeName.toLowerCase()&&a.applyCSS(b,a.getStyles("td",c))})}};return a.forEach(b,function(b){null!==b&&(e=a.el(d,h),b.nodeType?e.appendChild(b):e.innerHTML=a.shorten(b.toString()),g.appendChild(e))}),g},hRow:function(b,c){return a.row(b,c,"th")},table:function(b,c){b=b||[];var d={thead:{style:a.getStyles("thead",c)},tbody:{style:a.getStyles("tbody",c)},table:{style:a.getStyles("table",c)}},e=a.el("table",d.table),f=a.el("thead",d.thead),g=a.el("tbody",d.tbody);return b.length&&(e.appendChild(f),f.appendChild(a.hRow(b,c))),e.appendChild(g),{node:e,tbody:g,thead:f,appendChild:function(a){this.tbody.appendChild(a)},addRow:function(b,d,e){return this.appendChild(a.row.call(a,b,d||c,e)),this}}},shorten:function(a){return a},htmlentities:function(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")},merge:function(b,c){"object"!=typeof b&&(b={});for(var d in c)if(c.hasOwnProperty(d)){var e=c[d];if("object"==typeof e){b[d]=a.merge(b[d],e);continue}b[d]=e}for(var f=2,g=arguments.length;g>f;f++)a.merge(b,arguments[f]);return b},count:function(a,b){for(var c=0,d=0,e=a.length;e>d;d++)a[d]===b&&c++;return c},thead:function(a){return a.getElementsByTagName("thead")[0]},forEach:function(a,b,c){c||(c=b);for(var d=a.length,e=-1;++e<d&&c(a[e],e,a)!==!1;);return!0},type:function(a){try{if(null===a)return"null";if(void 0===a)return"undefined";var b=Object.prototype.toString.call(a).match(/\s(.+?)\]/)[1].toLowerCase();return a.nodeType?1===a.nodeType?"domelement":"domnode":/^(string|number|array|regexp|function|date|boolean)$/.test(b)?b:"object"==typeof a?a.jquery&&"string"==typeof a.jquery?"jquery":"object":a===window||a===document?"object":"default"}catch(c){return"default"}},within:function(a){return{is:function(b){for(var c in a)if(a[c]===b)return c;return""}}},common:{circRef:function(c,d,e){return a.expander("[POINTS BACK TO <strong>"+d+"</strong>]","Click to show this item anyway",function(){this.parentNode.appendChild(b(c,{maxDepth:1}))})},depthReached:function(c,d){return a.expander("[DEPTH REACHED]","Click to show this item anyway",function(){try{this.parentNode.appendChild(b(c,{maxDepth:1}))}catch(d){this.parentNode.appendChild(a.table(["ERROR OCCURED DURING OBJECT RETRIEVAL"],"error").addRow([d.message]).node)}})}},getStyles:function(c,d){return d=b.settings.styles[d]||{},a.merge({},b.settings.styles["default"][c],d[c])},expander:function(b,c,d){return a.el("a",{innerHTML:a.shorten(b)+' <b style="visibility:hidden;">[+]</b>',title:c,onmouseover:function(){this.getElementsByTagName("b")[0].style.visibility="visible"},onmouseout:function(){this.getElementsByTagName("b")[0].style.visibility="hidden"},onclick:function(){return this.style.display="none",d.call(this),!1},style:{cursor:"pointer"}})},stringify:function(b){var c,d=a.type(b),e=!0;if("array"===d)return c="[",a.forEach(b,function(b,d){c+=(0===d?"":", ")+a.stringify(b)}),c+"]";if("object"==typeof b){c="{";for(var f in b)b.hasOwnProperty(f)&&(c+=(e?"":", ")+f+":"+a.stringify(b[f]),e=!1);return c+"}"}return"regexp"===d?"/"+b.source+"/":"string"===d?'"'+b.replace(/"/g,'\\"')+'"':b.toString()},headerGradient:function(){var a=document.createElement("canvas");if(!a.getContext)return"";var b=a.getContext("2d");a.height=30,a.width=1;var c=b.createLinearGradient(0,0,0,30);c.addColorStop(0,"rgba(0,0,0,0)"),c.addColorStop(1,"rgba(0,0,0,0.25)"),b.fillStyle=c,b.fillRect(0,0,1,30);var d=a.toDataURL&&a.toDataURL();return"url("+(d||"")+")"}()},b=function(c,d){d=d||{};var e=a.merge({},b.config,d),f=a.el("div"),g=(b.config,0),h={},i=!1;b.settings=e;var j={string:function(b){return a.txt('"'+a.shorten(b.replace(/"/g,'\\"'))+'"')},number:function(b){return a.txt(b)},regexp:function(b){var c=a.table(["RegExp",null],"regexp"),d=a.table(),f=a.expander("/"+b.source+"/","Click to show more",function(){this.parentNode.appendChild(c.node)});return d.addRow(["g",b.global]).addRow(["i",b.ignoreCase]).addRow(["m",b.multiline]),c.addRow(["source","/"+b.source+"/"]).addRow(["flags",d.node]).addRow(["lastIndex",b.lastIndex]),e.expanded?c.node:f},domelement:function(b,c){var d=a.table(["DOMElement",null],"domelement"),f=["id","className","innerHTML","src","href"],g=b.nodeName||"";return d.addRow(["tag","<"+g.toLowerCase()+">"]),a.forEach(f,function(c){b[c]&&d.addRow([c,a.htmlentities(b[c])])}),e.expanded?d.node:a.expander("DOMElement ("+g.toLowerCase()+")","Click to show more",function(){this.parentNode.appendChild(d.node)})},domnode:function(b){var c=a.table(["DOMNode",null],"domelement"),d=a.htmlentities((b.data||"UNDEFINED").replace(/\n/g,"\\n"));return c.addRow(["nodeType",b.nodeType+" ("+b.nodeName+")"]).addRow(["data",d]),e.expanded?c.node:a.expander("DOMNode","Click to show more",function(){this.parentNode.appendChild(c.node)})},jquery:function(a,b,c){return j.array(a,b,c,!0)},object:function(b,c,d){var f=a.within(h).is(b);if(f)return a.common.circRef(b,f,e);if(h[d||"TOP"]=b,c===e.maxDepth)return a.common.depthReached(b,e);var g=a.table(["Object",null],"object"),k=!0;for(var l in b)if(!b.hasOwnProperty||b.hasOwnProperty(l)){var m=b[l],n=a.type(m);k=!1;try{g.addRow([l,j[n](m,c+1,l)],n)}catch(o){window.console&&window.console.log&&console.log(o.message)}}k?g.addRow(["<small>[empty]</small>"]):g.thead.appendChild(a.hRow(["key","value"],"colHeader"));var p=e.expanded||i?g.node:a.expander(a.stringify(b),"Click to show more",function(){this.parentNode.appendChild(g.node)});return i=!0,p},array:function(b,c,d,f){var g=a.within(h).is(b);if(g)return a.common.circRef(b,g);if(h[d||"TOP"]=b,c===e.maxDepth)return a.common.depthReached(b);var i=f?"jQuery":"Array",k=a.table([i+"("+b.length+")",null],f?"jquery":i.toLowerCase()),l=!0,m=0;return f&&k.addRow(["selector",b.selector]),a.forEach(b,function(d,f){return e.maxArray>=0&&++m>e.maxArray?(k.addRow([f+".."+(b.length-1),j[a.type(d)]("...",c+1,f)]),!1):(l=!1,void k.addRow([f,j[a.type(d)](d,c+1,f)]))}),f||(l?k.addRow(["<small>[empty]</small>"]):k.thead.appendChild(a.hRow(["index","value"],"colHeader"))),e.expanded?k.node:a.expander(a.stringify(b),"Click to show more",function(){this.parentNode.appendChild(k.node)})},"function":function(b,c,d){var f=a.within(h).is(b);if(f)return a.common.circRef(b,f);h[d||"TOP"]=b;var g=a.table(["Function",null],"function"),i=(a.table(["Arguments"]),b.toString().match(/\((.+?)\)/)),j=b.toString().match(/\(.*?\)\s+?\{?([\S\s]+)/)[1].replace(/\}?$/,"");return g.addRow(["arguments",i?i[1].replace(/[^\w_,\s]/g,""):"<small>[none/native]</small>"]).addRow(["body",j]),e.expanded?g.node:a.expander("function(){...}","Click to see more about this function.",function(){this.parentNode.appendChild(g.node)})},date:function(b){var c=a.table(["Date",null],"date"),d=b.toString().split(/\s/);return c.addRow(["Time",d[4]]).addRow(["Date",d.slice(0,4).join("-")]),e.expanded?c.node:a.expander("Date (timestamp): "+ +b,"Click to see a little more info about this date",function(){this.parentNode.appendChild(c.node)})},"boolean":function(b){return a.txt(b.toString().toUpperCase())},undefined:function(){return a.txt("UNDEFINED")},"null":function(){return a.txt("NULL")},"default":function(){return a.txt("prettyPrint: TypeNotFound Error")}};return f.appendChild(j[e.forceObject?"object":a.type(c)](c,g)),f};return b.config={expanded:!0,forceObject:!1,maxDepth:3,maxArray:-1,styles:{array:{th:{backgroundColor:"#A4C18B",color:"white"}},"function":{th:{backgroundColor:"#D82525"}},regexp:{th:{backgroundColor:"#E2F3FB",color:"#000"}},object:{th:{backgroundColor:"#8DA3AD"}},jquery:{th:{backgroundColor:"#FBF315"}},error:{th:{backgroundColor:"red",color:"yellow"}},domelement:{th:{backgroundColor:"#F3801E"}},date:{th:{backgroundColor:"#A725D8"}},colHeader:{th:{backgroundColor:"#EEE",color:"#aaa",textTransform:"uppercase",fontSize:"80%",padding:"2px 5px"}},"default":{table:{borderCollapse:"collapse",width:"100%"},td:{padding:"5px",fontSize:"12px",backgroundColor:"rgba(255,255,255,0.5)",color:"#222",border:"1px solid #ddd",verticalAlign:"top",fontFamily:'"Consolas","Lucida Console",Courier,mono',whiteSpace:"nowrap"},td_hover:{},th:{padding:"5px",fontSize:"12px",backgroundColor:"#222",color:"#EEE",textAlign:"left",border:"1px solid #ddd",verticalAlign:"top",fontFamily:'"Consolas","Lucida Console",Courier,mono',backgroundRepeat:"repeat-x"}}}},b}();!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){this.el=a,this.options=b=b||{};var d={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1};for(var e in d)!(e in b)&&(b[e]=d[e]);var g=b.group;g&&"object"==typeof g||(g=b.group={name:g}),["pull","put"].forEach(function(a){a in g||(g[a]=!0)}),M.forEach(function(d){b[d]=c(this,b[d]||N),f(a,d.substr(2).toLowerCase(),b[d])},this),b.groups=" "+g.name+(g.put.join?" "+g.put.join(" "):"")+" ",a[F]=b;for(var h in this)"_"===h.charAt(0)&&(this[h]=c(this,this[h]));f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),f(a,"dragover",this),f(a,"dragenter",this),Q.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){s&&s.state!==a&&(i(s,"display",a?"none":""),!a&&s.state&&t.insertBefore(s,q),s.state=a)}function c(a,b){var c=P.call(arguments,2);return b.bind?b.bind.apply(b,[a].concat(c)):function(){return b.apply(a,c.concat(P.call(arguments)))}}function d(a,b,c){if(a){c=c||H,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")\\s","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function e(a){a.dataTransfer.dropEffect="move",a.preventDefault()}function f(a,b,c){a.addEventListener(b,c,!1)}function g(a,b,c){a.removeEventListener(b,c,!1)}function h(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(/\s+/g," ").replace(" "+b+" ","");a.className=d+(c?" "+b:"")}}function i(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return H.defaultView&&H.defaultView.getComputedStyle?c=H.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function j(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function k(a){a.draggable=!1}function l(){K=!1}function m(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return b.clientY-(d.top+d.height)>5&&c}function n(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function o(a){for(var b=0;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function p(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E={},F="Sortable"+(new Date).getTime(),G=window,H=G.document,I=G.parseInt,J=!!("draggable"in H.createElement("div")),K=!1,L=function(a,b,c,d,e,f){var g=H.createEvent("Event");g.initEvent(b,!0,!0),g.item=c||a,g.from=d||a,g.clone=s,g.oldIndex=e,g.newIndex=f,a.dispatchEvent(g)},M="onAdd onUpdate onRemove onStart onEnd onFilter onSort".split(" "),N=function(){},O=Math.abs,P=[].slice,Q=[],R=p(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(w!==c&&(v=b.scroll,w=c,v===!0)){v=c;do if(v.offsetWidth<v.scrollWidth||v.offsetHeight<v.scrollHeight)break;while(v=v.parentNode)}v&&(d=v,e=v.getBoundingClientRect(),f=(O(e.right-j)<=h)-(O(e.left-j)<=h),g=(O(e.bottom-k)<=h)-(O(e.top-k)<=h)),f||g||(f=(h>=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=G)),(E.vx!==f||E.vy!==g||E.el!==d)&&(E.el=d,E.vx=f,E.vy=g,clearInterval(E.pid),d&&(E.pid=setInterval(function(){d===G?G.scrollTo(G.scrollX+f*i,G.scrollY+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30);return a.prototype={constructor:a,_dragStarted:function(){t&&q&&(h(q,this.options.ghostClass,!0),a.active=this,L(t,"start",q,t,z))},_onTapStart:function(a){var b=a.type,c=a.touches&&a.touches[0],e=(c||a).target,g=e,h=this.options,i=this.el,l=h.filter;if(!("mousedown"===b&&0!==a.button||h.disabled)&&(e=d(e,h.draggable,i))){if(z=o(e),"function"==typeof l){if(l.call(this,a,e,this))return L(g,"filter",e,i,z),void a.preventDefault()}else if(l&&(l=l.split(",").some(function(a){return a=d(g,a.trim(),i),a?(L(a,"filter",e,i,z),!0):void 0})))return void a.preventDefault();if((!h.handle||d(g,h.handle,i))&&e&&!q&&e.parentNode===i){C=a,t=this.el,q=e,u=q.nextSibling,B=this.options.group,q.draggable=!0,h.ignore.split(",").forEach(function(a){j(e,a.trim(),k)}),c&&(C={target:e,clientX:c.clientX,clientY:c.clientY},this._onDragStart(C,"touch"),a.preventDefault()),f(H,"mouseup",this._onDrop),f(H,"touchend",this._onDrop),f(H,"touchcancel",this._onDrop),f(q,"dragend",this),f(t,"dragstart",this._onDragStart),J||this._onDragStart(C,!0);try{H.selection?H.selection.empty():window.getSelection().removeAllRanges()}catch(m){}}}},_emulateDragOver:function(){if(D){i(r,"display","none");var a=H.elementFromPoint(D.clientX,D.clientY),b=a,c=" "+this.options.group.name,d=Q.length;if(b)do{if(b[F]&&b[F].groups.indexOf(c)>-1){for(;d--;)Q[d]({clientX:D.clientX,clientY:D.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);i(r,"display","")}},_onTouchMove:function(a){if(C){var b=a.touches?a.touches[0]:a,c=b.clientX-C.clientX,d=b.clientY-C.clientY,e=a.touches?"translate3d("+c+"px,"+d+"px,0)":"translate("+c+"px,"+d+"px)";D=b,i(r,"webkitTransform",e),i(r,"mozTransform",e),i(r,"msTransform",e),i(r,"transform",e),a.preventDefault()}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;if(this._offUpEvents(),"clone"==B.pull&&(s=q.cloneNode(!0),i(s,"display","none"),t.insertBefore(s,q)),b){var e,g=q.getBoundingClientRect(),h=i(q);r=q.cloneNode(!0),i(r,"top",g.top-I(h.marginTop,10)),i(r,"left",g.left-I(h.marginLeft,10)),i(r,"width",g.width),i(r,"height",g.height),i(r,"opacity","0.8"),i(r,"position","fixed"),i(r,"zIndex","100000"),t.appendChild(r),e=r.getBoundingClientRect(),i(r,"width",2*g.width-e.width),i(r,"height",2*g.height-e.height),"touch"===b?(f(H,"touchmove",this._onTouchMove),f(H,"touchend",this._onDrop),f(H,"touchcancel",this._onDrop)):(f(H,"mousemove",this._onTouchMove),f(H,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,150)}else c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,q)),f(H,"drop",this);setTimeout(this._dragStarted,0)},_onDragOver:function(a){var c,e,f,g=this.el,h=this.options,j=h.group,k=j.put,n=B===j,o=h.sort;if(q&&(void 0!==a.preventDefault&&(a.preventDefault(),!h.dragoverBubble&&a.stopPropagation()),B&&!h.disabled&&(n?o||(f=!t.contains(q)):B.pull&&k&&(B.name===j.name||k.indexOf&&~k.indexOf(B.name)))&&(void 0===a.rootEl||a.rootEl===this.el))){if(R(a,h,this.el),K)return;if(c=d(a.target,h.draggable,g),e=q.getBoundingClientRect(),f)return b(!0),void(s||u?t.insertBefore(q,s||u):o||t.appendChild(q));if(0===g.children.length||g.children[0]===r||g===a.target&&(c=m(g,a))){if(c){if(c.animated)return;v=c.getBoundingClientRect()}b(n),g.appendChild(q),this._animate(e,q),c&&this._animate(v,c)}else if(c&&!c.animated&&c!==q&&void 0!==c.parentNode[F]){x!==c&&(x=c,y=i(c));var p,v=c.getBoundingClientRect(),w=v.right-v.left,z=v.bottom-v.top,A=/left|right|inline/.test(y.cssFloat+y.display),C=c.offsetWidth>q.offsetWidth,D=c.offsetHeight>q.offsetHeight,E=(A?(a.clientX-v.left)/w:(a.clientY-v.top)/z)>.5,G=c.nextElementSibling;K=!0,setTimeout(l,30),b(n),p=A?c.previousElementSibling===q&&!C||E&&C:G!==q&&!D||E&&D,p&&!G?g.appendChild(q):c.parentNode.insertBefore(q,p?G:c),this._animate(e,q),this._animate(v,c)}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();i(b,"transition","none"),i(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,i(b,"transition","all "+c+"ms"),i(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){i(b,"transition",""),i(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){g(H,"mouseup",this._onDrop),g(H,"touchmove",this._onTouchMove),g(H,"touchend",this._onDrop),g(H,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(E.pid),g(H,"drop",this),g(H,"mousemove",this._onTouchMove),g(c,"dragstart",this._onDragStart),this._offUpEvents(),b&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation(),r&&r.parentNode.removeChild(r),q&&(g(q,"dragend",this),k(q),h(q,this.options.ghostClass,!1),t!==q.parentNode?(A=o(q),L(q.parentNode,"sort",q,t,z,A),L(t,"sort",q,t,z,A),L(q,"add",q,t,z,A),L(t,"remove",q,t,z,A)):(s&&s.parentNode.removeChild(s),q.nextSibling!==u&&(A=o(q),L(t,"update",q,t,z,A),L(t,"sort",q,t,z,A))),a.active&&L(t,"end",q,t,z,A)),t=q=r=u=s=v=w=C=D=x=y=B=a.active=null,this.save())},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?(this._onDragOver(a),e(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],c=this.el.children,e=0,f=c.length;f>e;e++)a=c[e],d(a,this.options.draggable,this.el)&&b.push(a.getAttribute("data-id")||n(a));return b},sort:function(a){var b={},c=this.el;this.toArray().forEach(function(a,e){var f=c.children[e];d(f,this.options.draggable,c)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(c.removeChild(b[a]),c.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return d(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:void(c[a]=b)},destroy:function(){var a=this.el,b=this.options;M.forEach(function(c){g(a,c.substr(2).toLowerCase(),b[c])}),g(a,"mousedown",this._onTapStart),g(a,"touchstart",this._onTapStart),g(a,"dragover",this),g(a,"dragenter",this),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){ -a.removeAttribute("draggable")}),Q.splice(Q.indexOf(this._onDragOver),1),this._onDrop(),this.el=null}},a.utils={on:f,off:g,css:i,find:j,bind:c,is:function(a,b){return!!d(a,b,a)},throttle:p,closest:d,toggleClass:h,dispatchEvent:L,index:o},a.version="1.1.1",a.create=function(b,c){return new a(b,c)},a}),function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";a.fn.sortable=function(b){var c;return this.each(function(){var d=a(this),e=d.data("sortable");if(e||!(b instanceof Object)&&b||(e=new Sortable(this,b),d.data("sortable",e)),e){if("widget"===b)return e;"destroy"===b?(e.destroy(),d.removeData("sortable")):b in e&&(c=e[e].apply(e,[].slice.call(arguments,1)))}}),void 0===c?this:c}});var XBBCODE=function(){function a(){i=[];var a,b,c;for(a in h)if(h.hasOwnProperty(a)){for("*"===a?i.push("\\"+a):(i.push(a),h[a].noParse&&u.push(a)),h[a].validChildLookup={},h[a].validParentLookup={},h[a].restrictParentsTo=h[a].restrictParentsTo||[],h[a].restrictChildrenTo=h[a].restrictChildrenTo||[],c=h[a].restrictChildrenTo.length,b=0;c>b;b++)h[a].validChildLookup[h[a].restrictChildrenTo[b]]=!0;for(c=h[a].restrictParentsTo.length,b=0;c>b;b++)h[a].validParentLookup[h[a].restrictParentsTo[b]]=!0}j=new RegExp("<bbcl=([0-9]+) ("+i.join("|")+")([ =][^>]*?)?>((?:.|[\\r\\n])*?)<bbcl=\\1 /\\2>","gi"),k=new RegExp("\\[("+i.join("|")+")([ =][^\\]]*?)?\\]([^\\[]*?)\\[/\\1\\]","gi"),l=new RegExp("\\[("+u.join("|")+")([ =][^\\]]*?)?\\]([\\s\\S]*?)\\[/\\1\\]","gi"),function(){for(var a=[],b=0;b<i.length;b++)"\\*"!==i[b]&&a.push("/"+i[b]);m=new RegExp("(\\[)((?:"+i.join("|")+")(?:[ =][^\\]]*?)?)(\\])","gi"),n=new RegExp("(\\[)("+a.join("|")+")(\\])","gi")}()}function b(a,c,d,e,f,g,k){k=k||[],d++;var l,m,n,o,p=new RegExp("(<bbcl="+d+" )("+i.join("|")+")([ =>])","gi"),q=new RegExp("(<bbcl="+d+" )("+i.join("|")+")([ =>])","i"),r=g.match(p)||[],s=h[a]||{};for(p.lastIndex=0,r||(g=""),n=0;n<r.length;n++)q.lastIndex=0,o=r[n].match(q)[2].toLowerCase(),s&&s.restrictChildrenTo&&s.restrictChildrenTo.length>0&&(s.validChildLookup[o]||(m='The tag "'+o+'" is not allowed as a child of the tag "'+a+'".',k.push(m))),l=h[o]||{},l.restrictParentsTo.length>0&&(l.validParentLookup[a]||(m='The tag "'+a+'" is not allowed as a parent of the tag "'+o+'".',k.push(m)));return g=g.replace(j,function(a,c,d,e,f){return k=b(d.toLowerCase(),a,c,d,e,f,k),a}),k}function c(a){return a=a.replace(/\<([^\>][^\>]*?)\>/gi,function(a,b){var c=b.match(/^bbcl=([0-9]+) /);return null===c?"<bbcl=0 "+b+">":"<"+b.replace(/^(bbcl=)([0-9]+)/,function(a,b,c){return b+(parseInt(c,10)+1)})+">"})}function d(a){return a.replace(/<bbcl=[0-9]+ \/\*>/gi,"").replace(/<bbcl=[0-9]+ /gi,"[").replace(/>/gi,"]")}function e(a){var b=a.text;return b=b.replace(j,v)}function f(a){for(a=a.replace(/\[(?!\*[ =\]]|list([ =][^\]]*)?\]|\/list[\]])/gi,"<"),a=a.replace(/\[(?=list([ =][^\]]*)?\]|\/list[\]])/gi,">");a!==(a=a.replace(/>list([ =][^\]]*)?\]([^>]*?)(>\/list])/gi,function(a,b,c){for(var d=a;d!==(d=d.replace(/\[\*\]([^\[]*?)(\[\*\]|>\/list])/i,function(a,b,c){return c=">/list]"===c.toLowerCase()?"</*]</list]":"</*][*]","<*]"+b+c})););return d=d.replace(/>/g,"<")})););return a=a.replace(/</g,"[")}function g(a){for(;a!==(a=a.replace(k,function(a,b,d,e){return a=a.replace(/\[/g,"<"),a=a.replace(/\]/g,">"),c(a)})););return a}var h,i,j,k,l,m,n,o={},p=/^(?:https?|file|c):(?:\/{1,3}|\\{1})[-a-zA-Z0-9:;@#%&()~_?\+=\/\\\.]*$/,q=/^(?:aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)$/,r=/^#?[a-fA-F0-9]{6}$/,s=/[^\s@]+@[^\s@]+\.[^\s@]+/,t=/^([a-z][a-z0-9_]+|"[a-z][a-z0-9_\s]+")$/i,u=[];h={b:{openTag:function(a,b){return'<span class="xbbcode-b">'},closeTag:function(a,b){return"</span>"}},bbcode:{openTag:function(a,b){return""},closeTag:function(a,b){return""}},center:{openTag:function(a,b){return'<span class="xbbcode-center">'},closeTag:function(a,b){return"</span>"}},code:{openTag:function(a,b){return'<span class="xbbcode-code">'},closeTag:function(a,b){return"</span>"},noParse:!0},color:{openTag:function(a,b){var c=a.substr(1).toLowerCase()||"black";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="black"),'<span style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},email:{openTag:function(a,b){var c;return c=a?a.substr(1):b.replace(/<.*?>/g,""),s.lastIndex=0,s.test(c)?'<a href="mailto:'+c+'">':"<a>"},closeTag:function(a,b){return"</a>"}},face:{openTag:function(a,b){var c=a.substr(1)||"inherit";return t.lastIndex=0,t.test(c)||(c="inherit"),'<span style="font-family:'+c+'">'},closeTag:function(a,b){return"</span>"}},font:{openTag:function(a,b){var c=a.substr(1)||"inherit";return t.lastIndex=0,t.test(c)||(c="inherit"),'<span style="font-family:'+c+'">'},closeTag:function(a,b){return"</span>"}},i:{openTag:function(a,b){return'<span class="xbbcode-i">'},closeTag:function(a,b){return"</span>"}},img:{openTag:function(a,b){var c=b;return p.lastIndex=0,p.test(c)||(c=""),'<img src="'+c+'" />'},closeTag:function(a,b){return""},displayContent:!1},justify:{openTag:function(a,b){return'<span class="xbbcode-justify">'},closeTag:function(a,b){return"</span>"}},large:{openTag:function(a,b){var a=a||"",c=a.substr(1)||"inherit";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="inherit"),'<span class="xbbcode-size-36" style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},left:{openTag:function(a,b){return'<span class="xbbcode-left">'},closeTag:function(a,b){return"</span>"}},li:{openTag:function(a,b){return"<li>"},closeTag:function(a,b){return"</li>"},restrictParentsTo:["list","ul","ol"]},list:{openTag:function(a,b){return"<ul>"},closeTag:function(a,b){return"</ul>"},restrictChildrenTo:["*","li"]},noparse:{openTag:function(a,b){return""},closeTag:function(a,b){return""},noParse:!0},ol:{openTag:function(a,b){return"<ol>"},closeTag:function(a,b){return"</ol>"},restrictChildrenTo:["*","li"]},php:{openTag:function(a,b){return'<span class="xbbcode-code">'},closeTag:function(a,b){return"</span>"},noParse:!0},quote:{openTag:function(a,b){return'<blockquote class="xbbcode-blockquote">'},closeTag:function(a,b){return"</blockquote>"}},right:{openTag:function(a,b){return'<span class="xbbcode-right">'},closeTag:function(a,b){return"</span>"}},s:{openTag:function(a,b){return'<span class="xbbcode-s">'},closeTag:function(a,b){return"</span>"}},size:{openTag:function(a,b){var c=parseInt(a.substr(1),10)||0;return(4>c||c>40)&&(c=14),'<span class="xbbcode-size-'+c+'">'},closeTag:function(a,b){return"</span>"}},small:{openTag:function(a,b){var a=a||"",c=a.substr(1)||"inherit";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="inherit"),'<span class="xbbcode-size-10" style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},sub:{openTag:function(a,b){return"<sub>"},closeTag:function(a,b){return"</sub>"}},sup:{openTag:function(a,b){return"<sup>"},closeTag:function(a,b){return"</sup>"}},table:{openTag:function(a,b){return'<table class="xbbcode-table">'},closeTag:function(a,b){return"</table>"},restrictChildrenTo:["tbody","thead","tfoot","tr"]},tbody:{openTag:function(a,b){return"<tbody>"},closeTag:function(a,b){return"</tbody>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},tfoot:{openTag:function(a,b){return"<tfoot>"},closeTag:function(a,b){return"</tfoot>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},thead:{openTag:function(a,b){return'<thead class="xbbcode-thead">'},closeTag:function(a,b){return"</thead>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},td:{openTag:function(a,b){return'<td class="xbbcode-td">'},closeTag:function(a,b){return"</td>"},restrictParentsTo:["tr"]},th:{openTag:function(a,b){return'<th class="xbbcode-th">'},closeTag:function(a,b){return"</th>"},restrictParentsTo:["tr"]},tr:{openTag:function(a,b){return'<tr class="xbbcode-tr">'},closeTag:function(a,b){return"</tr>"},restrictChildrenTo:["td","th"],restrictParentsTo:["table","tbody","tfoot","thead"]},u:{openTag:function(a,b){return'<span class="xbbcode-u">'},closeTag:function(a,b){return"</span>"}},ul:{openTag:function(a,b){return"<ul>"},closeTag:function(a,b){return"</ul>"},restrictChildrenTo:["*","li"]},url:{openTag:function(a,b){var c;return c=a?a.substr(1):b.replace(/<.*?>/g,""),p.lastIndex=0,p.test(c)||(c="#"),'<a href="'+c+'">'},closeTag:function(a,b){return"</a>"}},"*":{openTag:function(a,b){return"<li>"},closeTag:function(a,b){return"</li>"},restrictParentsTo:["list","ul","ol"]}},a();var v=function(a,b,c,e,f){c=c.toLowerCase();var g=h[c].noParse?d(f):f.replace(j,v),i=h[c].openTag(e,g),k=h[c].closeTag(e,g);return h[c].displayContent===!1&&(g=""),i+g+k};return o.tags=function(){return h},o.addTags=function(b){var c;for(c in b)h[c]=b[c];a()},o.process=function(a){var c={html:"",error:!1},d=[];for(a.text=a.text.replace(/</g,"<"),a.text=a.text.replace(/>/g,">"),a.text=a.text.replace(m,function(a,b,c,d){return"<"+c+">"}),a.text=a.text.replace(n,function(a,b,c,d){return"<"+c+">"}),a.text=a.text.replace(/\[/g,"["),a.text=a.text.replace(/\]/g,"]"),a.text=a.text.replace(/</g,"["),a.text=a.text.replace(/>/g,"]");a.text!==(a.text=a.text.replace(l,function(a,b,c,d){return d=d.replace(/\[/g,"["),d=d.replace(/\]/g,"]"),c=c||"",d=d||"","["+b+c+"]"+d+"[/"+b+"]"})););return a.text=f(a.text),a.text=g(a.text),d=b("bbcode",a.text,-1,"","",a.text),c.html=e(a),(-1!==c.html.indexOf("[")||-1!==c.html.indexOf("]"))&&d.push("Some tags appear to be misaligned."),a.removeMisalignedTags&&(c.html=c.html.replace(/\[.*?\]/g,"")),a.addInLineBreaks&&(c.html='<div style="white-space:pre;">'+c.html+"</div>"),c.html=c.html.replace("[","["),c.html=c.html.replace("]","]"),c.error=0!==d.length,c.errorQueue=d,c},o}();+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.1",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body), -d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{input:!0,ripples:!0,checkbox:!0,togglebutton:!0,radio:!0,arrive:!0,autofill:!0,withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",togglebuttonElements:".togglebutton > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=ripple></span><span class=check></span>")},togglebutton:function(b){a(b?b:this.options.togglebuttonElements).filter(":notmdproc").data("mdproc",!0).after("<span class=toggle></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if(b.attr("data-hint")&&b.after("<div class=hint>"+b.attr("data-hint")+"</div>"),(null===b.val()||"undefined"==b.val()||""===b.val())&&b.addClass("empty"),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input[type=checkbox]",function(){a(this).blur()}).on("keydown paste",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()&&b[0].checkValidity()?b.addClass("empty"):b.removeClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(b){a(b?b:this.options.withRipples).ripples()},autofill:function(){var b=setInterval(function(){a("input[type!=checkbox]").each(function(){a(this).val()&&a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input").not("[type=file]");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})},init:function(){a.ripples&&this.options.ripples&&this.ripples(),this.options.input&&this.input(),this.options.checkbox&&this.checkbox(),this.options.togglebutton&&this.togglebutton(),this.options.radio&&this.radio(),this.options.autofill&&this.autofill(),document.arrive&&this.options.arrive&&(a(document).arrive(this.options.inputElements,function(){a.material.input(a(this))}),a(document).arrive(this.options.checkboxElements,function(){a.material.checkbox(a(this))}),a(document).arrive(this.options.radioElements,function(){a.material.radio(a(this))}),a(document).arrive(this.options.togglebuttonElements,function(){a.material.togglebutton(a(this))}))}}}(jQuery),function(a,b,c,d){"use strict";function e(b,c){g=this,this.element=a(b),this.options=a.extend({},h,c),this._defaults=h,this._name=f,this.init()}var f="ripples",g=null,h={};e.prototype.init=function(){var c=this.element;c.on("mousedown touchstart",function(d){if(g.isTouch()&&"mousedown"===d.type)return!1;c.find(".ripple-wrapper").length||c.append('<div class="ripple-wrapper"></div>');var e=c.children(".ripple-wrapper"),f=g.getRelY(e,d),h=g.getRelX(e,d);if(f||h){var i=g.getRipplesColor(),j=a("<div></div>");j.addClass("ripple").css({left:h,top:f,"background-color":i}),e.append(j),function(){return b.getComputedStyle(j[0]).opacity}(),g.rippleOn(j),setTimeout(function(){g.rippleEnd(j)},500),c.on("mouseup mouseleave touchend",function(){j.data("mousedown","off"),"off"===j.data("animating")&&g.rippleOut(j)})}})},e.prototype.getNewSize=function(a){var b=this.element;return Math.max(b.outerWidth(),b.outerHeight())/a.outerWidth()*2.5},e.prototype.getRelX=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1!==b.touches.length?b.touches[0].pageX-c.left:!1):b.pageX-c.left},e.prototype.getRelY=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1!==b.touches.length?b.touches[0].pageY-c.top:!1):b.pageY-c.top},e.prototype.getRipplesColor=function(){var a,c=this.element;return a=this.options&&this.options.color?this.options.color:c.data("ripple-color")?c.data("ripple-color"):b.getComputedStyle(c[0]).color},e.prototype.hasTransitionSupport=function(){var a=c.body||c.documentElement,b=a.style,e=b.transition!==d||b.WebkitTransition!==d||b.MozTransition!==d||b.MsTransition!==d||b.OTransition!==d;return e},e.prototype.isTouch=function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},e.prototype.rippleEnd=function(a){a.data("animating","off"),"off"===a.data("mousedown")&&g.rippleOut(a)},e.prototype.rippleOut=function(a){a.off(),g.hasTransitionSupport()?a.addClass("ripple-out"):a.animate({opacity:0},100,function(){a.trigger("transitionend")}),a.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",function(){a.remove()})},e.prototype.rippleOn=function(a){var b=g.getNewSize(a),c=this.element;g.hasTransitionSupport()?a.css({"-ms-transform":"scale("+b+")","-moz-transform":"scale("+b+")","-webkit-transform":"scale("+b+")",transform:"scale("+b+")"}).addClass("ripple-on").data("animating","on").data("mousedown","on"):a.animate({width:2*Math.max(c.outerWidth(),c.outerHeight()),height:2*Math.max(c.outerWidth(),c.outerHeight()),"margin-left":-1*Math.max(c.outerWidth(),c.outerHeight()),"margin-top":-1*Math.max(c.outerWidth(),c.outerHeight()),opacity:.2},500,function(){a.trigger("transitionend")})},a.fn.ripples=function(b){return this.each(function(){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b))})}}(jQuery,window,document),function(a){function b(a){return"undefined"!=typeof a&&null!==a?!0:!1}a(document).ready(function(){a("body").append("<div id=snackbar-container/>")}),a(document).on("click","[data-toggle=snackbar]",function(){a(this).snackbar("toggle")}).on("click","#snackbar-container .snackbar",function(){a(this).snackbar("hide")}),a.snackbar=function(c){if(b(c)&&c===Object(c)){var d;d=b(c.id)?a("#"+c.id):a("<div/>").attr("id","snackbar"+Date.now()).attr("class","snackbar");var e=d.hasClass("snackbar-opened");b(c.style)?d.attr("class","snackbar "+c.style):d.attr("class","snackbar"),c.timeout=b(c.timeout)?c.timeout:3e3,b(c.content)&&(d.find(".snackbar-content").length?d.find(".snackbar-content").text(c.content):d.prepend("<span class=snackbar-content>"+c.content+"</span>")),b(c.id)?d.insertAfter("#snackbar-container .snackbar:last-child"):d.appendTo("#snackbar-container"),b(c.action)&&"toggle"==c.action&&(e?c.action="hide":c.action="show");var f=Date.now();d.data("animationId1",f),setTimeout(function(){d.data("animationId1")===f&&(b(c.action)&&"show"!=c.action?b(c.action)&&"hide"==c.action&&d.removeClass("snackbar-opened"):d.addClass("snackbar-opened"))},50);var g=Date.now();return d.data("animationId2",g),0!==c.timeout&&setTimeout(function(){d.data("animationId2")===g&&d.removeClass("snackbar-opened")},c.timeout),d}return!1},a.fn.snackbar=function(c){var d={};if(this.hasClass("snackbar"))return d.id=this.attr("id"),("show"===c||"hide"===c||"toggle"==c)&&(d.action=c),a.snackbar(d);b(c)&&"show"!==c&&"hide"!==c&&"toggle"!=c||(d={content:a(this).attr("data-content"),style:a(this).attr("data-style"),timeout:a(this).attr("data-timeout")}),b(c)&&(d.id=this.attr("data-snackbar-id"),("show"===c||"hide"===c||"toggle"==c)&&(d.action=c));var e=a.snackbar(d);return this.attr("data-snackbar-id",e.attr("id")),e}}(jQuery),function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){if(!d)var d={map:function(a,b){var c={};return b?a.map(function(a,d){return c.index=d,b.call(c,a)}):a.slice()},naturalOrder:function(a,b){return b>a?-1:a>b?1:0},sum:function(a,b){var c={};return a.reduce(b?function(a,d,e){return c.index=e,a+b.call(c,d)}:function(a,b){return a+b},0)},max:function(a,b){return Math.max.apply(null,b?d.map(a,b):a)}};var e=function(){function a(a,b,c){return(a<<2*j)+(b<<j)+c}function b(a){function b(){c.sort(a),d=!0}var c=[],d=!1;return{push:function(a){c.push(a),d=!1},peek:function(a){return d||b(),void 0===a&&(a=c.length-1),c[a]},pop:function(){return d||b(),c.pop()},size:function(){return c.length},map:function(a){return c.map(a)},debug:function(){return d||b(),c}}}function c(a,b,c,d,e,f,g){var h=this;h.r1=a,h.r2=b,h.g1=c,h.g2=d,h.b1=e,h.b2=f,h.histo=g}function e(){this.vboxes=new b(function(a,b){return d.naturalOrder(a.vbox.count()*a.vbox.volume(),b.vbox.count()*b.vbox.volume())})}function f(b){var c,d,e,f,g=1<<3*j,h=new Array(g);return b.forEach(function(b){d=b[0]>>k,e=b[1]>>k,f=b[2]>>k,c=a(d,e,f),h[c]=(h[c]||0)+1}),h}function g(a,b){var d,e,f,g=1e6,h=0,i=1e6,j=0,l=1e6,m=0;return a.forEach(function(a){d=a[0]>>k,e=a[1]>>k,f=a[2]>>k,g>d?g=d:d>h&&(h=d),i>e?i=e:e>j&&(j=e),l>f?l=f:f>m&&(m=f)}),new c(g,h,i,j,l,m,b)}function h(b,c){function e(a){var b,d,e,f,g,h=a+"1",i=a+"2",k=0;for(j=c[h];j<=c[i];j++)if(p[j]>o/2){for(e=c.copy(),f=c.copy(),b=j-c[h],d=c[i]-j,g=d>=b?Math.min(c[i]-1,~~(j+d/2)):Math.max(c[h],~~(j-1-b/2));!p[g];)g++;for(k=q[g];!k&&p[g-1];)k=q[--g];return e[i]=g,f[h]=e[i]+1,[e,f]}}if(c.count()){var f=c.r2-c.r1+1,g=c.g2-c.g1+1,h=c.b2-c.b1+1,i=d.max([f,g,h]);if(1==c.count())return[c.copy()];var j,k,l,m,n,o=0,p=[],q=[];if(i==f)for(j=c.r1;j<=c.r2;j++){for(m=0,k=c.g1;k<=c.g2;k++)for(l=c.b1;l<=c.b2;l++)n=a(j,k,l),m+=b[n]||0;o+=m,p[j]=o}else if(i==g)for(j=c.g1;j<=c.g2;j++){for(m=0,k=c.r1;k<=c.r2;k++)for(l=c.b1;l<=c.b2;l++)n=a(k,j,l),m+=b[n]||0;o+=m,p[j]=o}else for(j=c.b1;j<=c.b2;j++){for(m=0,k=c.r1;k<=c.r2;k++)for(l=c.g1;l<=c.g2;l++)n=a(k,l,j),m+=b[n]||0;o+=m,p[j]=o}return p.forEach(function(a,b){q[b]=o-a}),e(i==f?"r":i==g?"g":"b")}}function i(a,c){function i(a,b){for(var c,d=1,e=0;l>e;)if(c=a.pop(),c.count()){var f=h(j,c),g=f[0],i=f[1];if(!g)return;if(a.push(g),i&&(a.push(i),d++),d>=b)return;if(e++>l)return}else a.push(c),e++}if(!a.length||2>c||c>256)return!1;var j=f(a),k=0;j.forEach(function(){k++});var n=g(a,j),o=new b(function(a,b){return d.naturalOrder(a.count(),b.count())});o.push(n),i(o,m*c);for(var p=new b(function(a,b){return d.naturalOrder(a.count()*a.volume(),b.count()*b.volume())});o.size();)p.push(o.pop());i(p,c-p.size());for(var q=new e;p.size();)q.push(p.pop());return q}var j=5,k=8-j,l=1e3,m=.75;return c.prototype={volume:function(a){var b=this;return(!b._volume||a)&&(b._volume=(b.r2-b.r1+1)*(b.g2-b.g1+1)*(b.b2-b.b1+1)),b._volume},count:function(b){var c=this,d=c.histo;if(!c._count_set||b){var e,f,g,h=0;for(e=c.r1;e<=c.r2;e++)for(f=c.g1;f<=c.g2;f++)for(g=c.b1;g<=c.b2;g++)index=a(e,f,g),h+=d[index]||0;c._count=h,c._count_set=!0}return c._count},copy:function(){var a=this;return new c(a.r1,a.r2,a.g1,a.g2,a.b1,a.b2,a.histo)},avg:function(b){var c=this,d=c.histo;if(!c._avg||b){var e,f,g,h,i,k=0,l=1<<8-j,m=0,n=0,o=0;for(f=c.r1;f<=c.r2;f++)for(g=c.g1;g<=c.g2;g++)for(h=c.b1;h<=c.b2;h++)i=a(f,g,h),e=d[i]||0,k+=e,m+=e*(f+.5)*l,n+=e*(g+.5)*l,o+=e*(h+.5)*l;k?c._avg=[~~(m/k),~~(n/k),~~(o/k)]:c._avg=[~~(l*(c.r1+c.r2+1)/2),~~(l*(c.g1+c.g2+1)/2),~~(l*(c.b1+c.b2+1)/2)]}return c._avg},contains:function(a){var b=this,c=a[0]>>k;return gval=a[1]>>k,bval=a[2]>>k,c>=b.r1&&c<=b.r2&&gval>=b.g1&&gval<=b.g2&&bval>=b.b1&&bval<=b.b2}},e.prototype={push:function(a){this.vboxes.push({vbox:a,color:a.avg()})},palette:function(){return this.vboxes.map(function(a){return a.color})},size:function(){return this.vboxes.size()},map:function(a){for(var b=this.vboxes,c=0;c<b.size();c++)if(b.peek(c).vbox.contains(a))return b.peek(c).color;return this.nearest(a)},nearest:function(a){for(var b,c,d,e=this.vboxes,f=0;f<e.size();f++)c=Math.sqrt(Math.pow(a[0]-e.peek(f).color[0],2)+Math.pow(a[1]-e.peek(f).color[1],2)+Math.pow(a[2]-e.peek(f).color[2],2)),(b>c||void 0===b)&&(b=c,d=e.peek(f).color);return d},forcebw:function(){var a=this.vboxes;a.sort(function(a,b){return d.naturalOrder(d.sum(a.color),d.sum(b.color))});var b=a[0].color;b[0]<5&&b[1]<5&&b[2]<5&&(a[0].color=[0,0,0]);var c=a.length-1,e=a[c].color;e[0]>251&&e[1]>251&&e[2]>251&&(a[c].color=[255,255,255])}},{quantize:i}}();b.exports=e.quantize},{}],2:[function(a,b,c){(function(){var b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}},f=[].slice;window.Swatch=c=function(){function a(a,b){this.rgb=a,this.population=b}return a.prototype.hsl=void 0,a.prototype.rgb=void 0,a.prototype.population=1,a.yiq=0,a.prototype.getHsl=function(){return this.hsl?this.hsl:this.hsl=d.rgbToHsl(this.rgb[0],this.rgb[1],this.rgb[2])},a.prototype.getPopulation=function(){return this.population},a.prototype.getRgb=function(){return this.rgb},a.prototype.getHex=function(){return"#"+((1<<24)+(this.rgb[0]<<16)+(this.rgb[1]<<8)+this.rgb[2]).toString(16).slice(1,7)},a.prototype.getTitleTextColor=function(){return this._ensureTextColors(),this.yiq<200?"#fff":"#000"},a.prototype.getBodyTextColor=function(){return this._ensureTextColors(),this.yiq<150?"#fff":"#000"},a.prototype._ensureTextColors=function(){return this.yiq?void 0:this.yiq=(299*this.rgb[0]+587*this.rgb[1]+114*this.rgb[2])/1e3},a}(),window.Vibrant=d=function(){function d(a,d,f){this.swatches=e(this.swatches,this);var g,h,i,j,k,l,m,n,o,p,q,r;for("undefined"==typeof d&&(d=64),"undefined"==typeof f&&(f=5),m=new b(a),n=m.getImageData(),q=n.data,p=m.getPixelCount(),h=[],l=0;p>l;)o=4*l,r=q[o+0],k=q[o+1],i=q[o+2],g=q[o+3],g>=125&&(r>250&&k>250&&i>250||h.push([r,k,i])),l+=f;j=this.quantize(h,d),this._swatches=j.vboxes.map(function(a){return function(a){return new c(a.color,a.vbox.count())}}(this)),this.maxPopulation=this.findMaxPopulation,this.generateVarationColors(),this.generateEmptySwatches(),m.removeCanvas()}return d.prototype.quantize=a("quantize"),d.prototype._swatches=[],d.prototype.TARGET_DARK_LUMA=.26,d.prototype.MAX_DARK_LUMA=.45,d.prototype.MIN_LIGHT_LUMA=.55,d.prototype.TARGET_LIGHT_LUMA=.74,d.prototype.MIN_NORMAL_LUMA=.3,d.prototype.TARGET_NORMAL_LUMA=.5,d.prototype.MAX_NORMAL_LUMA=.7,d.prototype.TARGET_MUTED_SATURATION=.3,d.prototype.MAX_MUTED_SATURATION=.4,d.prototype.TARGET_VIBRANT_SATURATION=1,d.prototype.MIN_VIBRANT_SATURATION=.35,d.prototype.WEIGHT_SATURATION=3,d.prototype.WEIGHT_LUMA=6,d.prototype.WEIGHT_POPULATION=1,d.prototype.VibrantSwatch=void 0,d.prototype.MutedSwatch=void 0,d.prototype.DarkVibrantSwatch=void 0,d.prototype.DarkMutedSwatch=void 0,d.prototype.LightVibrantSwatch=void 0,d.prototype.LightMutedSwatch=void 0,d.prototype.HighestPopulation=0,d.prototype.generateVarationColors=function(){return this.VibrantSwatch=this.findColorVariation(this.TARGET_NORMAL_LUMA,this.MIN_NORMAL_LUMA,this.MAX_NORMAL_LUMA,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.LightVibrantSwatch=this.findColorVariation(this.TARGET_LIGHT_LUMA,this.MIN_LIGHT_LUMA,1,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.DarkVibrantSwatch=this.findColorVariation(this.TARGET_DARK_LUMA,0,this.MAX_DARK_LUMA,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.MutedSwatch=this.findColorVariation(this.TARGET_NORMAL_LUMA,this.MIN_NORMAL_LUMA,this.MAX_NORMAL_LUMA,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION),this.LightMutedSwatch=this.findColorVariation(this.TARGET_LIGHT_LUMA,this.MIN_LIGHT_LUMA,1,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION),this.DarkMutedSwatch=this.findColorVariation(this.TARGET_DARK_LUMA,0,this.MAX_DARK_LUMA,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION)},d.prototype.generateEmptySwatches=function(){var a;return void 0===this.VibrantSwatch&&void 0!==this.DarkVibrantSwatch&&(a=this.DarkVibrantSwatch.getHsl(),a[2]=this.TARGET_NORMAL_LUMA,this.VibrantSwatch=new c(d.hslToRgb(a[0],a[1],a[2]),0)),void 0===this.DarkVibrantSwatch&&void 0!==this.VibrantSwatch?(a=this.VibrantSwatch.getHsl(),a[2]=this.TARGET_DARK_LUMA,this.DarkVibrantSwatch=new c(d.hslToRgb(a[0],a[1],a[2]),0)):void 0},d.prototype.findMaxPopulation=function(){var a,b,c,d,e;for(c=0,d=this._swatches,a=0,b=d.length;b>a;a++)e=d[a],c=Math.max(c,e.getPopulation());return c},d.prototype.findColorVariation=function(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o;for(j=void 0,k=0,l=this._swatches,g=0,h=l.length;h>g;g++)n=l[g],m=n.getHsl()[1],i=n.getHsl()[2],m>=e&&f>=m&&i>=b&&c>=i&&!this.isAlreadySelected(n)&&(o=this.createComparisonValue(m,d,i,a,n.getPopulation(),this.HighestPopulation),(void 0===j||o>k)&&(j=n,k=o));return j},d.prototype.createComparisonValue=function(a,b,c,d,e,f){return this.weightedMean(this.invertDiff(a,b),this.WEIGHT_SATURATION,this.invertDiff(c,d),this.WEIGHT_LUMA,e/f,this.WEIGHT_POPULATION); -},d.prototype.invertDiff=function(a,b){return 1-Math.abs(a-b)},d.prototype.weightedMean=function(){var a,b,c,d,e,g;for(e=1<=arguments.length?f.call(arguments,0):[],b=0,c=0,a=0;a<e.length;)d=e[a],g=e[a+1],b+=d*g,c+=g,a+=2;return b/c},d.prototype.swatches=function(){return{Vibrant:this.VibrantSwatch,Muted:this.MutedSwatch,DarkVibrant:this.DarkVibrantSwatch,DarkMuted:this.DarkMutedSwatch,LightVibrant:this.LightVibrantSwatch,LightMuted:this.LightMuted}},d.prototype.isAlreadySelected=function(a){return this.VibrantSwatch===a||this.DarkVibrantSwatch===a||this.LightVibrantSwatch===a||this.MutedSwatch===a||this.DarkMutedSwatch===a||this.LightMutedSwatch===a},d.rgbToHsl=function(a,b,c){var d,e,f,g,h,i;if(a/=255,b/=255,c/=255,g=Math.max(a,b,c),h=Math.min(a,b,c),e=void 0,i=void 0,f=(g+h)/2,g===h)e=i=0;else{switch(d=g-h,i=f>.5?d/(2-g-h):d/(g+h),g){case a:e=(b-c)/d+(c>b?6:0);break;case b:e=(c-a)/d+2;break;case c:e=(a-b)/d+4}e/=6}return[e,i,f]},d.hslToRgb=function(a,b,c){var d,e,f,g,h,i;return i=void 0,e=void 0,d=void 0,f=function(a,b,c){return 0>c&&(c+=1),c>1&&(c-=1),1/6>c?a+6*(b-a)*c:.5>c?b:2/3>c?a+(b-a)*(2/3-c)*6:a},0===b?i=e=d=c:(h=.5>c?c*(1+b):c+b-c*b,g=2*c-h,i=f(g,h,a+1/3),e=f(g,h,a),d=f(g,h,a-1/3)),[255*i,255*e,255*d]},d}(),window.CanvasImage=b=function(){function a(a){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),document.body.appendChild(this.canvas),this.width=this.canvas.width=a.width,this.height=this.canvas.height=a.height,this.context.drawImage(a,0,0,this.width,this.height)}return a.prototype.clear=function(){return this.context.clearRect(0,0,this.width,this.height)},a.prototype.update=function(a){return this.context.putImageData(a,0,0)},a.prototype.getPixelCount=function(){return this.width*this.height},a.prototype.getImageData=function(){return this.context.getImageData(0,0,this.width,this.height)},a.prototype.removeCanvas=function(){return this.canvas.parentNode.removeChild(this.canvas)},a}()}).call(this)},{quantize:1}]},{},[2]),function(a,b){"use strict";function c(c,d){function e(a){return qa.preferFlash&&ja&&!qa.ignoreFlash&&qa.flash[a]!==b&&qa.flash[a]}function f(a){return function(b){var c,d=this._s;return d&&d._a?c=a.call(this,b):(d&&d.id?qa._wD(d.id+": Ignoring "+b.type):qa._wD(va+"Ignoring "+b.type),c=null),c}}this.setupOptions={url:c||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1e3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!1,noSWFCache:!1,idPrefix:"sound"},this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100},this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null},this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null},this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},opus:{type:["audio/ogg; codecs=opus","audio/opus"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}},this.movieID="sm2-container",this.id=d||"sm2movie",this.debugID="soundmanager-debug",this.debugURLParam=/([#?&])debug=1/i,this.versionNumber="V2.97a.20140901",this.version=null,this.movieURL=null,this.altURL=null,this.swfLoaded=!1,this.enabled=!1,this.oMC=null,this.sounds={},this.soundIDs=[],this.muted=!1,this.didFlashBlock=!1,this.filePattern=null,this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i},this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1},this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null},this.html5={usingFlash:null},this.flash={},this.html5Only=!1,this.ignoreFlash=!1;var g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa=this,ra=null,sa=null,ta="soundManager",ua=ta+": ",va="HTML5::",wa=navigator.userAgent,xa=a.location.href.toString(),ya=document,za=[],Aa=!0,Ba=!1,Ca=!1,Da=!1,Ea=!1,Fa=!1,Ga=0,Ha=["log","info","warn","error"],Ia=8,Ja=null,Ka=null,La=!1,Ma=!1,Na=0,Oa=null,Pa=[],Qa=null,Ra=Array.prototype.slice,Sa=!1,Ta=0,Ua=wa.match(/(ipad|iphone|ipod)/i),Va=wa.match(/android/i),Wa=wa.match(/msie/i),Xa=wa.match(/webkit/i),Ya=wa.match(/safari/i)&&!wa.match(/chrome/i),Za=wa.match(/opera/i),$a=wa.match(/(mobile|pre\/|xoom)/i)||Ua||Va,_a=!xa.match(/usehtml5audio/i)&&!xa.match(/sm2\-ignorebadua/i)&&Ya&&!wa.match(/silk/i)&&wa.match(/OS X 10_6_([3-7])/i),ab=a.console!==b&&console.log!==b,bb=ya.hasFocus!==b?ya.hasFocus():null,cb=Ya&&(ya.hasFocus===b||!ya.hasFocus()),db=!cb,eb=/(mp3|mp4|mpa|m4a|m4b)/i,fb=1e3,gb="about:blank",hb="data:audio/wave;base64,/UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQIAAAD//w==",ib=ya.location?ya.location.protocol.match(/http/i):null,jb=ib?"":"http://",kb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,lb=["mpeg4","aac","flv","mov","mp4","m4v","f4v","m4a","m4b","mp4v","3gp","3g2"],mb=new RegExp("\\.("+lb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i,this.useAltURL=!ib,R={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"},this.hasHTML5=function(){try{return Audio!==b&&(Za&&opera!==b&&opera.version()<10?new Audio(null):new Audio).canPlayType!==b}catch(a){return!1}}(),this.setup=function(a){var c=!qa.url;return a!==b&&Da&&Qa&&qa.ok()&&(a.flashVersion!==b||a.url!==b||a.html5Test!==b)&&V(O("setupLate")),q(a),a&&(c&&F&&a.url!==b&&qa.beginDelayedInit(),F||a.url===b||"complete"!==ya.readyState||setTimeout(D,1)),qa},this.ok=function(){return Qa?Da&&!Ea:qa.useHTML5Audio&&qa.hasHTML5},this.supported=this.ok,this.getMovie=function(b){return h(b)||ya[b]||a[b]},this.createSound=function(a,c){function d(){return h=T(h),qa.sounds[h.id]=new g(h),qa.soundIDs.push(h.id),qa.sounds[h.id]}var e,f,h,i=null;if(e=ta+".createSound(): ",f=e+O(Da?"notOK":"notReady"),!Da||!qa.ok())return V(f),!1;if(c!==b&&(a={id:a,url:c}),h=p(a),h.url=$(h.url),void 0===h.id&&(h.id=qa.setupOptions.idPrefix+Ta++),h.id.toString().charAt(0).match(/^[0-9]$/)&&qa._wD(e+O("badID",h.id),2),qa._wD(e+h.id+(h.url?" ("+h.url+")":""),1),W(h.id,!0))return qa._wD(e+h.id+" exists",1),qa.sounds[h.id];if(ba(h))i=d(),qa._wD(h.id+": Using HTML5"),i._setup_html5(h);else{if(qa.html5Only)return qa._wD(h.id+": No HTML5 support for this sound, and no Flash. Exiting."),d();if(qa.html5.usingFlash&&h.url&&h.url.match(/data\:/i))return qa._wD(h.id+": data: URIs not supported via Flash. Exiting."),d();l>8&&(null===h.isMovieStar&&(h.isMovieStar=!!(h.serverURL||(h.type?h.type.match(kb):!1)||h.url&&h.url.match(mb))),h.isMovieStar&&(qa._wD(e+"using MovieStar handling"),h.loops>1&&n("noNSLoop"))),h=U(h,e),i=d(),8===l?sa._createSound(h.id,h.loops||1,h.usePolicyFile):(sa._createSound(h.id,h.url,h.usePeakData,h.useWaveformData,h.useEQData,h.isMovieStar,h.isMovieStar?h.bufferTime:!1,h.loops||1,h.serverURL,h.duration||null,h.autoPlay,!0,h.autoLoad,h.usePolicyFile),h.serverURL||(i.connected=!0,h.onconnect&&h.onconnect.apply(i))),h.serverURL||!h.autoLoad&&!h.autoPlay||i.load(h)}return!h.serverURL&&h.autoPlay&&i.play(),i},this.destroySound=function(a,b){if(!W(a))return!1;var c,d=qa.sounds[a];for(d._iO={},d.stop(),d.unload(),c=0;c<qa.soundIDs.length;c++)if(qa.soundIDs[c]===a){qa.soundIDs.splice(c,1);break}return b||d.destruct(!0),d=null,delete qa.sounds[a],!0},this.load=function(a,b){return W(a)?qa.sounds[a].load(b):!1},this.unload=function(a){return W(a)?qa.sounds[a].unload():!1},this.onPosition=function(a,b,c,d){return W(a)?qa.sounds[a].onposition(b,c,d):!1},this.onposition=this.onPosition,this.clearOnPosition=function(a,b,c){return W(a)?qa.sounds[a].clearOnPosition(b,c):!1},this.play=function(a,b){var c=null,d=b&&!(b instanceof Object);if(!Da||!qa.ok())return V(ta+".play(): "+O(Da?"notOK":"notReady")),!1;if(W(a,d))d&&(b={url:b});else{if(!d)return!1;d&&(b={url:b}),b&&b.url&&(qa._wD(ta+'.play(): Attempting to create "'+a+'"',1),b.id=a,c=qa.createSound(b).play())}return null===c&&(c=qa.sounds[a].play(b)),c},this.start=this.play,this.setPosition=function(a,b){return W(a)?qa.sounds[a].setPosition(b):!1},this.stop=function(a){return W(a)?(qa._wD(ta+".stop("+a+")",1),qa.sounds[a].stop()):!1},this.stopAll=function(){var a;qa._wD(ta+".stopAll()",1);for(a in qa.sounds)qa.sounds.hasOwnProperty(a)&&qa.sounds[a].stop()},this.pause=function(a){return W(a)?qa.sounds[a].pause():!1},this.pauseAll=function(){var a;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].pause()},this.resume=function(a){return W(a)?qa.sounds[a].resume():!1},this.resumeAll=function(){var a;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].resume()},this.togglePause=function(a){return W(a)?qa.sounds[a].togglePause():!1},this.setPan=function(a,b){return W(a)?qa.sounds[a].setPan(b):!1},this.setVolume=function(a,b){return W(a)?qa.sounds[a].setVolume(b):!1},this.mute=function(a){var b=0;if(a instanceof String&&(a=null),a)return W(a)?(qa._wD(ta+'.mute(): Muting "'+a+'"'),qa.sounds[a].mute()):!1;for(qa._wD(ta+".mute(): Muting all sounds"),b=qa.soundIDs.length-1;b>=0;b--)qa.sounds[qa.soundIDs[b]].mute();return qa.muted=!0,!0},this.muteAll=function(){qa.mute()},this.unmute=function(a){var b;if(a instanceof String&&(a=null),a)return W(a)?(qa._wD(ta+'.unmute(): Unmuting "'+a+'"'),qa.sounds[a].unmute()):!1;for(qa._wD(ta+".unmute(): Unmuting all sounds"),b=qa.soundIDs.length-1;b>=0;b--)qa.sounds[qa.soundIDs[b]].unmute();return qa.muted=!1,!0},this.unmuteAll=function(){qa.unmute()},this.toggleMute=function(a){return W(a)?qa.sounds[a].toggleMute():!1},this.getMemoryUse=function(){var a=0;return sa&&8!==l&&(a=parseInt(sa._getMemoryUse(),10)),a},this.disable=function(c){var d;if(c===b&&(c=!1),Ea)return!1;for(Ea=!0,n("shutdown",1),d=qa.soundIDs.length-1;d>=0;d--)L(qa.sounds[qa.soundIDs[d]]);return o(c),ha.remove(a,"load",u),!0},this.canPlayMIME=function(a){var b;return qa.hasHTML5&&(b=ca({type:a})),!b&&Qa&&(b=a&&qa.ok()?!!((l>8?a.match(kb):null)||a.match(qa.mimePattern)):null),b},this.canPlayURL=function(a){var b;return qa.hasHTML5&&(b=ca({url:a})),!b&&Qa&&(b=a&&qa.ok()?!!a.match(qa.filePattern):null),b},this.canPlayLink=function(a){return a.type!==b&&a.type&&qa.canPlayMIME(a.type)?!0:qa.canPlayURL(a.href)},this.getSoundById=function(a,b){if(!a)return null;var c=qa.sounds[a];return c||b||qa._wD(ta+'.getSoundById(): Sound "'+a+'" not found.',2),c},this.onready=function(b,c){var d="onready",e=!1;if("function"!=typeof b)throw O("needFunction",d);return Da&&qa._wD(O("queue",d)),c||(c=a),s(d,b,c),t(),e=!0,e},this.ontimeout=function(b,c){var d="ontimeout",e=!1;if("function"!=typeof b)throw O("needFunction",d);return Da&&qa._wD(O("queue",d)),c||(c=a),s(d,b,c),t({type:d}),e=!0,e},this._writeDebug=function(a,c){var d,e,f="soundmanager-debug";return qa.debugMode?ab&&qa.useConsole&&(c&&"object"==typeof c?console.log(a,c):Ha[c]!==b?console[Ha[c]](a):console.log(a),qa.consoleOnly)?!0:(d=h(f))?(e=ya.createElement("div"),++Ga%2===0&&(e.className="sm2-alt"),c=c===b?0:parseInt(c,10),e.appendChild(ya.createTextNode(a)),c&&(c>=2&&(e.style.fontWeight="bold"),3===c&&(e.style.color="#ff3333")),d.insertBefore(e,d.firstChild),d=null,!0):!1:!1},-1!==xa.indexOf("sm2-debug=alert")&&(this._writeDebug=function(b){a.alert(b)}),this._wD=this._writeDebug,this._debug=function(){var a,b;for(n("currentObj",1),a=0,b=qa.soundIDs.length;b>a;a++)qa.sounds[qa.soundIDs[a]]._debug()},this.reboot=function(b,c){qa.soundIDs.length&&qa._wD("Destroying "+qa.soundIDs.length+" SMSound object"+(1!==qa.soundIDs.length?"s":"")+"...");var d,e,f;for(d=qa.soundIDs.length-1;d>=0;d--)qa.sounds[qa.soundIDs[d]].destruct();if(sa)try{Wa&&(Ka=sa.innerHTML),Ja=sa.parentNode.removeChild(sa)}catch(g){n("badRemove",2)}if(Ka=Ja=Qa=sa=null,qa.enabled=F=Da=La=Ma=Ba=Ca=Ea=Sa=qa.swfLoaded=!1,qa.soundIDs=[],qa.sounds={},Ta=0,b)za=[];else for(d in za)if(za.hasOwnProperty(d))for(e=0,f=za[d].length;f>e;e++)za[d][e].fired=!1;return c||qa._wD(ta+": Rebooting..."),qa.html5={usingFlash:null},qa.flash={},qa.html5Only=!1,qa.ignoreFlash=!1,a.setTimeout(function(){C(),c||qa.beginDelayedInit()},20),qa},this.reset=function(){return n("reset"),qa.reboot(!0,!0)},this.getMoviePercent=function(){return sa&&"PercentLoaded"in sa?sa.PercentLoaded():null},this.beginDelayedInit=function(){Fa=!0,D(),setTimeout(function(){return Ma?!1:(H(),B(),Ma=!0,!0)},20),v()},this.destruct=function(){qa._wD(ta+".destruct()"),qa.disable(!0)},g=function(a){var c,d,e,f,g,h,i,j,k,o,q=this,r=!1,s=[],t=0,u=null;k={duration:null,time:null},this.id=a.id,this.sID=this.id,this.url=a.url,this.options=p(a),this.instanceOptions=this.options,this._iO=this.instanceOptions,this.pan=this.options.pan,this.volume=this.options.volume,this.isHTML5=!1,this._a=null,o=this.url?!1:!0,this.id3={},this._debug=function(){qa._wD(q.id+": Merged options:",q.options)},this.load=function(a){var c,d=null;if(a!==b?q._iO=p(a,q.options):(a=q.options,q._iO=a,u&&u!==q.url&&(n("manURL"),q._iO.url=q.url,q.url=null)),q._iO.url||(q._iO.url=q.url),q._iO.url=$(q._iO.url),q.instanceOptions=q._iO,c=q._iO,qa._wD(q.id+": load ("+c.url+")"),!c.url&&!q.url)return qa._wD(q.id+": load(): url is unassigned. Exiting.",2),q;if(q.isHTML5||8!==l||q.url||c.autoPlay||qa._wD(q.id+": Flash 8 load() limitation: Wait for onload() before calling play().",1),c.url===q.url&&0!==q.readyState&&2!==q.readyState)return n("onURL",1),3===q.readyState&&c.onload&&pa(q,function(){c.onload.apply(q,[!!q.duration])}),q;if(q.loaded=!1,q.readyState=1,q.playState=0,q.id3={},ba(c))d=q._setup_html5(c),d._called_load?qa._wD(q.id+": Ignoring request to load again"):(q._html5_canplay=!1,q.url!==c.url&&(qa._wD(n("manURL")+": "+c.url),q._a.src=c.url,q.setPosition(0)),q._a.autobuffer="auto",q._a.preload="auto",q._a._called_load=!0);else{if(qa.html5Only)return qa._wD(q.id+": No flash support. Exiting."),q;if(q._iO.url&&q._iO.url.match(/data\:/i))return qa._wD(q.id+": data: URIs not supported via Flash. Exiting."),q;try{q.isHTML5=!1,q._iO=U(T(c)),q._iO.autoPlay&&(q._iO.position||q._iO.from)&&(qa._wD(q.id+": Disabling autoPlay because of non-zero offset case"),q._iO.autoPlay=!1),c=q._iO,8===l?sa._load(q.id,c.url,c.stream,c.autoPlay,c.usePolicyFile):sa._load(q.id,c.url,!!c.stream,!!c.autoPlay,c.loops||1,!!c.autoLoad,c.usePolicyFile)}catch(e){n("smError",2),m("onload",!1),I({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:!0})}}return q.url=c.url,q},this.unload=function(){return 0!==q.readyState&&(qa._wD(q.id+": unload()"),q.isHTML5?(f(),q._a&&(q._a.pause(),u=ea(q._a))):8===l?sa._unload(q.id,gb):sa._unload(q.id),c()),q},this.destruct=function(a){qa._wD(q.id+": Destruct"),q.isHTML5?(f(),q._a&&(q._a.pause(),ea(q._a),Sa||e(),q._a._s=null,q._a=null)):(q._iO.onfailure=null,sa._destroySound(q.id)),a||qa.destroySound(q.id,!0)},this.play=function(a,c){var d,e,f,i,k,m,n,s=!0,t=null;if(d=q.id+": play(): ",c=c===b?!0:c,a||(a={}),q.url&&(q._iO.url=q.url),q._iO=p(q._iO,q.options),q._iO=p(a,q._iO),q._iO.url=$(q._iO.url),q.instanceOptions=q._iO,!q.isHTML5&&q._iO.serverURL&&!q.connected)return q.getAutoPlay()||(qa._wD(d+" Netstream not connected yet - setting autoPlay"),q.setAutoPlay(!0)),q;if(ba(q._iO)&&(q._setup_html5(q._iO),g()),1!==q.playState||q.paused||(e=q._iO.multiShot,e?qa._wD(d+"Already playing (multi-shot)",1):(qa._wD(d+"Already playing (one-shot)",1),q.isHTML5&&q.setPosition(q._iO.position),t=q)),null!==t)return t;if(a.url&&a.url!==q.url&&(q.readyState||q.isHTML5||8!==l||!o?q.load(q._iO):o=!1),q.loaded?qa._wD(d.substr(0,d.lastIndexOf(":"))):0===q.readyState?(qa._wD(d+"Attempting to load"),q.isHTML5||qa.html5Only?q.isHTML5?q.load(q._iO):(qa._wD(d+"Unsupported type. Exiting."),t=q):(q._iO.autoPlay=!0,q.load(q._iO)),q.instanceOptions=q._iO):2===q.readyState?(qa._wD(d+"Could not load - exiting",2),t=q):qa._wD(d+"Loading - attempting to play..."),null!==t)return t;if(!q.isHTML5&&9===l&&q.position>0&&q.position===q.duration&&(qa._wD(d+"Sound at end, resetting to position:0"),a.position=0),q.paused&&q.position>=0&&(!q._iO.serverURL||q.position>0))qa._wD(d+"Resuming from paused state",1),q.resume();else{if(q._iO=p(a,q._iO),(!q.isHTML5&&null!==q._iO.position&&q._iO.position>0||null!==q._iO.from&&q._iO.from>0||null!==q._iO.to)&&0===q.instanceCount&&0===q.playState&&!q._iO.serverURL){if(i=function(){q._iO=p(a,q._iO),q.play(q._iO)},q.isHTML5&&!q._html5_canplay?(qa._wD(d+"Beginning load for non-zero offset case"),q.load({_oncanplay:i}),t=!1):q.isHTML5||q.loaded||q.readyState&&2===q.readyState||(qa._wD(d+"Preloading for non-zero offset case"),q.load({onload:i}),t=!1),null!==t)return t;q._iO=j()}(!q.instanceCount||q._iO.multiShotEvents||q.isHTML5&&q._iO.multiShot&&!Sa||!q.isHTML5&&l>8&&!q.getAutoPlay())&&q.instanceCount++,q._iO.onposition&&0===q.playState&&h(q),q.playState=1,q.paused=!1,q.position=q._iO.position===b||isNaN(q._iO.position)?0:q._iO.position,q.isHTML5||(q._iO=U(T(q._iO))),q._iO.onplay&&c&&(q._iO.onplay.apply(q),r=!0),q.setVolume(q._iO.volume,!0),q.setPan(q._iO.pan,!0),q.isHTML5?q.instanceCount<2?(g(),f=q._setup_html5(),q.setPosition(q._iO.position),f.play()):(qa._wD(q.id+": Cloning Audio() for instance #"+q.instanceCount+"..."),k=new Audio(q._iO.url),m=function(){ha.remove(k,"ended",m),q._onfinish(q),ea(k),k=null},n=function(){ha.remove(k,"canplay",n);try{k.currentTime=q._iO.position/fb}catch(a){V(q.id+": multiShot play() failed to apply position of "+q._iO.position/fb)}k.play()},ha.add(k,"ended",m),void 0!==q._iO.volume&&(k.volume=Math.max(0,Math.min(1,q._iO.volume/100))),q.muted&&(k.muted=!0),q._iO.position?ha.add(k,"canplay",n):k.play()):(s=sa._start(q.id,q._iO.loops||1,9===l?q.position:q.position/fb,q._iO.multiShot||!1),9!==l||s||(qa._wD(d+"No sound hardware, or 32-sound ceiling hit",2),q._iO.onplayerror&&q._iO.onplayerror.apply(q)))}return q},this.start=this.play,this.stop=function(a){var b,c=q._iO;return 1===q.playState&&(qa._wD(q.id+": stop()"),q._onbufferchange(0),q._resetOnPosition(0),q.paused=!1,q.isHTML5||(q.playState=0),i(),c.to&&q.clearOnPosition(c.to),q.isHTML5?q._a&&(b=q.position,q.setPosition(0),q.position=b,q._a.pause(),q.playState=0,q._onTimer(),f()):(sa._stop(q.id,a),c.serverURL&&q.unload()),q.instanceCount=0,q._iO={},c.onstop&&c.onstop.apply(q)),q},this.setAutoPlay=function(a){qa._wD(q.id+": Autoplay turned "+(a?"on":"off")),q._iO.autoPlay=a,q.isHTML5||(sa._setAutoPlay(q.id,a),a&&(q.instanceCount||1!==q.readyState||(q.instanceCount++,qa._wD(q.id+": Incremented instance count to "+q.instanceCount))))},this.getAutoPlay=function(){return q._iO.autoPlay},this.setPosition=function(a){a===b&&(a=0);var c,d,e=q.isHTML5?Math.max(a,0):Math.min(q.duration||q._iO.duration,Math.max(a,0));if(q.position=e,d=q.position/fb,q._resetOnPosition(q.position),q._iO.position=e,q.isHTML5){if(q._a){if(q._html5_canplay){if(q._a.currentTime!==d){qa._wD(q.id+": setPosition("+d+")");try{q._a.currentTime=d,(0===q.playState||q.paused)&&q._a.pause()}catch(f){qa._wD(q.id+": setPosition("+d+") failed: "+f.message,2)}}}else if(d)return qa._wD(q.id+": setPosition("+d+"): Cannot seek yet, sound not ready",2),q;q.paused&&q._onTimer(!0)}}else c=9===l?q.position:d,q.readyState&&2!==q.readyState&&sa._setPosition(q.id,c,q.paused||!q.playState,q._iO.multiShot);return q},this.pause=function(a){return q.paused||0===q.playState&&1!==q.readyState?q:(qa._wD(q.id+": pause()"),q.paused=!0,q.isHTML5?(q._setup_html5().pause(),f()):(a||a===b)&&sa._pause(q.id,q._iO.multiShot),q._iO.onpause&&q._iO.onpause.apply(q),q)},this.resume=function(){var a=q._iO;return q.paused?(qa._wD(q.id+": resume()"),q.paused=!1,q.playState=1,q.isHTML5?(q._setup_html5().play(),g()):(a.isMovieStar&&!a.serverURL&&q.setPosition(q.position),sa._pause(q.id,a.multiShot)),!r&&a.onplay?(a.onplay.apply(q),r=!0):a.onresume&&a.onresume.apply(q),q):q},this.togglePause=function(){return qa._wD(q.id+": togglePause()"),0===q.playState?(q.play({position:9!==l||q.isHTML5?q.position/fb:q.position}),q):(q.paused?q.resume():q.pause(),q)},this.setPan=function(a,c){return a===b&&(a=0),c===b&&(c=!1),q.isHTML5||sa._setPan(q.id,a),q._iO.pan=a,c||(q.pan=a,q.options.pan=a),q},this.setVolume=function(a,c){return a===b&&(a=100),c===b&&(c=!1),q.isHTML5?q._a&&(qa.muted&&!q.muted&&(q.muted=!0,q._a.muted=!0),q._a.volume=Math.max(0,Math.min(1,a/100))):sa._setVolume(q.id,qa.muted&&!q.muted||q.muted?0:a),q._iO.volume=a,c||(q.volume=a,q.options.volume=a),q},this.mute=function(){return q.muted=!0,q.isHTML5?q._a&&(q._a.muted=!0):sa._setVolume(q.id,0),q},this.unmute=function(){q.muted=!1;var a=q._iO.volume!==b;return q.isHTML5?q._a&&(q._a.muted=!1):sa._setVolume(q.id,a?q._iO.volume:q.options.volume),q},this.toggleMute=function(){return q.muted?q.unmute():q.mute()},this.onPosition=function(a,c,d){return s.push({position:parseInt(a,10),method:c,scope:d!==b?d:q,fired:!1}),q},this.onposition=this.onPosition,this.clearOnPosition=function(a,b){var c;if(a=parseInt(a,10),isNaN(a))return!1;for(c=0;c<s.length;c++)a===s[c].position&&(b&&b!==s[c].method||(s[c].fired&&t--,s.splice(c,1)))},this._processOnPosition=function(){var a,b,c=s.length;if(!c||!q.playState||t>=c)return!1;for(a=c-1;a>=0;a--)b=s[a],!b.fired&&q.position>=b.position&&(b.fired=!0,t++,b.method.apply(b.scope,[b.position]),c=s.length);return!0},this._resetOnPosition=function(a){var b,c,d=s.length;if(!d)return!1;for(b=d-1;b>=0;b--)c=s[b],c.fired&&a<=c.position&&(c.fired=!1,t--);return!0},j=function(){var a,b,c=q._iO,d=c.from,e=c.to;return b=function(){qa._wD(q.id+': "To" time of '+e+" reached."),q.clearOnPosition(e,b),q.stop()},a=function(){qa._wD(q.id+': Playing "from" '+d),null===e||isNaN(e)||q.onPosition(e,b)},null===d||isNaN(d)||(c.position=d,c.multiShot=!1,a()),c},h=function(){var a,b=q._iO.onposition;if(b)for(a in b)b.hasOwnProperty(a)&&q.onPosition(parseInt(a,10),b[a])},i=function(){var a,b=q._iO.onposition;if(b)for(a in b)b.hasOwnProperty(a)&&q.clearOnPosition(parseInt(a,10))},g=function(){q.isHTML5&&X(q)},f=function(){q.isHTML5&&Y(q)},c=function(a){a||(s=[],t=0),r=!1,q._hasTimer=null,q._a=null,q._html5_canplay=!1,q.bytesLoaded=null,q.bytesTotal=null,q.duration=q._iO&&q._iO.duration?q._iO.duration:null,q.durationEstimate=null,q.buffered=[],q.eqData=[],q.eqData.left=[],q.eqData.right=[],q.failures=0,q.isBuffering=!1,q.instanceOptions={},q.instanceCount=0,q.loaded=!1,q.metadata={},q.readyState=0,q.muted=!1,q.paused=!1,q.peakData={left:0,right:0},q.waveformData={left:[],right:[]},q.playState=0,q.position=null,q.id3={}},c(),this._onTimer=function(a){var b,c,d=!1,e={};return q._hasTimer||a?(q._a&&(a||(q.playState>0||1===q.readyState)&&!q.paused)&&(b=q._get_html5_duration(),b!==k.duration&&(k.duration=b,q.duration=b,d=!0),q.durationEstimate=q.duration,c=q._a.currentTime*fb||0,c!==k.time&&(k.time=c,d=!0),(d||a)&&q._whileplaying(c,e,e,e,e)),d):void 0},this._get_html5_duration=function(){var a=q._iO,b=q._a&&q._a.duration?q._a.duration*fb:a&&a.duration?a.duration:null,c=b&&!isNaN(b)&&b!==1/0?b:null;return c},this._apply_loop=function(a,b){!a.loop&&b>1&&qa._wD("Note: Native HTML5 looping is infinite.",1),a.loop=b>1?"loop":""},this._setup_html5=function(a){var b,e=p(q._iO,a),f=Sa?ra:q._a,g=decodeURI(e.url);if(Sa?g===decodeURI(ia)&&(b=!0):g===decodeURI(u)&&(b=!0),f){if(f._s)if(Sa)f._s&&f._s.playState&&!b&&f._s.stop();else if(!Sa&&g===decodeURI(u))return q._apply_loop(f,e.loops),f;b||(u&&c(!1),f.src=e.url,q.url=e.url,u=e.url,ia=e.url,f._called_load=!1)}else e.autoLoad||e.autoPlay?(q._a=new Audio(e.url),q._a.load()):q._a=Za&&opera.version()<10?new Audio(null):new Audio,f=q._a,f._called_load=!1,Sa&&(ra=f);return q.isHTML5=!0,q._a=f,f._s=q,d(),q._apply_loop(f,e.loops),e.autoLoad||e.autoPlay?q.load():(f.autobuffer=!1,f.preload="auto"),f},d=function(){function a(a,b,c){return q._a?q._a.addEventListener(a,b,c||!1):null}if(q._a._added_events)return!1;var b;q._a._added_events=!0;for(b in ma)ma.hasOwnProperty(b)&&a(b,ma[b]);return!0},e=function(){function a(a,b,c){return q._a?q._a.removeEventListener(a,b,c||!1):null}var b;qa._wD(q.id+": Removing event listeners"),q._a._added_events=!1;for(b in ma)ma.hasOwnProperty(b)&&a(b,ma[b])},this._onload=function(a){var b,c=!!a||!q.isHTML5&&8===l&&q.duration;return b=q.id+": ",qa._wD(b+(c?"onload()":"Failed to load / invalid sound?"+(q.duration?" -":" Zero-length duration reported.")+" ("+q.url+")"),c?1:2),c||q.isHTML5||(qa.sandbox.noRemote===!0&&qa._wD(b+O("noNet"),1),qa.sandbox.noLocal===!0&&qa._wD(b+O("noLocal"),1)),q.loaded=c,q.readyState=c?3:2,q._onbufferchange(0),q._iO.onload&&pa(q,function(){q._iO.onload.apply(q,[c])}),!0},this._onbufferchange=function(a){return 0===q.playState?!1:a&&q.isBuffering||!a&&!q.isBuffering?!1:(q.isBuffering=1===a,q._iO.onbufferchange&&(qa._wD(q.id+": Buffer state change: "+a),q._iO.onbufferchange.apply(q,[a])),!0)},this._onsuspend=function(){return q._iO.onsuspend&&(qa._wD(q.id+": Playback suspended"),q._iO.onsuspend.apply(q)),!0},this._onfailure=function(a,b,c){q.failures++,qa._wD(q.id+": Failure ("+q.failures+"): "+a),q._iO.onfailure&&1===q.failures?q._iO.onfailure(a,b,c):qa._wD(q.id+": Ignoring failure")},this._onwarning=function(a,b,c){q._iO.onwarning&&q._iO.onwarning(a,b,c)},this._onfinish=function(){var a=q._iO.onfinish;q._onbufferchange(0),q._resetOnPosition(0),q.instanceCount&&(q.instanceCount--,q.instanceCount||(i(),q.playState=0,q.paused=!1,q.instanceCount=0,q.instanceOptions={},q._iO={},f(),q.isHTML5&&(q.position=0)),(!q.instanceCount||q._iO.multiShotEvents)&&a&&(qa._wD(q.id+": onfinish()"),pa(q,function(){a.apply(q)})))},this._whileloading=function(a,b,c,d){var e=q._iO;q.bytesLoaded=a,q.bytesTotal=b,q.duration=Math.floor(c),q.bufferLength=d,q.isHTML5||e.isMovieStar?q.durationEstimate=q.duration:e.duration?q.durationEstimate=q.duration>e.duration?q.duration:e.duration:q.durationEstimate=parseInt(q.bytesTotal/q.bytesLoaded*q.duration,10),q.isHTML5||(q.buffered=[{start:0,end:q.duration}]),(3!==q.readyState||q.isHTML5)&&e.whileloading&&e.whileloading.apply(q)},this._whileplaying=function(a,c,d,e,f){var g,h=q._iO;return isNaN(a)||null===a?!1:(q.position=Math.max(0,a),q._processOnPosition(),!q.isHTML5&&l>8&&(h.usePeakData&&c!==b&&c&&(q.peakData={left:c.leftPeak,right:c.rightPeak}),h.useWaveformData&&d!==b&&d&&(q.waveformData={left:d.split(","),right:e.split(",")}),h.useEQData&&f!==b&&f&&f.leftEQ&&(g=f.leftEQ.split(","),q.eqData=g,q.eqData.left=g,f.rightEQ!==b&&f.rightEQ&&(q.eqData.right=f.rightEQ.split(",")))),1===q.playState&&(q.isHTML5||8!==l||q.position||!q.isBuffering||q._onbufferchange(0),h.whileplaying&&h.whileplaying.apply(q)),!0)},this._oncaptiondata=function(a){qa._wD(q.id+": Caption data received."),q.captiondata=a,q._iO.oncaptiondata&&q._iO.oncaptiondata.apply(q,[a])},this._onmetadata=function(a,b){qa._wD(q.id+": Metadata received.");var c,d,e={};for(c=0,d=a.length;d>c;c++)e[a[c]]=b[c];q.metadata=e,console.log("updated metadata",q.metadata),q._iO.onmetadata&&q._iO.onmetadata.call(q,q.metadata)},this._onid3=function(a,b){qa._wD(q.id+": ID3 data received.");var c,d,e=[];for(c=0,d=a.length;d>c;c++)e[a[c]]=b[c];q.id3=p(q.id3,e),q._iO.onid3&&q._iO.onid3.apply(q)},this._onconnect=function(a){a=1===a,qa._wD(q.id+": "+(a?"Connected.":"Failed to connect? - "+q.url),a?1:2),q.connected=a,a&&(q.failures=0,W(q.id)&&(q.getAutoPlay()?q.play(b,q.getAutoPlay()):q._iO.autoLoad&&q.load()),q._iO.onconnect&&q._iO.onconnect.apply(q,[a]))},this._ondataerror=function(a){q.playState>0&&(qa._wD(q.id+": Data error: "+a),q._iO.ondataerror&&q._iO.ondataerror.apply(q))},this._debug()},G=function(){return ya.body||ya.getElementsByTagName("div")[0]},h=function(a){return ya.getElementById(a)},p=function(a,c){var d,e,f=a||{};d=c===b?qa.defaultOptions:c;for(e in d)d.hasOwnProperty(e)&&f[e]===b&&("object"!=typeof d[e]||null===d[e]?f[e]=d[e]:f[e]=p(f[e],d[e]));return f},pa=function(b,c){b.isHTML5||8!==l?c():a.setTimeout(c,0)},r={onready:1,ontimeout:1,defaultOptions:1,flash9Options:1,movieStarOptions:1},q=function(a,c){var d,e=!0,f=c!==b,g=qa.setupOptions,h=r;if(a===b){e=[];for(d in g)g.hasOwnProperty(d)&&e.push(d);for(d in h)h.hasOwnProperty(d)&&("object"==typeof qa[d]?e.push(d+": {...}"):qa[d]instanceof Function?e.push(d+": function() {...}"):e.push(d));return qa._wD(O("setup",e.join(", "))),!1}for(d in a)if(a.hasOwnProperty(d))if("object"!=typeof a[d]||null===a[d]||a[d]instanceof Array||a[d]instanceof RegExp)f&&h[c]!==b?qa[c][d]=a[d]:g[d]!==b?(qa.setupOptions[d]=a[d],qa[d]=a[d]):h[d]===b?(V(O(qa[d]===b?"setupUndef":"setupError",d),2),e=!1):qa[d]instanceof Function?qa[d].apply(qa,a[d]instanceof Array?a[d]:[a[d]]):qa[d]=a[d];else{if(h[d]!==b)return q(a[d],d);V(O(qa[d]===b?"setupUndef":"setupError",d),2),e=!1}return e},ha=function(){function b(a){var b=Ra.call(a),c=b.length;return f?(b[1]="on"+b[1],c>3&&b.pop()):3===c&&b.push(!1),b}function c(a,b){var c=a.shift(),d=[g[b]];f?c[d](a[0],a[1]):c[d].apply(c,a)}function d(){c(b(arguments),"add")}function e(){c(b(arguments),"remove")}var f=a.attachEvent,g={add:f?"attachEvent":"addEventListener",remove:f?"detachEvent":"removeEventListener"};return{add:d,remove:e}}(),ma={abort:f(function(){qa._wD(this._s.id+": abort")}),canplay:f(function(){var a,c=this._s;if(c._html5_canplay)return!0;if(c._html5_canplay=!0,qa._wD(c.id+": canplay"),c._onbufferchange(0),a=c._iO.position===b||isNaN(c._iO.position)?null:c._iO.position/fb,this.currentTime!==a){qa._wD(c.id+": canplay: Setting position to "+a);try{this.currentTime=a}catch(d){qa._wD(c.id+": canplay: Setting position of "+a+" failed: "+d.message,2)}}c._iO._oncanplay&&c._iO._oncanplay()}),canplaythrough:f(function(){var a=this._s;a.loaded||(a._onbufferchange(0),a._whileloading(a.bytesLoaded,a.bytesTotal,a._get_html5_duration()),a._onload(!0))}),durationchange:f(function(){var a,b=this._s;a=b._get_html5_duration(),isNaN(a)||a===b.duration||(qa._wD(this._s.id+": durationchange ("+a+")"+(b.duration?", previously "+b.duration:"")),b.durationEstimate=b.duration=a)}),ended:f(function(){var a=this._s;qa._wD(a.id+": ended"),a._onfinish()}),error:f(function(){qa._wD(this._s.id+": HTML5 error, code "+this.error.code),this._s._onload(!1)}),loadeddata:f(function(){var a=this._s;qa._wD(a.id+": loadeddata"),a._loaded||Ya||(a.duration=a._get_html5_duration())}),loadedmetadata:f(function(){qa._wD(this._s.id+": loadedmetadata")}),loadstart:f(function(){qa._wD(this._s.id+": loadstart"),this._s._onbufferchange(1)}),play:f(function(){this._s._onbufferchange(0)}),playing:f(function(){qa._wD(this._s.id+": playing "+String.fromCharCode(9835)),this._s._onbufferchange(0)}),progress:f(function(a){var b,c,d,e=this._s,f=0,g="progress"===a.type,h=a.target.buffered,i=a.loaded||0,j=a.total||1;if(e.buffered=[],h&&h.length){for(b=0,c=h.length;c>b;b++)e.buffered.push({start:h.start(b)*fb,end:h.end(b)*fb});if(f=(h.end(0)-h.start(0))*fb,i=Math.min(1,f/(a.target.duration*fb)),g&&h.length>1){for(d=[],c=h.length,b=0;c>b;b++)d.push(a.target.buffered.start(b)*fb+"-"+a.target.buffered.end(b)*fb);qa._wD(this._s.id+": progress, timeRanges: "+d.join(", "))}g&&!isNaN(i)&&qa._wD(this._s.id+": progress, "+Math.floor(100*i)+"% loaded")}isNaN(i)||(e._whileloading(i,j,e._get_html5_duration()), -i&&j&&i===j&&ma.canplaythrough.call(this,a))}),ratechange:f(function(){qa._wD(this._s.id+": ratechange")}),suspend:f(function(a){var b=this._s;qa._wD(this._s.id+": suspend"),ma.progress.call(this,a),b._onsuspend()}),stalled:f(function(){qa._wD(this._s.id+": stalled")}),timeupdate:f(function(){this._s._onTimer()}),waiting:f(function(){var a=this._s;qa._wD(this._s.id+": waiting"),a._onbufferchange(1)})},ba=function(a){var b;return b=a&&(a.type||a.url||a.serverURL)?a.serverURL||a.type&&e(a.type)?!1:a.type?ca({type:a.type}):ca({url:a.url})||qa.html5Only||a.url.match(/data\:/i):!1},ea=function(a){var b;return a&&(b=Ya?gb:qa.html5.canPlayType("audio/wav")?hb:gb,a.src=b,void 0!==a._called_unload&&(a._called_load=!1)),Sa&&(ia=null),b},ca=function(a){if(!qa.useHTML5Audio||!qa.hasHTML5)return!1;var c,d,f,g,h=a.url||null,i=a.type||null,j=qa.audioFormats;if(i&&qa.html5[i]!==b)return qa.html5[i]&&!e(i);if(!da){da=[];for(g in j)j.hasOwnProperty(g)&&(da.push(g),j[g].related&&(da=da.concat(j[g].related)));da=new RegExp("\\.("+da.join("|")+")(\\?.*)?$","i")}return f=h?h.toLowerCase().match(da):null,f&&f.length?f=f[1]:i?(d=i.indexOf(";"),f=(-1!==d?i.substr(0,d):i).substr(6)):c=!1,f&&qa.html5[f]!==b?c=qa.html5[f]&&!e(f):(i="audio/"+f,c=qa.html5.canPlayType({type:i}),qa.html5[f]=c,c=c&&qa.html5[i]&&!e(i)),c},ga=function(){function a(a){var b,c,d=!1,e=!1;if(!g||"function"!=typeof g.canPlayType)return d;if(a instanceof Array){for(f=0,c=a.length;c>f;f++)(qa.html5[a[f]]||g.canPlayType(a[f]).match(qa.html5Test))&&(e=!0,qa.html5[a[f]]=!0,qa.flash[a[f]]=!!a[f].match(eb));d=e}else b=g&&"function"==typeof g.canPlayType?g.canPlayType(a):!1,d=!(!b||!b.match(qa.html5Test));return d}if(!qa.useHTML5Audio||!qa.hasHTML5)return qa.html5.usingFlash=!0,Qa=!0,!1;var c,d,e,f,g=Audio!==b?Za&&opera.version()<10?new Audio(null):new Audio:null,h={};e=qa.audioFormats;for(c in e)if(e.hasOwnProperty(c)&&(d="audio/"+c,h[c]=a(e[c].type),h[d]=h[c],c.match(eb)?(qa.flash[c]=!0,qa.flash[d]=!0):(qa.flash[c]=!1,qa.flash[d]=!1),e[c]&&e[c].related))for(f=e[c].related.length-1;f>=0;f--)h["audio/"+e[c].related[f]]=h[c],qa.html5[e[c].related[f]]=h[c],qa.flash[e[c].related[f]]=h[c];return h.canPlayType=g?a:null,qa.html5=p(qa.html5,h),qa.html5.usingFlash=aa(),Qa=qa.html5.usingFlash,!0},A={notReady:"Unavailable - wait until onready() has fired.",notOK:"Audio support is not available.",domError:ta+"exception caught while appending SWF to DOM.",spcWmode:"Removing wmode, preventing known SWF loading issue(s)",swf404:ua+"Verify that %s is a valid path.",tryDebug:"Try "+ta+".debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:ua+"Non-HTTP page ("+ya.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, e.g. c:/sm2/ or /users/me/sm2/",waitFocus:ua+"Special case: Waiting for SWF to load with window focus...",waitForever:ua+"Waiting indefinitely for Flash (will recover if unblocked)...",waitSWF:ua+"Waiting for 100% SWF load...",needFunction:ua+"Function object expected for %s",badID:'Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:ua+"_debug(): Current sound objects",waitOnload:ua+"Waiting for window.onload()",docLoaded:ua+"Document already loaded",onload:ua+"initComplete(): calling soundManager.onload()",onloadOK:ta+".onload() complete",didInit:ua+"init(): Already called?",secNote:"Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",badRemove:ua+"Failed to remove Flash node.",shutdown:ta+".disable(): Shutting down",queue:ua+"Queueing %s handler",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+R.swfTimedout+" CSS...",fbLoaded:"Flash loaded",fbHandler:ua+"flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:ta+".load(): current URL already assigned.",badFV:ta+'.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",needFlash:ua+"Fatal error: Flash is needed to play some required formats, but is not available.",gotFocus:ua+"Got window focus.",policy:"Enabling usePolicyFile for data access",setup:ta+".setup(): allowed parameters: %s",setupError:ta+'.setup(): "%s" cannot be assigned with this method.',setupUndef:ta+'.setup(): Could not find option "%s"',setupLate:ta+".setup(): url, flashVersion and html5Test property changes will not take effect until reboot().",noURL:ua+"Flash URL required. Call soundManager.setup({url:...}) to get started.",sm2Loaded:"SoundManager 2: Ready. "+String.fromCharCode(10003),reset:ta+".reset(): Removing event callbacks",mobileUA:"Mobile UA detected, preferring HTML5 by default.",globalHTML5:"Using singleton HTML5 Audio() pattern for this device."},O=function(){var a,b,c,d,e;if(a=Ra.call(arguments),d=a.shift(),e=A&&A[d]?A[d]:"",e&&a&&a.length)for(b=0,c=a.length;c>b;b++)e=e.replace("%s",a[b]);return e},T=function(a){return 8===l&&a.loops>1&&a.stream&&(n("as2loop"),a.stream=!1),a},U=function(a,b){return a&&!a.usePolicyFile&&(a.onid3||a.usePeakData||a.useWaveformData||a.useEQData)&&(qa._wD((b||"")+O("policy")),a.usePolicyFile=!0),a},V=function(a){ab&&console.warn!==b?console.warn(a):qa._wD(a)},i=function(){return!1},L=function(a){var b;for(b in a)a.hasOwnProperty(b)&&"function"==typeof a[b]&&(a[b]=i);b=null},M=function(a){a===b&&(a=!1),(Ea||a)&&qa.disable(a)},N=function(a){var b,c=null;if(a)if(a.match(/\.swf(\?.*)?$/i)){if(c=a.substr(a.toLowerCase().lastIndexOf(".swf?")+4))return a}else a.lastIndexOf("/")!==a.length-1&&(a+="/");return b=(a&&-1!==a.lastIndexOf("/")?a.substr(0,a.lastIndexOf("/")+1):"./")+qa.movieURL,qa.noSWFCache&&(b+="?ts="+(new Date).getTime()),b},y=function(){l=parseInt(qa.flashVersion,10),8!==l&&9!==l&&(qa._wD(O("badFV",l,Ia)),qa.flashVersion=l=Ia);var a=qa.debugMode||qa.debugFlash?"_debug.swf":".swf";qa.useHTML5Audio&&!qa.html5Only&&qa.audioFormats.mp4.required&&9>l&&(qa._wD(O("needfl9")),qa.flashVersion=l=9),qa.version=qa.versionNumber+(qa.html5Only?" (HTML5-only mode)":9===l?" (AS3/Flash 9)":" (AS2/Flash 8)"),l>8?(qa.defaultOptions=p(qa.defaultOptions,qa.flash9Options),qa.features.buffering=!0,qa.defaultOptions=p(qa.defaultOptions,qa.movieStarOptions),qa.filePatterns.flash9=new RegExp("\\.(mp3|"+lb.join("|")+")(\\?.*)?$","i"),qa.features.movieStar=!0):qa.features.movieStar=!1,qa.filePattern=qa.filePatterns[8!==l?"flash9":"flash8"],qa.movieURL=(8===l?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",a),qa.features.peakData=qa.features.waveformData=qa.features.eqData=l>8},J=function(a,b){return sa?void sa._setPolling(a,b):!1},K=function(){if(qa.debugURLParam.test(xa)&&(qa.debugMode=!0),h(qa.debugID))return!1;var a,b,c,d,e;if(qa.debugMode&&!h(qa.debugID)&&(!ab||!qa.useConsole||!qa.consoleOnly)){a=ya.createElement("div"),a.id=qa.debugID+"-toggle",d={position:"fixed",bottom:"0px",right:"0px",width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001},a.appendChild(ya.createTextNode("-")),a.onclick=S,a.title="Toggle SM2 debug console",wa.match(/msie 6/i)&&(a.style.position="absolute",a.style.cursor="hand");for(e in d)d.hasOwnProperty(e)&&(a.style[e]=d[e]);if(b=ya.createElement("div"),b.id=qa.debugID,b.style.display=qa.debugMode?"block":"none",qa.debugMode&&!h(a.id)){try{c=G(),c.appendChild(a)}catch(f){throw new Error(O("domError")+" \n"+f.toString())}c.appendChild(b)}}c=null},W=this.getSoundById,n=function(a,b){return a?qa._wD(O(a),b):""},S=function(){var a=h(qa.debugID),b=h(qa.debugID+"-toggle");return a?(Aa?(b.innerHTML="+",a.style.display="none"):(b.innerHTML="-",a.style.display="block"),void(Aa=!Aa)):!1},m=function(c,d,e){if(a.sm2Debugger!==b)try{sm2Debugger.handleEvent(c,d,e)}catch(f){return!1}return!0},Q=function(){var a=[];return qa.debugMode&&a.push(R.sm2Debug),qa.debugFlash&&a.push(R.flashDebug),qa.useHighPerformance&&a.push(R.highPerf),a.join(" ")},P=function(){var a=O("fbHandler"),b=qa.getMoviePercent(),c=R,d={type:"FLASHBLOCK"};return qa.html5Only?!1:void(qa.ok()?(qa.didFlashBlock&&qa._wD(a+": Unblocked"),qa.oMC&&(qa.oMC.className=[Q(),c.swfDefault,c.swfLoaded+(qa.didFlashBlock?" "+c.swfUnblocked:"")].join(" "))):(Qa&&(qa.oMC.className=Q()+" "+c.swfDefault+" "+(null===b?c.swfTimedout:c.swfError),qa._wD(a+": "+O("fbTimeout")+(b?" ("+O("fbLoaded")+")":""))),qa.didFlashBlock=!0,t({type:"ontimeout",ignoreInit:!0,error:d}),I(d)))},s=function(a,c,d){za[a]===b&&(za[a]=[]),za[a].push({method:c,scope:d||null,fired:!1})},t=function(a){if(a||(a={type:qa.ok()?"onready":"ontimeout"}),!Da&&a&&!a.ignoreInit)return!1;if("ontimeout"===a.type&&(qa.ok()||Ea&&!a.ignoreInit))return!1;var b,c,d={success:a&&a.ignoreInit?qa.ok():!Ea},e=a&&a.type?za[a.type]||[]:[],f=[],g=[d],h=Qa&&!qa.ok();for(a.error&&(g[0].error=a.error),b=0,c=e.length;c>b;b++)e[b].fired!==!0&&f.push(e[b]);if(f.length)for(b=0,c=f.length;c>b;b++)f[b].scope?f[b].method.apply(f[b].scope,g):f[b].method.apply(this,g),h||(f[b].fired=!0);return!0},u=function(){a.setTimeout(function(){qa.useFlashBlock&&P(),t(),"function"==typeof qa.onload&&(n("onload",1),qa.onload.apply(a),n("onloadOK",1)),qa.waitForWindowLoad&&ha.add(a,"load",u)},1)},ka=function(){if(ja!==b)return ja;var c,d,e,f=!1,g=navigator,h=g.plugins,i=a.ActiveXObject;if(h&&h.length)d="application/x-shockwave-flash",e=g.mimeTypes,e&&e[d]&&e[d].enabledPlugin&&e[d].enabledPlugin.description&&(f=!0);else if(i!==b&&!wa.match(/MSAppHost/i)){try{c=new i("ShockwaveFlash.ShockwaveFlash")}catch(j){c=null}f=!!c,c=null}return ja=f,f},aa=function(){var a,b,c=qa.audioFormats,d=Ua&&!!wa.match(/os (1|2|3_0|3_1)\s/i);if(d?(qa.hasHTML5=!1,qa.html5Only=!0,qa.oMC&&(qa.oMC.style.display="none")):qa.useHTML5Audio&&(qa.html5&&qa.html5.canPlayType||(qa._wD("SoundManager: No HTML5 Audio() support detected."),qa.hasHTML5=!1),_a&&qa._wD(ua+"Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - "+(ja?"will use flash fallback for MP3/MP4, if available":" would use flash fallback for MP3/MP4, but none detected."),1)),qa.useHTML5Audio&&qa.hasHTML5){_=!0;for(b in c)c.hasOwnProperty(b)&&c[b].required&&(qa.html5.canPlayType(c[b].type)?qa.preferFlash&&(qa.flash[b]||qa.flash[c[b].type])&&(a=!0):(_=!1,a=!0))}return qa.ignoreFlash&&(a=!1,_=!0),qa.html5Only=qa.hasHTML5&&qa.useHTML5Audio&&!a,!qa.html5Only},$=function(a){var b,c,d,e=0;if(a instanceof Array){for(b=0,c=a.length;c>b;b++)if(a[b]instanceof Object){if(qa.canPlayMIME(a[b].type)){e=b;break}}else if(qa.canPlayURL(a[b])){e=b;break}a[e].url&&(a[e]=a[e].url),d=a[e]}else d=a;return d},X=function(a){a._hasTimer||(a._hasTimer=!0,!$a&&qa.html5PollingInterval&&(null===Oa&&0===Na&&(Oa=setInterval(Z,qa.html5PollingInterval)),Na++))},Y=function(a){a._hasTimer&&(a._hasTimer=!1,!$a&&qa.html5PollingInterval&&Na--)},Z=function(){var a;if(null!==Oa&&!Na)return clearInterval(Oa),Oa=null,!1;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].isHTML5&&qa.sounds[qa.soundIDs[a]]._hasTimer&&qa.sounds[qa.soundIDs[a]]._onTimer()},I=function(c){c=c!==b?c:{},"function"==typeof qa.onerror&&qa.onerror.apply(a,[{type:c.type!==b?c.type:null}]),c.fatal!==b&&c.fatal&&qa.disable()},la=function(){if(!_a||!ka())return!1;var a,b,c=qa.audioFormats;for(b in c)if(c.hasOwnProperty(b)&&("mp3"===b||"mp4"===b)&&(qa._wD(ta+": Using flash fallback for "+b+" format"),qa.html5[b]=!1,c[b]&&c[b].related))for(a=c[b].related.length-1;a>=0;a--)qa.html5[c[b].related[a]]=!1},this._setSandboxType=function(a){var c=qa.sandbox;c.type=a,c.description=c.types[c.types[a]!==b?a:"unknown"],"localWithFile"===c.type?(c.noRemote=!0,c.noLocal=!1,n("secNote",2)):"localWithNetwork"===c.type?(c.noRemote=!1,c.noLocal=!0):"localTrusted"===c.type&&(c.noRemote=!1,c.noLocal=!1)},this._externalInterfaceOK=function(a){if(qa.swfLoaded)return!1;var b;return m("swf",!0),m("flashtojs",!0),qa.swfLoaded=!0,cb=!1,_a&&la(),a&&a.replace(/\+dev/i,"")===qa.versionNumber.replace(/\+dev/i,"")?void setTimeout(k,Wa?100:1):(b=ta+': Fatal: JavaScript file build "'+qa.versionNumber+'" does not match Flash SWF build "'+a+'" at '+qa.url+". Ensure both are up-to-date.",setTimeout(function(){throw new Error(b)},0),!1)},H=function(a,c){function d(){var a,b=[],c=[],d=" + ";a="SoundManager "+qa.version+(!qa.html5Only&&qa.useHTML5Audio?qa.hasHTML5?" + HTML5 audio":", no HTML5 audio support":""),qa.html5Only?qa.html5PollingInterval&&b.push("html5PollingInterval ("+qa.html5PollingInterval+"ms)"):(qa.preferFlash&&b.push("preferFlash"),qa.useHighPerformance&&b.push("useHighPerformance"),qa.flashPollingInterval&&b.push("flashPollingInterval ("+qa.flashPollingInterval+"ms)"),qa.html5PollingInterval&&b.push("html5PollingInterval ("+qa.html5PollingInterval+"ms)"),qa.wmode&&b.push("wmode ("+qa.wmode+")"),qa.debugFlash&&b.push("debugFlash"),qa.useFlashBlock&&b.push("flashBlock")),b.length&&(c=c.concat([b.join(d)])),qa._wD(a+(c.length?d+c.join(", "):""),1),na()}function e(a,b){return'<param name="'+a+'" value="'+b+'" />'}if(Ba&&Ca)return!1;if(qa.html5Only)return y(),d(),qa.oMC=h(qa.movieID),k(),Ba=!0,Ca=!0,!1;var f,g,i,j,l,m,n,o,p=c||qa.url,q=qa.altURL||p,r="JS/Flash audio component (SoundManager 2)",s=G(),t=Q(),u=null,v=ya.getElementsByTagName("html")[0];if(u=v&&v.dir&&v.dir.match(/rtl/i),a=a===b?qa.id:a,y(),qa.url=N(ib?p:q),c=qa.url,qa.wmode=!qa.wmode&&qa.useHighPerformance?"transparent":qa.wmode,null!==qa.wmode&&(wa.match(/msie 8/i)||!Wa&&!qa.useHighPerformance)&&navigator.platform.match(/win32|win64/i)&&(Pa.push(A.spcWmode),qa.wmode=null),f={name:a,id:a,src:c,quality:"high",allowScriptAccess:qa.allowScriptAccess,bgcolor:qa.bgColor,pluginspage:jb+"www.macromedia.com/go/getflashplayer",title:r,type:"application/x-shockwave-flash",wmode:qa.wmode,hasPriority:"true"},qa.debugFlash&&(f.FlashVars="debug=1"),qa.wmode||delete f.wmode,Wa)g=ya.createElement("div"),j=['<object id="'+a+'" data="'+c+'" type="'+f.type+'" title="'+f.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+jb+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">',e("movie",c),e("AllowScriptAccess",qa.allowScriptAccess),e("quality",f.quality),qa.wmode?e("wmode",qa.wmode):"",e("bgcolor",qa.bgColor),e("hasPriority","true"),qa.debugFlash?e("FlashVars",f.FlashVars):"","</object>"].join("");else{g=ya.createElement("embed");for(i in f)f.hasOwnProperty(i)&&g.setAttribute(i,f[i])}if(K(),t=Q(),s=G())if(qa.oMC=h(qa.movieID)||ya.createElement("div"),qa.oMC.id)o=qa.oMC.className,qa.oMC.className=(o?o+" ":R.swfDefault)+(t?" "+t:""),qa.oMC.appendChild(g),Wa&&(l=qa.oMC.appendChild(ya.createElement("div")),l.className=R.swfBox,l.innerHTML=j),Ca=!0;else{if(qa.oMC.id=qa.movieID,qa.oMC.className=R.swfDefault+" "+t,m=null,l=null,qa.useFlashBlock||(qa.useHighPerformance?m={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(m={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},u&&(m.left=Math.abs(parseInt(m.left,10))+"px"))),Xa&&(qa.oMC.style.zIndex=1e4),!qa.debugFlash)for(n in m)m.hasOwnProperty(n)&&(qa.oMC.style[n]=m[n]);try{Wa||qa.oMC.appendChild(g),s.appendChild(qa.oMC),Wa&&(l=qa.oMC.appendChild(ya.createElement("div")),l.className=R.swfBox,l.innerHTML=j),Ca=!0}catch(w){throw new Error(O("domError")+" \n"+w.toString())}}return Ba=!0,d(),!0},B=function(){return qa.html5Only?(H(),!1):sa?!1:qa.url?(sa=qa.getMovie(qa.id),sa||(Ja?(Wa?qa.oMC.innerHTML=Ka:qa.oMC.appendChild(Ja),Ja=null,Ba=!0):H(qa.id,qa.url),sa=qa.getMovie(qa.id)),"function"==typeof qa.oninitmovie&&setTimeout(qa.oninitmovie,1),oa(),!0):(n("noURL"),!1)},v=function(){setTimeout(w,1e3)},x=function(){a.setTimeout(function(){V(ua+"useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false..."),qa.setup({preferFlash:!1}).reboot(),qa.didFlashBlock=!0,qa.beginDelayedInit()},1)},w=function(){var b,c=!1;return qa.url?La?!1:(La=!0,ha.remove(a,"load",v),ja&&cb&&!bb?(n("waitFocus"),!1):(Da||(b=qa.getMoviePercent(),b>0&&100>b&&(c=!0)),void setTimeout(function(){return b=qa.getMoviePercent(),c?(La=!1,qa._wD(O("waitSWF")),a.setTimeout(v,1),!1):(Da||(qa._wD(ta+": No Flash response within expected time. Likely causes: "+(0===b?"SWF load failed, ":"")+"Flash blocked or JS-Flash security error."+(qa.debugFlash?" "+O("checkSWF"):""),2),!ib&&b&&(n("localFail",2),qa.debugFlash||n("tryDebug",2)),0===b&&qa._wD(O("swf404",qa.url),1),m("flashtojs",!1," (Check flash security or flash blockers)")),void(!Da&&db&&(null===b?qa.useFlashBlock||0===qa.flashLoadTimeout?(qa.useFlashBlock&&P(),n("waitForever")):!qa.useFlashBlock&&_?x():(n("waitForever"),t({type:"ontimeout",ignoreInit:!0,error:{type:"INIT_FLASHBLOCK"}})):0===qa.flashLoadTimeout?n("waitForever"):!qa.useFlashBlock&&_?x():M(!0))))},qa.flashLoadTimeout))):!1},z=function(){function b(){ha.remove(a,"focus",z)}return bb||!cb?(b(),!0):(db=!0,bb=!0,n("gotFocus"),La=!1,v(),b(),!0)},oa=function(){Pa.length&&(qa._wD("SoundManager 2: "+Pa.join(" "),1),Pa=[])},na=function(){oa();var a,b=[];if(qa.useHTML5Audio&&qa.hasHTML5){for(a in qa.audioFormats)qa.audioFormats.hasOwnProperty(a)&&b.push(a+" = "+qa.html5[a]+(!qa.html5[a]&&Qa&&qa.flash[a]?" (using flash)":qa.preferFlash&&qa.flash[a]&&Qa?" (preferring flash)":qa.html5[a]?"":" ("+(qa.audioFormats[a].required?"required, ":"")+"and no flash support)"));qa._wD("SoundManager 2 HTML5 support: "+b.join(", "),1)}},o=function(b){if(Da)return!1;if(qa.html5Only)return n("sm2Loaded",1),Da=!0,u(),m("onload",!0),!0;var c,d=qa.useFlashBlock&&qa.flashLoadTimeout&&!qa.getMoviePercent(),e=!0;return d||(Da=!0),c={type:!ja&&Qa?"NO_FLASH":"INIT_TIMEOUT"},qa._wD("SoundManager 2 "+(Ea?"failed to load":"loaded")+" ("+(Ea?"Flash security/load error":"OK")+") "+String.fromCharCode(Ea?10006:10003),Ea?2:1),Ea||b?(qa.useFlashBlock&&qa.oMC&&(qa.oMC.className=Q()+" "+(null===qa.getMoviePercent()?R.swfTimedout:R.swfError)),t({type:"ontimeout",error:c,ignoreInit:!0}),m("onload",!1),I(c),e=!1):m("onload",!0),Ea||(qa.waitForWindowLoad&&!Fa?(n("waitOnload"),ha.add(a,"load",u)):(qa.waitForWindowLoad&&Fa&&n("docLoaded"),u())),e},j=function(){var a,c=qa.setupOptions;for(a in c)c.hasOwnProperty(a)&&(qa[a]===b?qa[a]=c[a]:qa[a]!==c[a]&&(qa.setupOptions[a]=qa[a]))},k=function(){function b(){ha.remove(a,"load",qa.beginDelayedInit)}if(Da)return n("didInit"),!1;if(qa.html5Only)return Da||(b(),qa.enabled=!0,o()),!0;B();try{sa._externalInterfaceTest(!1),J(!0,qa.flashPollingInterval||(qa.useHighPerformance?10:50)),qa.debugMode||sa._disableDebug(),qa.enabled=!0,m("jstoflash",!0),qa.html5Only||ha.add(a,"unload",i)}catch(c){return qa._wD("js/flash exception: "+c.toString()),m("jstoflash",!1),I({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),M(!0),o(),!1}return o(),b(),!0},D=function(){return F?!1:(F=!0,j(),K(),function(){var a="sm2-usehtml5audio=",b="sm2-preferflash=",c=null,d=null,e=xa.toLowerCase();-1!==e.indexOf(a)&&(c="1"===e.charAt(e.indexOf(a)+a.length),ab&&console.log((c?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"),qa.setup({useHTML5Audio:c})),-1!==e.indexOf(b)&&(d="1"===e.charAt(e.indexOf(b)+b.length),ab&&console.log((d?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),qa.setup({preferFlash:d}))}(),!ja&&qa.hasHTML5&&(qa._wD("SoundManager 2: No Flash detected"+(qa.useHTML5Audio?". Trying HTML5-only mode.":", enabling HTML5."),1),qa.setup({useHTML5Audio:!0,preferFlash:!1})),ga(),!ja&&Qa&&(Pa.push(A.needFlash),qa.setup({flashLoadTimeout:1})),ya.removeEventListener&&ya.removeEventListener("DOMContentLoaded",D,!1),B(),!0)},fa=function(){return"complete"===ya.readyState&&(D(),ya.detachEvent("onreadystatechange",fa)),!0},E=function(){Fa=!0,D(),ha.remove(a,"load",E)},C=function(){$a&&((!qa.setupOptions.useHTML5Audio||qa.setupOptions.preferFlash)&&Pa.push(A.mobileUA),qa.setupOptions.useHTML5Audio=!0,qa.setupOptions.preferFlash=!1,(Ua||Va&&!wa.match(/android\s2\.3/i))&&(Pa.push(A.globalHTML5),Ua&&(qa.ignoreFlash=!0),Sa=!0))},C(),ka(),ha.add(a,"focus",z),ha.add(a,"load",v),ha.add(a,"load",E),ya.addEventListener?ya.addEventListener("DOMContentLoaded",D,!1):ya.attachEvent?ya.attachEvent("onreadystatechange",fa):(m("onload",!1),I({type:"NO_DOM2_EVENTS",fatal:!0}))}if(!a||!a.document)throw new Error("SoundManager requires a browser with window and document objects.");var d=null;void 0!==a.SM2_DEFER&&SM2_DEFER||(d=new c),"object"==typeof module&&module&&"object"==typeof module.exports?(a.soundManager=d,module.exports.SoundManager=c,module.exports.soundManager=d):"function"==typeof define&&define.amd?define("SoundManager",[],function(){return{SoundManager:c,soundManager:d}}):(a.SoundManager=c,a.soundManager=d)}(window),window.JST["apps/album/show/tpl/album_with_songs.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="album album--with-songs">\n <div class="region-album-side">\n <div class="region-album-meta"></div>\n </div>\n <div class="region-album-content">\n <div class="region-album-songs"></div>\n </div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/album/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub"><a href="#music/albums?year=')),d(this.year),d(b('">')),d(this.year),d(b("</a></span></h2>\n </div>\n ")),this.rating&&(d(b('\n <div class="region-details-rating">\n ')),d(this.rating),d(b(" <i></i>\n </div>\n "))),d(b('\n</div>\n\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.artist&&(d(b("\n <li><label>")),d(tr("artist")),d(b(':</label> <span><a href="#music/artist/')),d(this.artistid),d(b('">')),d(this.artist),d(b("</a></span></li>\n "))),d(b("\n ")),this.genre.length>0&&(d(b("\n <li><label>")),d(t.ngettext("genre","genres",this.genre.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.style.length&&(d(b("\n <li><label>")),d(t.ngettext("style","styles",this.style.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","style",this.style))),d(b("</span></li>\n "))),d(b("\n ")),this.albumlabel&&(d(b("\n <li><label>")),d(tr("label")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","albumlabel",[this.albumlabel]))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <div class="description">')),d(this.description),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream localplay">')),d(tr("Stream")),d(b('</li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="localadd">')),d(tr("Add to playlist")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.artist),d(b(" ")),d(this.label),d(b('">Google</li>\n <li data-type="soundcloud" data-query="')),d(this.artist),d(b('">SoundCloud</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.artist),d(b(" ")),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/artist/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2>')),d(this.label),d(b('</h2>\n </div>\n</div>\n\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(t.ngettext("genre","genres",this.genre.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/artists","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.style.length&&(d(b("\n <li><label>")),d(t.ngettext("style","styles",this.style.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/artists","style",this.style))),d(b("</span></li>\n "))),d(b("\n ")),this.formed&&(d(b("\n <li><label>")),d(tr("formed")),d(b(":</label> <span>")),d(this.formed),d(b("</span></li>\n "))),d(b("\n ")),this.yearsactive&&this.yearsactive.length>0&&(d(b("\n <li><label>")),d(tr("years active")),d(b(":</label> <span>")),d(this.yearsactive),d(b("</span></li>\n "))),d(b("\n ")),this.born&&(d(b("\n <li><label>")),d(tr("born")),d(b(":</label> <span>")),d(this.born),d(b("</span></li>\n "))),d(b("\n ")),this.died&&(d(b("\n <li><label>")),d(tr("died")),d(b(":</label> <span>")),d(this.died),d(b("</span></li>\n "))),d(b("\n ")),this.disbanded&&(d(b("\n <li><label>")),d(tr("disbanded")),d(b(":</label> <span>")),d(this.disbanded),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <div class="description">')),d(this.description),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream localplay">')),d(tr("Stream")),d(b('</li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="localadd">')),d(tr("Add to playlist")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="soundcloud" data-query="')),d(this.label),d(b('">SoundCloud</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/back_button.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<i class="mdi thumb"></i><div class="title">')),d(t.gettext("Back")),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/file.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="thumb" style="background-image: url(\'')),d(this.thumbnail),d(b('\')"><div class="mdi play"></div></div>\n<div class="title" title="')),d(helpers.global.stripTags(this.label)),d(b('">')),d(b(this.label)),d(b('</div>\n<ul class="actions">\n <li class="menu dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu pull-right"></ul>\n </li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/folder_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="folder-layout">\n <div class="loading-bar"><div class="inner"><div class="loader-small-inline"></div> <span>')),d(tr("Loading folder...")),d(b('</span></div></div>\n <div class="path"></div>\n <ul class="actions">\n <li class="dropdown sort-wrapper">\n <i class="sort-toggle" data-toggle="dropdown" title="')),d(tr("Sort")),d(b('"></i>\n <ul class="sorts dropdown-menu pull-right">\n <li data-sort="none">')),d(tr("default")),d(b('<i></i></li>\n <li data-sort="label">')),d(tr("title")),d(b('<i></i></li>\n <li data-sort="dateadded">')),d(tr("date added")),d(b('<i></i></li>\n <li data-sort="random">')),d(tr("random")),d(b('<i></i></li>\n </ul>\n </li>\n <li class="dropdown context-wrapper">\n <i class="context-toggle" data-toggle="dropdown" title="')),d(tr("Actions")),d(b('"></i>\n <ul class="dropdown-menu pull-right">\n <li class="play">')), -d(tr("play files")),d(b('<i></i></li>\n <li class="queue">')),d(tr("queue files")),d(b('<i></i></li>\n </ul>\n </li>\n </ul>\n\n\n <div class="folder-container">\n <div class="files">\n </div>\n <div class="folders-pane">\n <div class="back"></div>\n <div class="folders">\n <div class="intro">\n <h3><span class="mdi-navigation-arrow-back text-dim"></span> ')),d(tr("Browse files and add-ons")),d(b("</h3>\n <p>")),d(tr("This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.")),d(b("</p>\n </div>\n </div>\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/path.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">')),d(this.label),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/source.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="source source-')),d(this.media),d(b('">\n ')),d(this.label),d(b("\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/source_set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.label),d(b('</h3>\n<ul class="sources"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/cast/list/tpl/cast.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a href="#')),d(this.origin),d(b("?cast=")),d(this.name),d(b('" title="')),d(this.name),d(b(" (")),d(this.role),d(b(')">\n <div class="thumb">\n <img src="')),d(this.thumbnail),d(b('" />\n </div>\n <div class="meta">\n <strong>')),d(this.name),d(b('</strong>\n <span title="')),d(this.role),d(b('">')),d(this.role),d(b('</span>\n </div>\n</a>\n<ul class="actions">\n <li class="imdb" title="IMDb search ')),d(this.name),d(b('"></li>\n <li class="google" title="Google search ')),d(this.name),d(b('"></li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/category/list/tpl/item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a href="#')),d(this.url),d(b('">\n <span>')),d(this.title),d(b("</span>\n</a>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/epg/list/tpl/channel.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.channel),d(b('</h3>\n<ul class="items">\n <li class="play">')),d(tr("Play")),d(b('</li>\n <li class="record">')),d(tr("Record")),d(b("</li>\n</ul>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/epg/list/tpl/programme.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">\n <strong>')),d(this.label),d(b('</strong>\n</div>\n<div class="date">\n ')),d(this.start.toString("h:mmtt").toLowerCase()),d(b(" - ")),d(this.end.toString("h:mmtt").toLowerCase()),d(b(" (")),d(this.runtime),d(b("min)<br />\n ")),d(this.start.toString("dddd, dS MMM")),d(b('\n</div>\n<div class="plot">')),d(this.plot),d(b('</div>\n<div class="entity-progress">\n <div class="current-progress" style="width: ')),d(this.progresspercentage),d(b('%" title="')),d(Math.round(this.progresspercentage)),d(b("% ")),d(tr("complete")),d(b('"></div>\n</div>\n<ul class="actions">\n ')),this.isactive?(d(b('\n <li class="play" title="')),d(tr("Play")),d(b('"></li>\n <li class="record" title="')),d(tr("Record")),d(b('"></li>\n '))):(d(b("\n ")),this.wasactive||(d(b('\n <li class="toggle-timer" title="')),d(tr("Toggle timer")),d(b('"></li>\n '))),d(b("\n "))),d(b("\n</ul>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/external/youtube/tpl/youtube.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<img src="')),d(this.thumbnail),d(b('" class="thumb" />\n<h3>')),d(this.title),d(b('</h3>\n<span class="play-kodi flat-btn action">Play in Kodi</span>\n<span class="play-local flat-btn action">Play in browser</span>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filter_options.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="options-search-wrapper">\n <input class="options-search" value="" />\n</div>\n<div class="deselect-all">')),d(t.gettext("Deselect all")),d(b('</div>\n<ul class="selection-list"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filters_bar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<span class="filters-active-all">')),d(this.filters),d(b('</span><i class="remove"></i>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filters_ui.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="filters-container">\n\n <div class="filters-current filter-pane">\n <div class="nav-section"></div>\n\n <h3 class="open-filters">')),d(t.gettext("Filters")),d(b('<i></i></h3>\n <div class="filters-active"></div>\n\n <h3>')),d(t.gettext("Sort")),d(b('</h3>\n <div class="list sort-options"></div>\n </div>\n\n <div class="filters-page filter-pane">\n <h3 class="close-filters">')),d(t.gettext("Select a filter")),d(b('</h3>\n <div class="list filters-list"></div>\n </div>\n\n <div class="filters-options filter-pane">\n <h3 class="close-options">')),d(t.gettext("Select an option")),d(b('</h3>\n <div class="list filter-options-list"></div>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/list_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b(this.title))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/help/overview/tpl/overview.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h1>")),d(tr("About Chorus")),d(b("</h1>\n<h2>")),d(tr("Status report")),d(b('</h2>\n<div class="help--overview--report">\n <ul>\n <li class="report-chorus-version"><strong>Chorus ')),d(tr("version")),d(b('</strong><span></span></li>\n <li class="report-kodi-version"><strong>Kodi ')),d(tr("version")),d(b('</strong><span></span></li>\n <li class="report-websockets"><strong>')),d(tr("Remote control")),d(b('</strong><span></span></li>\n <li class="report-local-audio"><strong>')),d(tr("Local audio")),d(b('</strong><span></span></li>\n </ul>\n</div>\n<div class="help--overview--header"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/input/remote/tpl/remote_control.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="remote-background" class="close-remote"></div>\n<div class="remote kodi-remote">\n <div class="toggle-visibility"></div>\n <div class="playing-area">\n\n </div>\n <div class="main-controls">\n <div class="direction">\n <div class="pad">\n <div class="ibut mdi-hardware-keyboard-arrow-left left input-button" data-type="Left"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-up up input-button" data-type="Up"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-down down input-button" data-type="Down"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-right right input-button" data-type="Right"></div>\n <div class="ibut mdi-image-brightness-1 ok input-button" data-type="Select"></div>\n </div>\n </div>\n <div class="buttons">\n <div class="ibut mdi-action-settings-power power-button"></div>\n <div class="ibut mdi-navigation-more-vert input-button" data-type="ContextMenu"></div>\n <div class="ibut mdi-action-info info-button" data-type="Info"></div>\n </div>\n </div>\n <div class="secondary-controls">\n <div class="ibut mdi-hardware-keyboard-return input-button" data-type="Back"></div>\n <div class="ibut mdi-av-stop player-button" data-type="Stop"></div>\n <div class="ibut mdi-maps-store-mall-directory input-button" data-type="Home"></div>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_browser_landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-browser--landing page">\n <h2>')),d(t.gettext("Kodi API browser")),d(b('</h2>\n <h4><a href="#lab">')),d(t.gettext("Chorus lab")),d(b('</a></h4>\n <div class="api-browser--content">\n <p>')),d(t.gettext("This is a tool to test out the api. Select a method then execute it with parameters.")),d(b('</p>\n <br />\n <div class="alert alert-dismissable alert-warning">\n <button type="button" class="close" data-dismiss="alert">×</button>\n <h4>')),d(t.gettext("Warning")),d(b("</h4>\n <p>")),d(t.gettext("You could potentially damage your system with this and there are no sanity checks. Use at own risk.")),d(b("<br /></p>\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-method--item">\n <h4 class="method">')),d(this.method),d(b('</h4>\n <p class="description">')),d(this.description),d(b("</p>\n</div>\n\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-methods--list">\n <p class="search-box"><input type="text" id="api-search" class="api-methods--search" /></p>\n <ul class="items"></ul>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('\n<div class="api-method--info page">\n <h2 class="method"><a href="http://kodi.wiki/view/JSON-RPC_API/v6#')),d(this.method),d(b('" target="_blank">')),d(this.method),d(b('</a></h2>\n <p class="description">')),d(this.description),d(b("</p>\n\n</div>\n\n")),"method"===this.type&&(d(b('\n <div class="api-method--execute">\n <h3>Execute <strong>')),d(this.method),d(b('</strong> with these params:</h3>\n <textarea class="api-method--params" placeholder=\'Eg. ["arg", "foo", true]\'></textarea>\n <p class="description">Parameters get parsed by\n <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" target="_blank">JSON.parse</a>.\n Check the console for response objects, you will get an \'unexpected token\' error if parsing failed.\n Params should be an array \'[]\' matching below \'Method params\'. Only use double quotes for strings/keys.\n </p>\n <p class="description">\n Pass params as array Eg. [true] or [255, ["born", "formed", "thumbnail"]] or [] or [255]. Brackets required.<br />\n Pass params as object Eg. {songid: 255} or {songid: 255, fields: ["born", "formed", "thumbnail"]}. Braces required.<br />\n </p>\n <p><button class="btn btn-primary" id="send-command">Send Command</button></p>\n\n </div>\n'))),d(b('\n\n<div class="api-method--result" id="api-result"></div>\n\n<h3>')),"method"===this.type&&d(b("Method ")),d(b('Params</h3>\n<div class="api-method--params"></div>\n\n')),"method"===this.type&&d(b('\n <hr />\n <h3>Method Returns</h3>\n <div class="api-method--return"></div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/iconBrowser/tpl/icon_browser_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h3>Material Icons</h3>\n<ul id="icons-material"></ul>\n\n<h3>Custom Icons</h3>\n<ul id="icons-custom"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/lab/tpl/lab_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a class="lab-item" href="#')),d(this.path),d(b('">\n <h4>')),d(this.title),d(b("</h4>\n <p>")),d(this.description),d(b("</p>\n</a>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/landing/show/tpl/landing_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a id="landing-hero"></a>\n<div class="landing-sections">\n <div id="landing-section-1"></div>\n <div id="landing-section-2"></div>\n <div id="landing-section-3"></div>\n <div id="landing-section-4"></div>\n <div id="landing-section-5"></div>\n <div id="landing-section-6"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/landing/show/tpl/landing_set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h3 class="set-header"></h3>\n<div class="set-results landing-section"></div>\n<div class="more"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/loading/show/tpl/loading_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="loading-page">\n <div class="spinner-double-section-far"></div>\n <h2>')),d(t.gettext("Just a sec...")),d(b("</h2>\n</div>\n\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<span class="item">')),d(b(this.title)),d(b("</span>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="local-playlist-header">\n <h2></h2>\n <div class="dropdown">\n <i data-toggle="dropdown"></i>\n <ul class="dropdown-menu">\n <li class="play">')),d(tr("Play in Kodi")),d(b('</li>\n <li class="localplay">')),d(tr("Play in browser")),d(b('</li>\n <li class="export">')),d(tr("Export list")),d(b('</li>\n <div class="divider"></div>\n <li class="rename">')),d(tr("Rename playlist")),d(b('</li>\n <li class="clear">')),d(tr("Clear playlist")),d(b('</li>\n <li class="delete">')),d(tr("Delete playlist")),d(b('</li>\n </ul>\n </div>\n</div>\n<div class="item-container">\n <div class="empty-content">')),d(t.gettext("Empty playlist, you should probably add something to it?")),d(b("</div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h3></h3>\n<ul class="lists"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_sidebar_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="current-lists"></div>\n<div class="new-list">')),d(tr("New playlist")),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/content.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="section-content">\n <h2>')),d(t.gettext("Synopsis")),d(b("</h2>\n ")),this.mediaTrailer&&"youtube"===this.mediaTrailer.source&&(d(b('\n <div class="trailer ')),d(this.mediaTrailer.source),d(b('">\n <img src="')),d(b(this.mediaTrailer.img)),d(b('" />\n </div>\n '))),d(b("\n <p>")),d(this.plot),d(b('</p>\n <ul class="inline-links">\n <li>')),d(b(helpers.url.imdbUrl(this.imdbnumber,"View on IMDb"))),d(b("</li>\n </ul>\n</div>\n\n")),this.cast.length>0&&(d(b('\n <div class="section-content">\n <h2>')),d(t.gettext("Full cast")),d(b('</h2>\n <div class="region-cast"></div>\n </div>\n'))),d(b('\n\n<div class="region-more-1"></div>\n<div class="region-more-2"></div>\n<div class="region-more-3"></div>\n<div class="region-more-4"></div>\n<div class="region-more-5"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;if(d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub"><a href="#movies?year=')),d(this.year),d(b('">')),d(this.year),d(b('</a></span></h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n\n<div class="region-details-meta-below">\n\n <div class="region-details-subtext">\n <div class="runtime">\n ')),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b('\n </div>\n </div>\n\n <div class="tagline">')),d(this.plotoutline),d(b('</div>\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(t.gettext("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.director.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Director","Directors",this.director.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","director",this.director))),d(b("</span></li>\n "))),d(b("\n ")),this.writer.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Writer","Writers",this.writer.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","writer",this.writer))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(t.gettext("Cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(t.gettext("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <ul class="streams">\n ')),this.streamdetails.video.length>0&&(d(b("\n <li><label>")),d(t.gettext("Video")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.video,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.audio.length>0&&(d(b("\n <li><label>")),d(t.gettext("Audio")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.audio,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.subtitle.length>0&&""!==this.streamdetails.subtitle[0].label){for(d(b("\n <li><label>")),d(t.ngettext("Subtitle","Subtitles",this.streamdetails.subtitle.length)),d(b(':</label>\n <span class="dropdown"><span data-toggle="dropdown">')),d(_.pluck(this.streamdetails.subtitle,"label").join(", ")),d(b('</span>\n <ul class="dropdown-menu">\n ')),e=this.streamdetails.subtitle,a=0,c=e.length;c>a;a++)f=e[a],d(b("\n <li>")),d(f.label),d(b("</li>\n "));d(b("\n </ul>\n </span>\n </li>\n "))}d(b('\n </ul>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(t.gettext("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream stream">')),d(t.gettext("Stream")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(t.gettext("set")),d(b(' <span class="action-watched">')),d(t.gettext("watched")),d(b('</span><span class="action-unwatched">')),d(t.gettext("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="download">')),d(tr("Download")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.label),d(b('">IMDb</li>\n <li data-type="tmdb" data-query="')),d(this.label),d(b('">TVDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="refresh">')),d(tr("Refresh")),d(b('</li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="section-content">\n <div class="set-collection">\n <h2 class="set-name"></h2>\n <div class="collection-items"></div>\n </div>\n</div>')); -}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/navMain.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f,g,h,i,j;for(d(b('<div id="nav-header"></div>\n<nav>\n <ul>\n ')),i=this.items,c=0,g=i.length;g>c;c++)if(e=i[c],"undefined"!==e.path&&0===e.parent){if(d(b('\n <li class="')),d(e["class"]),d(b('">\n <a href="#')),d(e.path),d(b('">\n <i class="')),d(e.icon),d(b('"></i>\n <span>')),d(e.title),d(b("</span>\n </a>\n\n ")),0!==e.children.length){for(d(b("\n <ul>\n ")),j=e.children,f=0,h=j.length;h>f;f++)a=j[f],"undefined"!==a.path&&(d(b('\n <li><a href="#')),d(a.path),d(b('">')),d(a.title),d(b("</a></li>\n ")));d(b("\n </ul>\n "))}d(b("\n </li>\n "))}d(b("\n </ul>\n</nav>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/nav_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b(this.link))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/nav_sub.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.title),d(b('</h3>\n<ul class="items"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/player/show/tpl/player.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="player">\n\n <div class="controls-primary">\n <div class="controls-primary-buttons">\n <div class="control control-prev"></div>\n <div class="control control-play"></div>\n <div class="control control-next"></div>\n </div>\n </div>\n\n <div class="controls-secondary">\n <div class="volume slider-bar"></div>\n <div class="controls-secondary-buttons">\n <div class="control control-mute"></div>\n <div class="control control-repeat"></div>\n <div class="control control-shuffle"></div>\n <div class="control control-menu"></div>\n </div>\n </div>\n\n <div class="now-playing">\n <div class="playing-thumb thumb">\n <div class="mdi remote-toggle"></div>\n </div>\n <div class="playing-info">\n <div class="playing-progress slider-bar"></div>\n <div class="playing-time">\n <div class="playing-time-current">0</div>\n <div class="playing-time-duration">0:00</div>\n </div>\n <div class="playing-meta">\n <div class="playing-title">')),d(t.gettext("Nothing playing")),d(b('</div>\n <div class="playing-subtitle"></div>\n </div>\n </div>\n </div>\n\n</div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/list/tpl/playlist_bar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="playlist-header">\n <ul class="player-toggle">\n <li class="kodi">')),d(t.gettext("Kodi")),d(b('</li>\n <li class="local">')),d(t.gettext("Local")),d(b('</li>\n </ul>\n <div class="playlist-menu dropdown">\n <i data-toggle="dropdown" class="menu-toggle"></i>\n <ul class="dropdown-menu pull-right">\n <li class="dropdown-header">')),d(t.gettext("Current playlist")),d(b('</li>\n <li><a href="#" class="clear-playlist">')),d(t.gettext("Clear playlist")),d(b('</a></li>\n <li><a href="#" class="refresh-playlist">')),d(t.gettext("Refresh playlist")),d(b('</a></li>\n <li class="dropdown-header">')),d(t.gettext("Kodi")),d(b('</li>\n <li><a href="#" class="party-mode">')),d(t.gettext("Party mode")),d(b(' <i class="mdi-navigation-check"></i></a></li>\n <li><a href="#" class="save-playlist">')),d(t.gettext("Save Kodi playlist")),d(b('</a></li>\n </li>\n </ul>\n </div>\n</div>\n<div class="playlists-wrapper">\n <div class="kodi-playlists">\n <ul class="media-toggle">\n <li class="audio">')),d(t.gettext("Audio")),d(b('</li>\n <li class="video">')),d(t.gettext("Video")),d(b('</li>\n </ul>\n <div class="kodi-playlist"></div>\n </div>\n <div class="local-playlists">\n <div class="local-playlist"></div>\n </div>\n</div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/list/tpl/playlist_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="item-inner item-')),d(this.type),d(b('">\n <div class="artwork">\n <div class="thumb" title="')),d(this.label),d(b('" style="background-image: url(\'')),d(this.thumbnail),d(b('\')">\n <div class="mdi play"></div>\n ')),this.canThumbsUp&&d(b('\n <div class="mdi thumbs"></div>\n ')),d(b('\n </div>\n </div>\n <div class="meta">\n <div class="title"><a href="#')),d(this.url),d(b('" title="')),d(this.label),d(b('">')),d(this.label),d(b("</a></div>\n ")),null!=this.subtitle&&(d(b('\n <div class="subtitle">')),d(b(this.subtitle)),d(b("</div>\n "))),d(b('\n </div>\n <div class="remove"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/m3u/tpl/list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;for(d(b("#EXTCPlayListM3U::M3U\n")),f=this.items,a=0,e=f.length;e>a;a++)c=f[a],d(b("#EXTINF:")),d(c.duration),d(b(",")),d(c.artist.join("/")),d(b(" - ")),d(c.label),d(b("\n")),d(c.file),d(b("\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/show/tpl/landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="playlist-page playlist-page__empty set-page">\n <h3>')),d(t.gettext("Now playing - Playlists")),d(b("</h3>\n <p>")),d(t.gettext("Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right")),d(b("</p>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/pvr/recordingList/tpl/recording.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">\n <strong>')),d(this.label),d(b("</strong> <span>- ")),d(this.channel),d(b('</span>\n</div>\n<div class="date">\n ')),d(this.start.toString("h:mmtt").toLowerCase()),d(b(" -\n ")),"1970"!==this.end.toString("yyyy")?(d(b("\n ")),d(this.end.toString("h:mmtt").toLowerCase()),d(b("\n (")),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b(")\n "))):(d(b("\n ")),d(tr("Now")),d(b("\n "))),d(b("\n\n <br />")),d(this.start.toString("dddd, dS MMM")),d(b('\n</div>\n<div class="plot">')),d(this.plot),d(b('</div>\n<div class="entity-progress">\n <div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div>\n</div>\n<ul class="actions">\n <li class="play"></li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/list/tpl/search_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="search-inner">\n <div class="entity-set entity-set-movie"></div>\n <div class="entity-set entity-set-tvshow"></div>\n <div class="entity-set entity-set-artist"></div>\n <div class="entity-set entity-set-album"></div>\n <div class="entity-set entity-set-song"></div>\n <div class="entity-set entity-set-loading"></div>\n <div class="entity-set entity-set-addons"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/list/tpl/search_set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h2 class="set-header"></h2>\n<div class="set-results"></div>\n<div class="more"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/list/tpl/search_sidebar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="sidebar-section sidebar-section-media">\n <h3>Local media</h3>\n <ul class="search-media-links"></ul>\n</div>\n\n<div class="sidebar-section sidebar-section-addon">\n <h3>Addons</h3>\n <ul class="search-addon-links"></ul>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/show/tpl/landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="search-page search-page__empty set-page">\n <h3>')),d(t.gettext("Enter your search above")),d(b("</h3>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/settings/show/tpl/settings_sidebar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="settings-sidebar">\n <div class="settings-sidebar--section local-nav nav-sub"></div>\n <div class="settings-sidebar--section kodi-nav"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/shell/show/tpl/homepage.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="homepage"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/shell/show/tpl/shell.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="shell">\n\n <a id="logo" href="#"></a>\n\n <div id="nav-bar"></div>\n\n <div id="header">\n\n <h1 id="page-title">\n <span class="context"></span>\n <span class="title"></span>\n </h1>\n\n <ul class="mobile-menu">\n <li><a href="#remote" class="mobile-menu--link__remote remote-toggle"><i></i></a></li>\n <li><a href="#search" class="mobile-menu--link__search"><i></i></a></li>\n <li><a href="#playlist" class="mobile-menu--link__playlist"><i></i></a></li>\n </ul>\n\n <div id="selected-region">\n <div class="selected-text">\n <span id="selected-count"></span>\n </div>\n <i data-toggle="dropdown" class="menu-toggle"></i>\n <ul class="dropdown-menu pull-right">\n <li class="selected-play">')),d(tr("Play in Kodi")),d(b('</li>\n <li class="selected-add">')),d(tr("Queue in Kodi")),d(b('</li>\n <li class="selected-localadd">')),d(tr("Add to playlist")),d(b('</li>\n </ul>\n </div>\n\n <div id="search-region">\n <input id="search" title="Search">\n <span id="do-search"></span>\n </div>\n\n </div>\n\n <div id="main">\n\n <div id="sidebar-one"></div>\n\n <div id="content">')),d(tr("Loading things...")),d(b('</div>\n\n </div>\n\n <div id="sidebar-two">\n <div class="playlist-toggle-open"></div>\n <div id="playlist-summary"></div>\n <div id="playlist-bar"></div>\n </div>\n\n <div id="remote"></div>\n\n <div id="player-wrapper">\n <footer id="player-kodi"></footer>\n <footer id="player-local"></footer>\n </div>\n\n <div class="player-menu-wrapper">\n <ul class="player-menu">\n <li class="video-scan">')),d(t.gettext("Scan video library")),d(b('</li>\n <li class="audio-scan">')),d(t.gettext("Scan audio library")),d(b('</li>\n <li class="send-input">')),d(t.gettext("Send text to Kodi")),d(b('</li>\n <li class="goto-lab">')),d(t.gettext("The lab")),d(b('</li>\n <li class="about">')),d(t.gettext("About Chorus")),d(b('</li>\n </ul>\n </div>\n\n</div>\n\n<div id="fanart"></div>\n<div id="fanart-overlay"></div>\n\n<div id="snackbar-container"></div>\n\n<div class="modal fade" id="modal-window">\n <div class="modal-dialog">\n <div class="modal-content">\n <div class="modal-header">\n <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>\n <h4 class="modal-title"></h4>\n </div>\n <div class="modal-body"></div>\n <div class="modal-footer"></div>\n </div>\n </div>\n</div>\n\n<div id="offscreen"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/song/list/tpl/song.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<td class="cell-first">\n <div class="thumb" style="background-image: url(\'')),d(this.thumbnail),d(b('\')">\n </div>\n <div class="track">')),d(this.track),d(b('</div>\n <div class="mdi play"></div>\n</td>\n<td class="cell-label song-title"><span class="crop">')),d(this.label),d(b('</span></td>\n<td class="cell-label song-album"><a class="crop" href="#music/album/')),d(this.albumid),d(b('">')),d(this.album),d(b('</a></td>\n<td class="cell-label song-artist"><a class="crop" href="#music/artist/')),d(this.artistid),d(b('">')),d(this.artist),d(b('</a></td>\n<td class="cell-last">\n <li class="thumbed-up"></li>\n <div class="duration">')),d(this.displayDuration),d(b('</div>\n <ul class="actions">\n <li class="mdi thumbs"></li>\n <li class="mdi add"></li>\n <li class="menu dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu pull-right"></ul>\n </li>\n </ul>\n</td>\n<td class="cell-remove song-remove">\n <i class="mdi mdi-navigation-close"></i>\n</td>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/thumbs/list/tpl/thumbs_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="thumbs-inner">\n <div class="entity-set entity-set-movie"></div>\n <div class="entity-set entity-set-tvshow"></div>\n <div class="entity-set entity-set-episode"></div>\n <div class="entity-set entity-set-artist"></div>\n <div class="entity-set entity-set-album"></div>\n <div class="entity-set entity-set-song"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/thumbs/list/tpl/thumbs_set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h2 class="set-header"></h2>\n<div class="set-results"></div>\n<div class="more"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/episode/tpl/content.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('\n<div class="section-content">\n <h2>')),d(t.gettext("Synopsis")),d(b("</h2>\n <p>")),d(this.plot),d(b("</p>\n</div>\n\n")),this.cast.length>0&&(d(b('\n <div class="section-content">\n <h2>')),d(tr("Full cast")),d(b('</h2>\n <div class="region-cast"></div>\n </div>\n'))),d(b('\n\n<div class="section-content section-full-width">\n <h2>')),d(tr("Season")),d(b(" ")),d(this.season),d(b('</h2>\n <div class="region-season"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/episode/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;if(d(b('<div class="region-details-top">\n ')),null!=this.showtitle&&d(b("\n\n ")),d(b('\n <div class="region-details-title">\n <h2>\n <span class="title">')),d(this.label),d(b('</span>\n <span class="sub show-title"><a href="#')),d(this.url.split("/",2).join("/")),d(b('">')),d(this.showtitle),d(b('</a></span>\n <span class="sub">S')),d(this.season),d(b(" E")),d(this.episode),d(b('</span>\n </h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <div class="region-details-subtext">\n\n ')),this.runtime>0&&(d(b('\n <div class="runtime">\n ')),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b("\n </div>\n "))),d(b('\n\n </div>\n\n <ul class="meta">\n <li><label>')),d(t.gettext("Season")),d(b(':</label> <span><a href="#tvshow/')),d(this.tvshowid),d(b("/")),d(this.season),d(b('">')),d(t.gettext("Season")),d(b(" ")),d(this.season),d(b("</a></span></li>\n ")),this.firstaired&&(d(b("\n <li><label>")),d(t.gettext("First aired")),d(b(":</label> <span>")),d(this.firstaired),d(b(" </span></li>\n "))),d(b("\n ")),this.director.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Director","Directors",this.director.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","director",this.director))),d(b("</span></li>\n "))),d(b("\n ")),this.writer.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Writer","Writers",this.writer.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","writer",this.writer))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(t.gettext("Cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <ul class="streams">\n ')),this.streamdetails.video.length>0&&(d(b("\n <li><label>")),d(t.gettext("Video")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.video,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.audio.length>0&&(d(b("\n <li><label>")),d(t.gettext("Audio")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.audio,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.subtitle.length>0&&""!==this.streamdetails.subtitle[0].label){for(d(b("\n <li><label>")),d(t.ngettext("Subtitle","Subtitles",this.streamdetails.subtitle.length)),d(b(':</label>\n <span class="dropdown"><span data-toggle="dropdown">')),d(_.first(_.pluck(this.streamdetails.subtitle,"label"))),d(b('</span>\n <ul class="dropdown-menu">\n ')),e=this.streamdetails.subtitle,a=0,c=e.length;c>a;a++)f=e[a],d(b("\n <li>")),d(f.label),d(b("</li>\n "));d(b("\n </ul>\n </span>\n </li>\n "))}d(b('\n </ul>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream stream">')),d(tr("Stream")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(t.gettext("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="download">')),d(tr("Download")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.showtitle))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.showtitle),d(b(" ")),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.showtitle),d(b('">IMDb</li>\n <li data-type="tvdb" data-query="')),d(this.showtitle),d(b('">TVDb</li>\n <li data-type="tmdb" data-query="')),d(this.showtitle),d(b('">TMDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.showtitle),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="refresh">')),d(tr("Refresh")),d(b('</li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/season/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2>\n <span class="title">')),d(tr("Season")),d(b(" ")),d(this.season),d(b('</span>\n <span class="sub"><a href="#tvshow/')),d(this.tvshowid),d(b('">')),d(this.label),d(b('</a></span>\n </h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(tr("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(tr("cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.studio.length>0&&(d(b("\n <li><label>")),d(tr("studio")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","studio",this.studio))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(tr("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b("\n <li><label>")),d(tr("episodes")),d(b(':</label> <span><span class="episode-total">')),d(this.episode),d(b("</span> ")),d(tr("total")),d(b(' (<span class="episode-unwatched">')),d(this.unwatched),d(b("</span> ")),d(tr("unwatched")),d(b(')</span></li>\n </ul>\n\n <div class="description">')),d(this.plot),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(tr("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b("</span>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub">')),d(this.year),d(b('</span></h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(tr("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(tr("cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.studio.length>0&&(d(b("\n <li><label>")),d(tr("studio")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","studio",this.studio))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(tr("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b("\n <li><label>")),d(tr("episodes")),d(b(':</label> <span><span class="episode-total">')), -d(this.episode),d(b("</span> ")),d(tr("total")),d(b(' (<span class="episode-unwatched">')),d(this.unwatched),d(b("</span> ")),d(tr("unwatched")),d(b(')</span></li>\n </ul>\n\n <div class="description">')),d(this.plot),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(tr("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.label),d(b('">IMDb</li>\n <li data-type="tvdb" data-query="')),d(this.label),d(b('">TVDb</li>\n <li data-type="tmdb" data-query="')),d(this.label),d(b('">TMDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu">')),d(tr("Refresh")),d(b('\n <ul class="dropdown-menu">\n <li class="refresh">')),d(tr("Show only")),d(b('</li>\n <li class="refresh-episodes">')),d(tr("Show and episodes")),d(b('</li>\n </ul>\n </li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="form-inner">\n <div class="form-content-region"></div>\n <footer>\n <ul class="inline-list">\n <li>\n <button type="submit" data-form-button="submit" class="btn btn-primary form-save">Save</button>\n </li>\n <li class="response">\n\n </li>\n </ul>\n </footer>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){this.title&&(d(b('\n <label class="control-label">')),d(b(this.title)),d(b("</label>\n"))),d(b("\n\n")),"markup"===this.type?(d(b("\n ")),d(b(this.element)),d(b("\n"))):(d(b('\n <div class="element">\n ')),"checkbox"!==this.type?(d(b("\n ")),d(b(this.element)),d(b("\n "))):(d(b('\n <div class="togglebutton">\n <label>')),d(b(this.element)),d(b("</label>\n </div>\n "))),d(b("\n ")),this.description&&(d(b('\n <div class="help-block description">')),d(b(this.description)),d(b("</div>\n "))),d(b("\n </div>\n"))),d(b("\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item_group.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){this.title&&(d(b('\n <h3 class="group-title">')),this.icon&&(d(b('<i class="')),d(b(this.icon)),d(b('"></i> '))),d(b(this.title)),d(b("</h3>\n"))),d(b('\n<div class="form-items"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item_imageselect.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="form-imageselect">\n <ul class="form-imageselect__tabs">\n <li data-pane="select" class="active">')),d(tr("Image Selector")),d(b('</li>\n <li data-pane="url">')),d(tr("Image URL")),d(b('</li>\n </ul>\n <div class="form-imageselect__panes">\n <div class="pane active" rel="select">\n <ul class="form-imageselect__thumbs">\n ')),this.image&&(d(b('\n <li data-original="')),d(this.image.original),d(b('" class="selected"><img src="')),d(this.image.thumb),d(b('" /></li>\n '))),d(b('\n </ul>\n <div class="form-imageselect__loader"><div class="loader-small-inline"></div> <span>')),d(tr("Searching for more images")),d(b('</span></div>\n </div>\n <div class="pane" rel="url">\n ')),this.title&&(d(b('\n <label class="control-label">')),d(b(this.title)),d(b("</label>\n "))),d(b('\n <div class="form-imageselect__url">\n ')),d(b(this.element)),d(b("\n </div>\n ")),this.description&&(d(b('\n <div class="help-block description">')),d(b(this.description)),d(b("</div>\n "))),d(b("\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/card/tpl/card.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e;if(d(b('<div class="card-')),d(this.type),d(b('">\n <div class="artwork">\n <a href="#')),d(this.url),d(b('" class="thumb" title="')),d(helpers.global.stripTags(this.label)),d(b('" style="background-image: url(\'')),d(this.thumbnail),d(b('\')"></a>\n <div class="mdi play" title="')),d(tr("Play")),d(b('"></div>\n ')),("channeltv"===this.type||"channelradio"===this.type)&&d(b('\n <div class="mdi record"></div>\n ')),d(b('\n </div>\n <div class="meta">\n <div class="title"><a href="#')),d(this.url),d(b('" title="')),d(helpers.global.stripTags(this.label)),d(b('">')),d(b(this.label)),d(b("</a></div>\n ")),null!=this.subtitle&&(d(b('\n <div class="subtitle">')),d(b(this.subtitle)),d(b("</div>\n "))),d(b("\n </div>\n ")),this.actions){d(b('\n <ul class="actions">\n ')),c=this.actions;for(a in c)e=c[a],d(b('<li class="mdi ')),d(a),d(b('" title="')),d(e),d(b('"></li>'));d(b("\n </ul>\n "))}d(b("\n ")),this.menu&&d(b('\n <div class="dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu"></ul>\n </div>\n ')),d(b("\n ")),this.progress=null!=this.progress?this.progress:0,d(b('\n <div class="entity-progress"><div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/card/tpl/card_placeholder.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<i></i>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/empty/tpl/empty_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="empty--page">\n ')),this.title&&(d(b('\n <h2 class="empty--page-title">')),d(title),d(b("</h2>\n "))),d(b("\n\n ")),this.content&&(d(b('\n <div class="empty--page-content">')),d(this.content),d(b("</div>\n "))),d(b("\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/empty/tpl/empty_results.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="empty-result">\n <h2>')),d(b(t.sprintf(tr("No %1$s found"),'<span class="empty-key">'+tr("results")+"</span>"))),d(b('</h2>\n <div class="empty-actions">\n <div class="back-link"></div>\n </div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_details_header.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container details-header">\n\n <div class="region-details-side"></div>\n\n <div class="region-details-meta-wrapper"><div class="region-details-meta">\n\n <div class="region-details-title"><span class="title"></span> <span class="sub"></span></div>\n\n <div class="region-details-meta-below">\n <div class="region-details-subtext"></div>\n <div class="description"></div>\n </div>\n\n </div></div>\n\n ')),this.fanart&&(d(b('\n <div class="region-details-fanart" style="background-image: url(\'')),d(this.fanart),d(b('\')"><div class="gradient"></div></div>\n '))),d(b("\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_with_header.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container with-header">\n\n <header class="region-header"></header>\n\n <div class="region-content-wrapper">\n <div class="entity-progress"><div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div></div>\n <section class="region-content"></section>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_with_sidebar_first.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container with-sidebar-first">\n\n <div class="region-first-toggle"></div>\n <section class="region-first">\n <div class="region-first-primary"></div>\n <div class="region-first-secondary"></div>\n </section>\n\n <section class="region-content-wrapper">\n <div class="region-content-top"></div>\n <div class="region-content"></div>\n </section>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/song/tpl/song_placeholder.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<td colspan="6"><i></i></td>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())};;var tr, +}this._hasPushState?b.$(window).on("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!f?b.$(window).on("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),this.fragment=d;var h=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot())return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+"#"+this.fragment),!0;this._hasPushState&&this.atRoot()&&h.hash&&(this.fragment=this.getHash().replace(E,""),this.history.replaceState({},document.title,this.root+this.fragment))}return this.options.silent?void 0:this.loadUrl()},stop:function(){b.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),D.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(a){var b=this.getFragment();return b===this.fragment&&this.iframe&&(b=this.getFragment(this.getHash(this.iframe))),b===this.fragment?!1:(this.iframe&&this.navigate(b),void this.loadUrl())},loadUrl:function(a){return a=this.fragment=this.getFragment(a),c.any(this.handlers,function(b){return b.route.test(a)?(b.callback(a),!0):void 0})},navigate:function(a,b){if(!D.started)return!1;b&&b!==!0||(b={trigger:!!b});var c=this.root+(a=this.getFragment(a||""));if(a=a.replace(I,""),this.fragment!==a){if(this.fragment=a,""===a&&"/"!==c&&(c=c.slice(0,-1)),this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,c);else{if(!this._wantsHashChange)return this.location.assign(c);this._updateHash(this.location,a,b.replace),this.iframe&&a!==this.getFragment(this.getHash(this.iframe))&&(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,a,b.replace))}return b.trigger?this.loadUrl(a):void 0}},_updateHash:function(a,b,c){if(c){var d=a.href.replace(/(javascript:|#).*$/,"");a.replace(d+"#"+b)}else a.hash="#"+b}}),b.history=new D;var J=function(a,b){var d,e=this;d=a&&c.has(a,"constructor")?a.constructor:function(){return e.apply(this,arguments)},c.extend(d,e,b);var f=function(){this.constructor=d};return f.prototype=e.prototype,d.prototype=new f,a&&c.extend(d.prototype,a),d.__super__=e.prototype,d};m.extend=o.extend=y.extend=t.extend=D.extend=J;var K=function(){throw new Error('A "url" property or function must be specified')},L=function(a,b){var c=b.error;b.error=function(d){c&&c(a,d,b),a.trigger("error",a,d,b)}};return b}),"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(a){return 10>a?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g,h=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,g=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;f>c;c+=1)g[c]=str(c,i)||"null";return e=0===g.length?"[]":gap?"[\n"+gap+g.join(",\n"+gap)+"\n"+h+"]":"["+g.join(",")+"]",gap=h,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;f>c;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));return e=0===g.length?"{}":gap?"{\n"+gap+g.join(",\n"+gap)+"\n"+h+"}":"{"+g.join(",")+"}",gap=h,e}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;c>d;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();var saveAs=saveAs||function(a){"use strict";if(!("undefined"==typeof a||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=b.createElementNS("http://www.w3.org/1999/xhtml","a"),e="download"in d,f=function(a){var b=new MouseEvent("click");a.dispatchEvent(b)},g=/constructor/i.test(a.HTMLElement)||a.safari,h=/CriOS\/[\d]+/.test(navigator.userAgent),i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=4e4,l=function(a){var b=function(){"string"==typeof a?c().revokeObjectURL(a):a.remove()};setTimeout(b,k)},m=function(a,b,c){b=[].concat(b);for(var d=b.length;d--;){var e=a["on"+b[d]];if("function"==typeof e)try{e.call(a,c||a)}catch(f){i(f)}}},n=function(a){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob([String.fromCharCode(65279),a],{type:a.type}):a},o=function(b,i,k){k||(b=n(b));var o,p=this,q=b.type,r=q===j,s=function(){m(p,"writestart progress write writeend".split(" "))},t=function(){if((h||r&&g)&&a.FileReader){var d=new FileReader;return d.onloadend=function(){var b=h?d.result:d.result.replace(/^data:[^;]*;/,"data:attachment/file;"),c=a.open(b,"_blank");c||(a.location.href=b),b=void 0,p.readyState=p.DONE,s()},d.readAsDataURL(b),void(p.readyState=p.INIT)}if(o||(o=c().createObjectURL(b)),r)a.location.href=o;else{var e=a.open(o,"_blank");e||(a.location.href=o)}p.readyState=p.DONE,s(),l(o)};return p.readyState=p.INIT,e?(o=c().createObjectURL(b),void setTimeout(function(){d.href=o,d.download=i,f(d),s(),l(o),p.readyState=p.DONE})):void t()},p=o.prototype,q=function(a,b,c){return new o(a,b||a.name||"download",c)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(a,b,c){return b=b||a.name||"download",c||(a=n(a)),navigator.msSaveOrOpenBlob(a,b)}:(p.abort=function(){},p.readyState=p.INIT=0,p.WRITING=1,p.DONE=2,p.error=p.onwritestart=p.onprogress=p.onwrite=p.onabort=p.onerror=p.onwriteend=null,q)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define("FileSaver.js",function(){return saveAs}),function(a,b){if("object"==typeof exports)module.exports=b(require("underscore"),require("backbone"));else if("function"==typeof define&&define.amd)define(["underscore","backbone"],b);else{for(var c="FilteredCollection",d=c.split("."),e=a,f=0;f<d.length-1;f++)void 0===e[d[f]]&&(e[d[f]]={}),e=e[d[f]];e[d[d.length-1]]=b(a._,a.Backbone)}}(this,function(a,b){function c(c){return{underscore:a,backbone:b}[c]}var d=function(a){function b(a){var c=b.cache[a];if(!c){var d={};c=b.cache[a]={id:a,exports:d},b.modules[a].call(d,c,d)}return c.exports}return b.cache=[],b.modules=[function(a,d){function e(){this._filterResultCache={}}function f(a){for(var b in this._filterResultCache)this._filterResultCache.hasOwnProperty(b)&&delete this._filterResultCache[b][a]}function g(a,b){this._filters[a]&&f.call(this,a),this._filters[a]=b,this.trigger("filtered:add",a)}function h(a){delete this._filters[a],f.call(this,a),this.trigger("filtered:remove",a)}function i(a){this._filterResultCache[a.cid]||(this._filterResultCache[a.cid]={});var b=this._filterResultCache[a.cid];for(var c in this._filters)if(this._filters.hasOwnProperty(c)&&(b.hasOwnProperty(c)||(b[c]=this._filters[c].fn(a)),!b[c]))return!1;return!0}function j(){var a=[];this._superset&&(a=this._superset.filter(p.bind(i,this))),this._collection.reset(a),this.length=this._collection.length}function k(a){if(this._filterResultCache[a.cid]={},i.call(this,a)){if(!this._collection.get(a.cid)){for(var b=this.superset().indexOf(a),c=null,d=b-1;d>=0;d-=1)if(this.contains(this.superset().at(d))){c=this.indexOf(this.superset().at(d))+1;break}c=c||0,this._collection.add(a,{at:c})}}else this._collection.get(a.cid)&&this._collection.remove(a);this.length=this._collection.length}function l(a){this._filterResultCache[a.cid]={},i.call(this,a)||this._collection.get(a.cid)&&this._collection.remove(a)}function m(a,b,c){"change:"===a.slice(0,7)&&l.call(this,arguments[1])}function n(a){this.contains(a)&&this._collection.remove(a),this.length=this._collection.length}function o(a){this._superset=a,this._collection=new q.Collection(a.toArray()),r(this._collection,this),this.resetFilters(),this.listenTo(this._superset,"reset sort",j),this.listenTo(this._superset,"add change",k),this.listenTo(this._superset,"remove",n),this.listenTo(this._superset,"all",m)}var p=c("underscore"),q=c("backbone"),r=b(1),s=b(2),t={defaultFilterName:"__default",filterBy:function(a,b){return b||(b=a,a=this.defaultFilterName),g.call(this,a,s(b)),j.call(this),this},removeFilter:function(a){return a||(a=this.defaultFilterName),h.call(this,a),j.call(this),this},resetFilters:function(){return this._filters={},e.call(this),this.trigger("filtered:reset"),j.call(this),this},superset:function(){return this._superset},refilter:function(a){return"object"==typeof a&&a.cid?k.call(this,a):(e.call(this),j.call(this)),this},getFilters:function(){return p.keys(this._filters)},hasFilter:function(a){return p.contains(this.getFilters(),a)},destroy:function(){this.stopListening(),this._collection.reset([]),this._superset=this._collection,this.length=0,this.trigger("filtered:destroy")}};p.extend(o.prototype,t,q.Events),a.exports=o},function(a,b){function d(a,b){function c(){b.length=a.length}function d(c){var d=e.toArray(arguments),f="change"===c||"change:"===c.slice(0,7);"reset"===c&&(b.models=a.models),e.contains(h,c)?(e.contains(["add","remove","destroy"],c)?d[2]=b:e.contains(["reset","sort"],c)&&(d[1]=b),b.trigger.apply(this,d)):f&&b.contains(d[1])&&b.trigger.apply(this,d)}var i={};return e.each(e.functions(f.Collection.prototype),function(b){e.contains(g,b)||(i[b]=function(){return a[b].apply(a,arguments)})}),e.extend(b,f.Events,i),b.listenTo(a,"all",c),b.listenTo(a,"all",d),b.models=a.models,c(),b}var e=c("underscore"),f=c("backbone"),g=["_onModelEvent","_prepareModel","_removeReference","_reset","add","initialize","sync","remove","reset","set","push","pop","unshift","shift","sort","parse","fetch","create","model","off","on","listenTo","listenToOnce","bind","trigger","once","stopListening"],h=["add","remove","reset","sort","destroy","sync","request","error"];a.exports=d},function(a,b){function d(a,b){return function(c){return c.get(a)===b}}function e(a,b){return function(c){return b(c.get(a))}}function f(a,b){return i.isArray(b)||(b=null),{fn:a,keys:b}}function g(a){var b=i.keys(a),c=i.map(b,function(b){var c=a[b];return i.isFunction(c)?e(b,c):d(b,c)}),g=function(a){for(var b=0;b<c.length;b++)if(!c[b](a))return!1;return!0};return f(g,b)}function h(a,b){return i.isFunction(a)?f(a,b):i.isObject(a)?g(a):void 0}var i=c("underscore");a.exports=h}],b(0)}();return d}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.ChildViewContainer;return a.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;return this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength(),this},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;return a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength(),this},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck","reduce"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(a,b),a.ChildViewContainer.VERSION="0.1.6",a.ChildViewContainer.noConflict=function(){return a.ChildViewContainer=c,this},a.ChildViewContainer}),function(a,b){"function"==typeof define&&define.amd?define(["underscore","backbone","jquery"],function(c,d,e){return a.Backbone=b(c,d,e)}):"undefined"!=typeof exports&&"undefined"!=typeof require?module.exports=b(require("underscore"),require("backbone"),require("jquery")):a.Backbone=b(a._,a.Backbone,a.jQuery)}(this,function(a,b,c){function d(b,d){if(b&&a.isObject(b)){if(a.isFunction(b.getCacheKey))return b.getCacheKey(d);b=d&&d.url?d.url:a.isFunction(b.url)?b.url():b.url}else if(a.isFunction(b))return b(d);return d&&d.data?"string"==typeof d.data?b+"?"+d.data:b+"?"+c.param(d.data):b}function e(a,c,d){c=c||{};var e=b.fetchCache.getCacheKey(a,c),f=!1,g=c.lastSync||(new Date).getTime(),h=!1;e&&c.cache!==!1&&(c.cache||c.prefill)&&(c.expires!==!1&&(f=(new Date).getTime()+1e3*(c.expires||300)),c.prefillExpires!==!1&&(h=(new Date).getTime()+1e3*(c.prefillExpires||300)),b.fetchCache._cache[e]={expires:f,lastSync:g,prefillExpires:h,value:d},b.fetchCache.setLocalStorage())}function f(c,e){return a.isFunction(c)?c=c():c&&a.isObject(c)&&(c=d(c,e)),b.fetchCache._cache[c]}function g(a,b){return f(a).lastSync}function h(c,e){a.isFunction(c)?c=c():c&&a.isObject(c)&&(c=d(c,e)),delete b.fetchCache._cache[c],b.fetchCache.setLocalStorage()}function i(){b.fetchCache._cache={}}function j(){if(n&&b.fetchCache.localStorage)try{localStorage.setItem(b.fetchCache.getLocalStorageKey(),JSON.stringify(b.fetchCache._cache))}catch(a){var c=a.code||a.number||a.message;if(22!==c&&1014!==c)throw a;this._deleteCacheWithPriority()}}function k(){if(n&&b.fetchCache.localStorage){var a=localStorage.getItem(b.fetchCache.getLocalStorageKey())||"{}";b.fetchCache._cache=JSON.parse(a)}}function l(a){return window.setTimeout(a,0)}var m={modelFetch:b.Model.prototype.fetch,modelSync:b.Model.prototype.sync,collectionFetch:b.Collection.prototype.fetch},n=function(){var a="undefined"!=typeof window.localStorage;if(a)try{localStorage.setItem("test_support","test_support"),localStorage.removeItem("test_support")}catch(b){a=!1}return a}();return b.fetchCache=b.fetchCache||{},b.fetchCache._cache=b.fetchCache._cache||{},b.fetchCache.enabled=!0,b.fetchCache.priorityFn=function(a,b){return a&&a.expires&&b&&b.expires?a.expires-b.expires:a},b.fetchCache._prioritize=function(){var b=a.values(this._cache).sort(this.priorityFn),c=a.indexOf(a.values(this._cache),b[0]);return a.keys(this._cache)[c]},b.fetchCache._deleteCacheWithPriority=function(){b.fetchCache._cache[this._prioritize()]=null,delete b.fetchCache._cache[this._prioritize()],b.fetchCache.setLocalStorage()},b.fetchCache.getLocalStorageKey=function(){return"backboneCache"},"undefined"==typeof b.fetchCache.localStorage&&(b.fetchCache.localStorage=!0),b.Model.prototype.fetch=function(d){function e(){return d.prefill&&(!d.prefillExpires||k)}function g(){d.parse&&(n=q.parse(n,d)),q.set(n,d),a.isFunction(d.prefillSuccess)&&d.prefillSuccess.call(p,q,n,d),q.trigger("cachesync",q,n,d),q.trigger("sync",q,n,d),e()?o.notifyWith(p,[q]):(a.isFunction(d.success)&&d.success.call(p,q,n,d),o.resolveWith(p,[q]))}if(!b.fetchCache.enabled)return m.modelFetch.apply(this,arguments);d=a.defaults(d||{},{parse:!0});var h=b.fetchCache.getCacheKey(this,d),i=f(h),j=!1,k=!1,n=!1,o=new c.Deferred,p=d.context||this,q=this;if(i&&(j=i.expires,j=j&&i.expires<(new Date).getTime(),k=i.prefillExpires,k=k&&i.prefillExpires<(new Date).getTime(),n=i.value),!j&&(d.cache||d.prefill)&&n&&(null==d.async&&(d.async=!0),d.async?l(g):g(),!e()))return o.promise();var r=m.modelFetch.apply(this,arguments);return"undefined"!=typeof r&&(r.done(a.bind(o.resolve,p,this)).done(a.bind(b.fetchCache.setCache,null,this,d)).fail(a.bind(o.reject,p,this)),o.abort=r.abort),o.promise()},b.Model.prototype.sync=function(a,c,d){if("read"===a||!b.fetchCache.enabled)return m.modelSync.apply(this,arguments);var e,f,g=c.collection,i=[];for(i.push(b.fetchCache.getCacheKey(c,d)),g&&i.push(b.fetchCache.getCacheKey(g)),e=0,f=i.length;f>e;e++)h(i[e]);return m.modelSync.apply(this,arguments)},b.Collection.prototype.fetch=function(d){function e(){return d.prefill&&(!d.prefillExpires||k)}function g(){q[d.reset?"reset":"set"](n,d),a.isFunction(d.prefillSuccess)&&d.prefillSuccess.call(p,q),q.trigger("cachesync",q,n,d),q.trigger("sync",q,n,d),e()?o.notifyWith(p,[q]):(a.isFunction(d.success)&&d.success.call(p,q,n,d),o.resolveWith(p,[q]))}if(!b.fetchCache.enabled)return m.collectionFetch.apply(this,arguments);d=a.defaults(d||{},{parse:!0});var h=b.fetchCache.getCacheKey(this,d),i=f(h),j=!1,k=!1,n=!1,o=new c.Deferred,p=d.context||this,q=this;if(i&&(j=i.expires,j=j&&i.expires<(new Date).getTime(),k=i.prefillExpires,k=k&&i.prefillExpires<(new Date).getTime(),n=i.value),!j&&(d.cache||d.prefill)&&n&&(null==d.async&&(d.async=!0),d.async?l(g):g(),!e()))return o.promise();var r=m.collectionFetch.apply(this,arguments);return"undefined"!=typeof r&&(r.done(a.bind(o.resolve,p,this)).done(a.bind(b.fetchCache.setCache,null,this,d)).fail(a.bind(o.reject,p,this)),o.abort=r.abort),o.promise()},k(),b.fetchCache._superMethods=m,b.fetchCache.setCache=e,b.fetchCache.getCache=f,b.fetchCache.getCacheKey=d,b.fetchCache.getLastSync=g,b.fetchCache.clearItem=h,b.fetchCache.reset=i,b.fetchCache.setLocalStorage=j,b.fetchCache.getLocalStorage=k,b}),function(a,b){"object"==typeof exports&&"function"==typeof require?module.exports=b(require("backbone")):"function"==typeof define&&define.amd?define(["backbone"],function(c){return b(c||a.Backbone)}):b(Backbone)}(this,function(a){function b(){return(65536*(1+Math.random())|0).toString(16).substring(1)}function c(){return b()+b()+"-"+b()+"-"+b()+"-"+b()+"-"+b()+b()+b()}function d(a){return a===Object(a)}function e(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1}function f(a,b){for(var c in b)a[c]=b[c];return a}function g(a,b){if(null==a)return void 0;var c=a[b];return"function"==typeof c?a[b]():c}return a.LocalStorage=window.Store=function(a,b){if(!this.localStorage)throw"Backbone.localStorage: Environment does not support localStorage.";this.name=a,this.serializer=b||{serialize:function(a){return d(a)?JSON.stringify(a):a},deserialize:function(a){return a&&JSON.parse(a)}};var c=this.localStorage().getItem(this.name);this.records=c&&c.split(",")||[]},f(a.LocalStorage.prototype,{save:function(){this.localStorage().setItem(this.name,this.records.join(","))},create:function(a){return a.id||0===a.id||(a.id=c(),a.set(a.idAttribute,a.id)),this.localStorage().setItem(this._itemName(a.id),this.serializer.serialize(a)),this.records.push(a.id.toString()),this.save(),this.find(a)},update:function(a){this.localStorage().setItem(this._itemName(a.id),this.serializer.serialize(a));var b=a.id.toString();return e(this.records,b)||(this.records.push(b),this.save()),this.find(a)},find:function(a){return this.serializer.deserialize(this.localStorage().getItem(this._itemName(a.id)))},findAll:function(){for(var a,b,c=[],d=0;d<this.records.length;d++)a=this.records[d],b=this.serializer.deserialize(this.localStorage().getItem(this._itemName(a))),null!=b&&c.push(b);return c},destroy:function(a){this.localStorage().removeItem(this._itemName(a.id));for(var b=a.id.toString(),c=0;c<this.records.length;c++)this.records[c]===b&&this.records.splice(c,1);return this.save(),a},localStorage:function(){return localStorage},_clear:function(){var a=this.localStorage(),b=new RegExp("^"+this.name+"-");a.removeItem(this.name);for(var c in a)b.test(c)&&a.removeItem(c);this.records.length=0},_storageSize:function(){return this.localStorage().length},_itemName:function(a){return this.name+"-"+a}}),a.LocalStorage.sync=window.Store.sync=a.localSync=function(b,c,d){var e,f,h=g(c,"localStorage")||g(c.collection,"localStorage"),i=a.$?a.$.Deferred&&a.$.Deferred():a.Deferred&&a.Deferred();try{switch(b){case"read":e=void 0!=c.id?h.find(c):h.findAll();break;case"create":e=h.create(c);break;case"update":e=h.update(c);break;case"delete":e=h.destroy(c)}}catch(j){f=22===j.code&&0===h._storageSize()?"Private browsing is unsupported":j.message}return e?(d&&d.success&&("0.9.10"===a.VERSION?d.success(c,e,d):d.success(e)),i&&i.resolve(e)):(f=f?f:"Record Not Found",d&&d.error&&("0.9.10"===a.VERSION?d.error(c,f,d):d.error(f)),i&&i.reject(f)),d&&d.complete&&d.complete(e),i&&i.promise()},a.ajaxSync=a.sync,a.getSyncMethod=function(b,c){var d=c&&c.ajaxSync;return d||!g(b,"localStorage")&&!g(b.collection,"localStorage")?a.ajaxSync:a.localSync},a.sync=function(b,c,d){return a.getSyncMethod(c,d).apply(this,[b,c,d])},a.LocalStorage}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(c,d){return a.Marionette=a.Mn=b(a,c,d)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(a,c,d)}else a.Marionette=a.Mn=b(a,a.Backbone,a._)}(this,function(a,b,c){"use strict";!function(a,b){var c=a.ChildViewContainer;return a.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;return this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength(),this},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;return a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength(),this},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(a,b),a.ChildViewContainer.VERSION="0.1.5",a.ChildViewContainer.noConflict=function(){return a.ChildViewContainer=c,this},a.ChildViewContainer}(b,c),function(a,b){var c=a.Wreqr,d=a.Wreqr={};return a.Wreqr.VERSION="1.3.1",a.Wreqr.noConflict=function(){return a.Wreqr=c,this},d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this)},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(b)return function(){var a=Array.prototype.slice.apply(arguments);return b.callback.apply(b.context,a)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,b),d.CommandStorage=function(){var c=function(a){this.options=a,this._commands={},b.isFunction(this.initialize)&&this.initialize(a)};return b.extend(c.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),c}(),d.Commands=function(a){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this);var c=Array.prototype.slice.call(arguments);a.Handlers.prototype.constructor.apply(this,c)},execute:function(a,b){a=arguments[0],b=Array.prototype.slice.call(arguments,1),this.hasHandler(a)?this.getHandler(a).apply(this,b):this.storage.addCommand(a,b)},_executeCommands:function(a,c,d){var e=this.storage.getCommands(a);b.each(e.instances,function(a){c.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var c,d=a.storageType||this.storageType;c=b.isFunction(d)?new d:d,this.storage=c}})}(d),d.RequestResponse=function(a){return a.Handlers.extend({request:function(){var a=arguments[0],b=Array.prototype.slice.call(arguments,1);return this.hasHandler(a)?this.getHandler(a).apply(this,b):void 0}})}(d),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,b),d.Channel=function(c){var d=function(b){this.vent=new a.Wreqr.EventAggregator,this.reqres=new a.Wreqr.RequestResponse,this.commands=new a.Wreqr.Commands,this.channelName=b};return b.extend(d.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(a,b){return this._connect("vent",a,b),this},connectCommands:function(a,b){return this._connect("commands",a,b),this},connectRequests:function(a,b){return this._connect("reqres",a,b),this},_connect:function(a,c,d){if(c){d=d||this;var e="vent"===a?"on":"setHandler";b.each(c,function(c,f){this[a][e](f,b.bind(c,d))},this)}}}),d}(d),d.radio=function(a){var c=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};b.extend(c.prototype,{channel:function(a){if(!a)throw new Error("Channel must receive a name");return this._getChannel(a)},_getChannel:function(b){var c=this._channels[b];return c||(c=new a.Channel(b),this._channels[b]=c),c},_proxyMethods:function(){b.each(["vent","commands","reqres"],function(a){b.each(d[a],function(b){this[a][b]=e(this,a,b)},this)},this)}});var d={vent:["on","off","trigger","once","stopListening","listenTo","listenToOnce"],commands:["execute","setHandler","setHandlers","removeHandler","removeAllHandlers"],reqres:["request","setHandler","setHandlers","removeHandler","removeAllHandlers"]},e=function(a,b,c){return function(d){var e=a._getChannel(d)[b],f=Array.prototype.slice.call(arguments,1);return e[c].apply(e,f)}};return new c}(d),a.Wreqr}(b,c);var d=a.Marionette,e=b.Marionette={};e.VERSION="2.3.1",e.noConflict=function(){return a.Marionette=d,this},b.Marionette=e,e.Deferred=b.$.Deferred,e.extend=b.Model.extend,e.isNodeAttached=function(a){return b.$.contains(document.documentElement,a)},e.getOption=function(a,b){return a&&b?a.options&&void 0!==a.options[b]?a.options[b]:a[b]:void 0},e.proxyGetOption=function(a){return e.getOption(this,a)},e._getValue=function(a,b,d){return c.isFunction(a)&&(a=a.apply(b,d)),a},e.normalizeMethods=function(a){return c.reduce(a,function(a,b,d){return c.isFunction(b)||(b=this[b]),b&&(a[d]=b),a},{},this)},e.normalizeUIString=function(a,b){return a.replace(/@ui\.[a-zA-Z_$0-9]*/g,function(a){return b[a.slice(4)]})},e.normalizeUIKeys=function(a,b){return c.reduce(a,function(a,c,d){var f=e.normalizeUIString(d,b);return a[f]=c,a},{})},e.normalizeUIValues=function(a,b){return c.each(a,function(d,f){c.isString(d)&&(a[f]=e.normalizeUIString(d,b))}),a},e.actAsCollection=function(a,b){var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];c.each(d,function(d){a[d]=function(){var a=c.values(c.result(this,b)),e=[a].concat(c.toArray(arguments));return c[d].apply(c,e)}})};var f=e.deprecate=function(a,b){c.isObject(a)&&(a=a.prev+" is going to be removed in the future. Please use "+a.next+" instead."+(a.url?" See: "+a.url:"")),void 0!==b&&b||f._cache[a]||(f._warn("Deprecation warning: "+a),f._cache[a]=!0)};f._warn="undefined"!=typeof console&&(console.warn||console.log)||function(){},f._cache={},e._triggerMethod=function(){function a(a,b,c){return c.toUpperCase()}var b=/(^|:)(\w)/gi;return function(d,e,f){var g=arguments.length<3;g&&(f=e,e=f[0]);var h,i="on"+e.replace(b,a),j=d[i];return c.isFunction(j)&&(h=j.apply(d,g?c.rest(f):f)),c.isFunction(d.trigger)&&(g+f.length>1?d.trigger.apply(d,g?f:[e].concat(c.rest(f,0))):d.trigger(e)),h}}(),e.triggerMethod=function(a){return e._triggerMethod(this,arguments)},e.triggerMethodOn=function(a){var b=c.isFunction(a.triggerMethod)?a.triggerMethod:e.triggerMethod;return b.apply(a,c.rest(arguments))},e.MonitorDOMRefresh=function(a){function b(){a._isShown=!0,f()}function d(){a._isRendered=!0,f()}function f(){a._isShown&&a._isRendered&&e.isNodeAttached(a.el)&&c.isFunction(a.triggerMethod)&&a.triggerMethod("dom:refresh")}a.on({show:b,render:d})},function(a){function b(b,d,e,f){var g=f.split(/\s+/);c.each(g,function(c){var f=b[c];if(!f)throw new a.Error('Method "'+c+'" was configured as an event handler, but does not exist.');b.listenTo(d,e,f)})}function d(a,b,c,d){a.listenTo(b,c,d)}function e(a,b,d,e){var f=e.split(/\s+/);c.each(f,function(c){var e=a[c];a.stopListening(b,d,e)})}function f(a,b,c,d){a.stopListening(b,c,d)}function g(b,d,e,f,g){if(d&&e){if(!c.isObject(e))throw new a.Error({message:"Bindings must be an object or function.",url:"marionette.functions.html#marionettebindentityevents"});e=a._getValue(e,b),c.each(e,function(a,e){c.isFunction(a)?f(b,d,e,a):g(b,d,e,a)})}}a.bindEntityEvents=function(a,c,e){g(a,c,e,d,b)},a.unbindEntityEvents=function(a,b,c){g(a,b,c,f,e)},a.proxyBindEntityEvents=function(b,c){return a.bindEntityEvents(this,b,c)},a.proxyUnbindEntityEvents=function(b,c){ +return a.unbindEntityEvents(this,b,c)}}(e);var g=["description","fileName","lineNumber","name","message","number"];return e.Error=e.extend.call(Error,{urlRoot:"http://marionettejs.com/docs/v"+e.VERSION+"/",constructor:function(a,b){c.isObject(a)?(b=a,a=b.message):b||(b={});var d=Error.call(this,a);c.extend(this,c.pick(d,g),c.pick(b,g)),this.captureStackTrace(),b.url&&(this.url=this.urlRoot+b.url)},captureStackTrace:function(){Error.captureStackTrace&&Error.captureStackTrace(this,e.Error)},toString:function(){return this.name+": "+this.message+(this.url?" See: "+this.url:"")}}),e.Error.extend=e.extend,e.Callbacks=function(){this._deferred=e.Deferred(),this._callbacks=[]},c.extend(e.Callbacks.prototype,{add:function(a,b){var d=c.result(this._deferred,"promise");this._callbacks.push({cb:a,ctx:b}),d.then(function(c){b&&(c.context=b),a.call(c.context,c.options)})},run:function(a,b){this._deferred.resolve({options:a,context:b})},reset:function(){var a=this._callbacks;this._deferred=e.Deferred(),this._callbacks=[],c.each(a,function(a){this.add(a.cb,a.ctx)},this)}}),e.Controller=function(a){this.options=a||{},c.isFunction(this.initialize)&&this.initialize(this.options)},e.Controller.extend=e.extend,c.extend(e.Controller.prototype,b.Events,{destroy:function(){return e._triggerMethod(this,"before:destroy",arguments),e._triggerMethod(this,"destroy",arguments),this.stopListening(),this.off(),this},triggerMethod:e.triggerMethod,getOption:e.proxyGetOption}),e.Object=function(a){this.options=c.extend({},c.result(this,"options"),a),this.initialize.apply(this,arguments)},e.Object.extend=e.extend,c.extend(e.Object.prototype,b.Events,{initialize:function(){},destroy:function(){this.triggerMethod("before:destroy"),this.triggerMethod("destroy"),this.stopListening()},triggerMethod:e.triggerMethod,getOption:e.proxyGetOption,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.Region=e.Object.extend({constructor:function(a){if(this.options=a||{},this.el=this.getOption("el"),this.el=this.el instanceof b.$?this.el[0]:this.el,!this.el)throw new e.Error({name:"NoElError",message:'An "el" must be specified for a region.'});this.$el=this.getEl(this.el),e.Object.call(this,a)},show:function(a,b){if(this._ensureElement()){this._ensureViewIsIntact(a);var c=b||{},d=a!==this.currentView,f=!!c.preventDestroy,g=!!c.forceShow,h=!!this.currentView,i=d&&!f,j=d||g;if(h&&this.triggerMethod("before:swapOut",this.currentView,this,b),this.currentView&&delete this.currentView._parent,i?this.empty():h&&j&&this.currentView.off("destroy",this.empty,this),j){a.once("destroy",this.empty,this),a.render(),a._parent=this,h&&this.triggerMethod("before:swap",a,this,b),this.triggerMethod("before:show",a,this,b),e.triggerMethodOn(a,"before:show",a,this,b),h&&this.triggerMethod("swapOut",this.currentView,this,b);var k=e.isNodeAttached(this.el),l=[],m=c.triggerBeforeAttach||this.triggerBeforeAttach,n=c.triggerAttach||this.triggerAttach;return k&&m&&(l=this._displayedViews(a),this._triggerAttach(l,"before:")),this.attachHtml(a),this.currentView=a,k&&n&&(l=this._displayedViews(a),this._triggerAttach(l)),h&&this.triggerMethod("swap",a,this,b),this.triggerMethod("show",a,this,b),e.triggerMethodOn(a,"show",a,this,b),this}return this}},triggerBeforeAttach:!0,triggerAttach:!0,_triggerAttach:function(a,b){var d=(b||"")+"attach";c.each(a,function(a){e.triggerMethodOn(a,d,a,this)},this)},_displayedViews:function(a){return c.union([a],c.result(a,"_getNestedViews")||[])},_ensureElement:function(){if(c.isObject(this.el)||(this.$el=this.getEl(this.el),this.el=this.$el[0]),!this.$el||0===this.$el.length){if(this.getOption("allowMissingEl"))return!1;throw new e.Error('An "el" '+this.$el.selector+" must exist in DOM")}return!0},_ensureViewIsIntact:function(a){if(!a)throw new e.Error({name:"ViewNotValid",message:"The view passed is undefined and therefore invalid. You must pass a view instance to show."});if(a.isDestroyed)throw new e.Error({name:"ViewDestroyedError",message:'View (cid: "'+a.cid+'") has already been destroyed and cannot be used.'})},getEl:function(a){return b.$(a,e._getValue(this.options.parentEl,this))},attachHtml:function(a){this.$el.contents().detach(),this.el.appendChild(a.el)},empty:function(){var a=this.currentView;if(a)return a.off("destroy",this.empty,this),this.triggerMethod("before:empty",a),this._destroyView(),this.triggerMethod("empty",a),delete this.currentView,this},_destroyView:function(){var a=this.currentView;a.destroy&&!a.isDestroyed?a.destroy():a.remove&&(a.remove(),a.isDestroyed=!0)},attachView:function(a){return this.currentView=a,this},hasView:function(){return!!this.currentView},reset:function(){return this.empty(),this.$el&&(this.el=this.$el.selector),delete this.$el,this}},{buildRegion:function(a,b){if(c.isString(a))return this._buildRegionFromSelector(a,b);if(a.selector||a.el||a.regionClass)return this._buildRegionFromObject(a,b);if(c.isFunction(a))return this._buildRegionFromRegionClass(a);throw new e.Error({message:"Improper region configuration type.",url:"marionette.region.html#region-configuration-types"})},_buildRegionFromSelector:function(a,b){return new b({el:a})},_buildRegionFromObject:function(a,b){var d=a.regionClass||b,e=c.omit(a,"selector","regionClass");return a.selector&&!e.el&&(e.el=a.selector),new d(e)},_buildRegionFromRegionClass:function(a){return new a}}),e.RegionManager=e.Controller.extend({constructor:function(a){this._regions={},e.Controller.call(this,a),this.addRegions(this.getOption("regions"))},addRegions:function(a,b){return a=e._getValue(a,this,arguments),c.reduce(a,function(a,d,e){return c.isString(d)&&(d={selector:d}),d.selector&&(d=c.defaults({},d,b)),a[e]=this.addRegion(e,d),a},{},this)},addRegion:function(a,b){var c;return c=b instanceof e.Region?b:e.Region.buildRegion(b,e.Region),this.triggerMethod("before:add:region",a,c),c._parent=this,this._store(a,c),this.triggerMethod("add:region",a,c),c},get:function(a){return this._regions[a]},getRegions:function(){return c.clone(this._regions)},removeRegion:function(a){var b=this._regions[a];return this._remove(a,b),b},removeRegions:function(){var a=this.getRegions();return c.each(this._regions,function(a,b){this._remove(b,a)},this),a},emptyRegions:function(){var a=this.getRegions();return c.invoke(a,"empty"),a},destroy:function(){return this.removeRegions(),e.Controller.prototype.destroy.apply(this,arguments)},_store:function(a,b){this._regions[a]=b,this._setLength()},_remove:function(a,b){this.triggerMethod("before:remove:region",a,b),b.empty(),b.stopListening(),delete b._parent,delete this._regions[a],this._setLength(),this.triggerMethod("remove:region",a,b)},_setLength:function(){this.length=c.size(this._regions)}}),e.actAsCollection(e.RegionManager.prototype,"_regions"),e.TemplateCache=function(a){this.templateId=a},c.extend(e.TemplateCache,{templateCaches:{},get:function(a){var b=this.templateCaches[a];return b||(b=new e.TemplateCache(a),this.templateCaches[a]=b),b.load()},clear:function(){var a,b=c.toArray(arguments),d=b.length;if(d>0)for(a=0;d>a;a++)delete this.templateCaches[b[a]];else this.templateCaches={}}}),c.extend(e.TemplateCache.prototype,{load:function(){if(this.compiledTemplate)return this.compiledTemplate;var a=this.loadTemplate(this.templateId);return this.compiledTemplate=this.compileTemplate(a),this.compiledTemplate},loadTemplate:function(a){var c=b.$(a).html();if(!c||0===c.length)throw new e.Error({name:"NoTemplateError",message:'Could not find template: "'+a+'"'});return c},compileTemplate:function(a){return c.template(a)}}),e.Renderer={render:function(a,b){if(!a)throw new e.Error({name:"TemplateNotFoundError",message:"Cannot render the template since its false, null or undefined."});var d=c.isFunction(a)?a:e.TemplateCache.get(a);return d(b)}},e.View=b.View.extend({isDestroyed:!1,constructor:function(a){c.bindAll(this,"render"),a=e._getValue(a,this),this.options=c.extend({},c.result(this,"options"),a),this._behaviors=e.Behaviors(this),b.View.apply(this,arguments),e.MonitorDOMRefresh(this),this.on("show",this.onShowCalled)},getTemplate:function(){return this.getOption("template")},serializeModel:function(a){return a.toJSON.apply(a,c.rest(arguments))},mixinTemplateHelpers:function(a){a=a||{};var b=this.getOption("templateHelpers");return b=e._getValue(b,this),c.extend(a,b)},normalizeUIKeys:function(a){var b=c.result(this,"_uiBindings");return e.normalizeUIKeys(a,b||c.result(this,"ui"))},normalizeUIValues:function(a){var b=c.result(this,"ui"),d=c.result(this,"_uiBindings");return e.normalizeUIValues(a,d||b)},configureTriggers:function(){if(this.triggers){var a=this.normalizeUIKeys(c.result(this,"triggers"));return c.reduce(a,function(a,b,c){return a[c]=this._buildViewTrigger(b),a},{},this)}},delegateEvents:function(a){return this._delegateDOMEvents(a),this.bindEntityEvents(this.model,this.getOption("modelEvents")),this.bindEntityEvents(this.collection,this.getOption("collectionEvents")),c.each(this._behaviors,function(a){a.bindEntityEvents(this.model,a.getOption("modelEvents")),a.bindEntityEvents(this.collection,a.getOption("collectionEvents"))},this),this},_delegateDOMEvents:function(a){var d=e._getValue(a||this.events,this);d=this.normalizeUIKeys(d),c.isUndefined(a)&&(this.events=d);var f={},g=c.result(this,"behaviorEvents")||{},h=this.configureTriggers(),i=c.result(this,"behaviorTriggers")||{};c.extend(f,g,d,h,i),b.View.prototype.delegateEvents.call(this,f)},undelegateEvents:function(){return b.View.prototype.undelegateEvents.apply(this,arguments),this.unbindEntityEvents(this.model,this.getOption("modelEvents")),this.unbindEntityEvents(this.collection,this.getOption("collectionEvents")),c.each(this._behaviors,function(a){a.unbindEntityEvents(this.model,a.getOption("modelEvents")),a.unbindEntityEvents(this.collection,a.getOption("collectionEvents"))},this),this},onShowCalled:function(){},_ensureViewIsIntact:function(){if(this.isDestroyed)throw new e.Error({name:"ViewDestroyedError",message:'View (cid: "'+this.cid+'") has already been destroyed and cannot be used.'})},destroy:function(){if(!this.isDestroyed){var a=c.toArray(arguments);return this.triggerMethod.apply(this,["before:destroy"].concat(a)),this.isDestroyed=!0,this.triggerMethod.apply(this,["destroy"].concat(a)),this.unbindUIElements(),this.remove(),c.invoke(this._behaviors,"destroy",a),this}},bindUIElements:function(){this._bindUIElements(),c.invoke(this._behaviors,this._bindUIElements)},_bindUIElements:function(){if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var a=c.result(this,"_uiBindings");this.ui={},c.each(a,function(a,b){this.ui[b]=this.$(a)},this)}},unbindUIElements:function(){this._unbindUIElements(),c.invoke(this._behaviors,this._unbindUIElements)},_unbindUIElements:function(){this.ui&&this._uiBindings&&(c.each(this.ui,function(a,b){delete this.ui[b]},this),this.ui=this._uiBindings,delete this._uiBindings)},_buildViewTrigger:function(a){var b=c.isObject(a),d=c.defaults({},b?a:{},{preventDefault:!0,stopPropagation:!0}),e=b?d.event:a;return function(a){a&&(a.preventDefault&&d.preventDefault&&a.preventDefault(),a.stopPropagation&&d.stopPropagation&&a.stopPropagation());var b={view:this,model:this.model,collection:this.collection};this.triggerMethod(e,b)}},setElement:function(){var a=b.View.prototype.setElement.apply(this,arguments);return c.invoke(this._behaviors,"proxyViewProperties",this),a},triggerMethod:function(){for(var a=e._triggerMethod,b=a(this,arguments),c=this._behaviors,d=0,f=c&&c.length;f>d;d++)a(c[d],arguments);return b},_getImmediateChildren:function(){return[]},_getNestedViews:function(){var a=this._getImmediateChildren();return a.length?c.reduce(a,function(a,b){return b._getNestedViews?a.concat(b._getNestedViews()):a},a):a},normalizeMethods:e.normalizeMethods,getOption:e.proxyGetOption,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.ItemView=e.View.extend({constructor:function(){e.View.apply(this,arguments)},serializeData:function(){if(!this.model&&!this.collection)return{};var a=[this.model||this.collection];return arguments.length&&a.push.apply(a,arguments),this.model?this.serializeModel.apply(this,a):{items:this.serializeCollection.apply(this,a)}},serializeCollection:function(a){return a.toJSON.apply(a,c.rest(arguments))},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderTemplate(),this.bindUIElements(),this.triggerMethod("render",this),this},_renderTemplate:function(){var a=this.getTemplate();if(a!==!1){if(!a)throw new e.Error({name:"UndefinedTemplateError",message:"Cannot render the template since it is null or undefined."});var b=this.serializeData();b=this.mixinTemplateHelpers(b);var c=e.Renderer.render(a,b,this);return this.attachElContent(c),this}},attachElContent:function(a){return this.$el.html(a),this}}),e.CollectionView=e.View.extend({childViewEventPrefix:"childview",constructor:function(a){var b=a||{};c.isUndefined(this.sort)&&(this.sort=c.isUndefined(b.sort)?!0:b.sort),this.once("render",this._initialEvents),this._initChildViewStorage(),e.View.apply(this,arguments),this.initRenderBuffer()},initRenderBuffer:function(){this.elBuffer=document.createDocumentFragment(),this._bufferedChildren=[]},startBuffering:function(){this.initRenderBuffer(),this.isBuffering=!0},endBuffering:function(){this.isBuffering=!1,this._triggerBeforeShowBufferedChildren(),this.attachBuffer(this,this.elBuffer),this._triggerShowBufferedChildren(),this.initRenderBuffer()},_triggerBeforeShowBufferedChildren:function(){this._isShown&&c.each(this._bufferedChildren,c.partial(this._triggerMethodOnChild,"before:show"))},_triggerShowBufferedChildren:function(){this._isShown&&(c.each(this._bufferedChildren,c.partial(this._triggerMethodOnChild,"show")),this._bufferedChildren=[])},_triggerMethodOnChild:function(a,b){e.triggerMethodOn(b,a)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this.render),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},_onCollectionAdd:function(a){this.destroyEmptyView();var b=this.getChildView(a),c=this.collection.indexOf(a);this.addChild(a,b,c)},_onCollectionRemove:function(a){var b=this.children.findByModel(a);this.removeChildView(b),this.checkEmpty()},onShowCalled:function(){this.children.each(c.partial(this._triggerMethodOnChild,"show"))},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderChildren(),this.triggerMethod("render",this),this},resortView:function(){this.render()},_sortViews:function(){var a=this.collection.find(function(a,b){var c=this.children.findByModel(a);return!c||c._index!==b},this);a&&this.resortView()},_emptyViewIndex:-1,_renderChildren:function(){this.destroyEmptyView(),this.destroyChildren(),this.isEmpty(this.collection)?this.showEmptyView():(this.triggerMethod("before:render:collection",this),this.startBuffering(),this.showCollection(),this.endBuffering(),this.triggerMethod("render:collection",this))},showCollection:function(){var a;this.collection.each(function(b,c){a=this.getChildView(b),this.addChild(b,a,c)},this)},showEmptyView:function(){var a=this.getEmptyView();if(a&&!this._showingEmptyView){this.triggerMethod("before:render:empty"),this._showingEmptyView=!0;var c=new b.Model;this.addEmptyView(c,a),this.triggerMethod("render:empty")}},destroyEmptyView:function(){this._showingEmptyView&&(this.triggerMethod("before:remove:empty"),this.destroyChildren(),delete this._showingEmptyView,this.triggerMethod("remove:empty"))},getEmptyView:function(){return this.getOption("emptyView")},addEmptyView:function(a,b){var d=this.getOption("emptyViewOptions")||this.getOption("childViewOptions");c.isFunction(d)&&(d=d.call(this,a,this._emptyViewIndex));var f=this.buildChildView(a,b,d);f._parent=this,this.proxyChildEvents(f),this._isShown&&e.triggerMethodOn(f,"before:show"),this.children.add(f),this.renderChildView(f,this._emptyViewIndex),this._isShown&&e.triggerMethodOn(f,"show")},getChildView:function(a){var b=this.getOption("childView");if(!b)throw new e.Error({name:"NoChildViewError",message:'A "childView" must be specified'});return b},addChild:function(a,b,c){var d=this.getOption("childViewOptions");d=e._getValue(d,this,[a,c]);var f=this.buildChildView(a,b,d);return this._updateIndices(f,!0,c),this._addChildView(f,c),f._parent=this,f},_updateIndices:function(a,b,c){this.sort&&(b&&(a._index=c),this.children.each(function(c){c._index>=a._index&&(c._index+=b?1:-1)}))},_addChildView:function(a,b){this.proxyChildEvents(a),this.triggerMethod("before:add:child",a),this.children.add(a),this.renderChildView(a,b),this._isShown&&!this.isBuffering&&e.triggerMethodOn(a,"show"),this.triggerMethod("add:child",a)},renderChildView:function(a,b){return a.render(),this.attachHtml(this,a,b),a},buildChildView:function(a,b,d){var e=c.extend({model:a},d);return new b(e)},removeChildView:function(a){return a&&(this.triggerMethod("before:remove:child",a),a.destroy?a.destroy():a.remove&&a.remove(),delete a._parent,this.stopListening(a),this.children.remove(a),this.triggerMethod("remove:child",a),this._updateIndices(a,!1)),a},isEmpty:function(){return!this.collection||0===this.collection.length},checkEmpty:function(){this.isEmpty(this.collection)&&this.showEmptyView()},attachBuffer:function(a,b){a.$el.append(b)},attachHtml:function(a,b,c){a.isBuffering?(a.elBuffer.appendChild(b.el),a._bufferedChildren.push(b)):a._insertBefore(b,c)||a._insertAfter(b)},_insertBefore:function(a,b){var c,d=this.sort&&b<this.children.length-1;return d&&(c=this.children.find(function(a){return a._index===b+1})),c?(c.$el.before(a.el),!0):!1},_insertAfter:function(a){this.$el.append(a.el)},_initChildViewStorage:function(){this.children=new b.ChildViewContainer},destroy:function(){return this.isDestroyed?void 0:(this.triggerMethod("before:destroy:collection"),this.destroyChildren(),this.triggerMethod("destroy:collection"),e.View.prototype.destroy.apply(this,arguments))},destroyChildren:function(){var a=this.children.map(c.identity);return this.children.each(this.removeChildView,this),this.checkEmpty(),a},proxyChildEvents:function(a){var b=this.getOption("childViewEventPrefix");this.listenTo(a,"all",function(){var d=c.toArray(arguments),e=d[0],f=this.normalizeMethods(c.result(this,"childEvents"));d[0]=b+":"+e,d.splice(1,0,a),"undefined"!=typeof f&&c.isFunction(f[e])&&f[e].apply(this,d.slice(1)),this.triggerMethod.apply(this,d)},this)},_getImmediateChildren:function(){return c.values(this.children._views)}}),e.CompositeView=e.CollectionView.extend({constructor:function(){e.CollectionView.apply(this,arguments)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"remove",this._onCollectionRemove),this.listenTo(this.collection,"reset",this._renderChildren),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},getChildView:function(a){var b=this.getOption("childView")||this.constructor;return b},serializeData:function(){var a={};return this.model&&(a=c.partial(this.serializeModel,this.model).apply(this,arguments)),a},render:function(){return this._ensureViewIsIntact(),this.isRendered=!0,this.resetChildViewContainer(),this.triggerMethod("before:render",this),this._renderTemplate(),this._renderChildren(),this.triggerMethod("render",this),this},_renderChildren:function(){this.isRendered&&e.CollectionView.prototype._renderChildren.call(this)},_renderTemplate:function(){var a={};a=this.serializeData(),a=this.mixinTemplateHelpers(a),this.triggerMethod("before:render:template");var b=this.getTemplate(),c=e.Renderer.render(b,a,this);this.attachElContent(c),this.bindUIElements(),this.triggerMethod("render:template")},attachElContent:function(a){return this.$el.html(a),this},attachBuffer:function(a,b){var c=this.getChildViewContainer(a);c.append(b)},_insertAfter:function(a){var b=this.getChildViewContainer(this,a);b.append(a.el)},getChildViewContainer:function(a,b){if("$childViewContainer"in a)return a.$childViewContainer;var c,d=e.getOption(a,"childViewContainer");if(d){var f=e._getValue(d,a);if(c="@"===f.charAt(0)&&a.ui?a.ui[f.substr(4)]:a.$(f),c.length<=0)throw new e.Error({name:"ChildViewContainerMissingError",message:'The specified "childViewContainer" was not found: '+a.childViewContainer})}else c=a.$el;return a.$childViewContainer=c,c},resetChildViewContainer:function(){this.$childViewContainer&&delete this.$childViewContainer}}),e.LayoutView=e.ItemView.extend({regionClass:e.Region,constructor:function(a){a=a||{},this._firstRender=!0,this._initializeRegions(a),e.ItemView.call(this,a)},render:function(){return this._ensureViewIsIntact(),this._firstRender?this._firstRender=!1:this._reInitializeRegions(),e.ItemView.prototype.render.apply(this,arguments)},destroy:function(){return this.isDestroyed?this:(this.regionManager.destroy(),e.ItemView.prototype.destroy.apply(this,arguments))},addRegion:function(a,b){var c={};return c[a]=b,this._buildRegions(c)[a]},addRegions:function(a){return this.regions=c.extend({},this.regions,a),this._buildRegions(a)},removeRegion:function(a){return delete this.regions[a],this.regionManager.removeRegion(a)},getRegion:function(a){return this.regionManager.get(a)},getRegions:function(){return this.regionManager.getRegions()},_buildRegions:function(a){var b={regionClass:this.getOption("regionClass"),parentEl:c.partial(c.result,this,"el")};return this.regionManager.addRegions(a,b)},_initializeRegions:function(a){var b;this._initRegionManager(),b=e._getValue(this.regions,this,[a])||{};var d=this.getOption.call(a,"regions");d=e._getValue(d,this,[a]),c.extend(b,d),b=this.normalizeUIValues(b),this.addRegions(b)},_reInitializeRegions:function(){this.regionManager.invoke("reset")},getRegionManager:function(){return new e.RegionManager},_initRegionManager:function(){this.regionManager=this.getRegionManager(),this.regionManager._parent=this,this.listenTo(this.regionManager,"before:add:region",function(a){this.triggerMethod("before:add:region",a)}),this.listenTo(this.regionManager,"add:region",function(a,b){this[a]=b,this.triggerMethod("add:region",a,b)}),this.listenTo(this.regionManager,"before:remove:region",function(a){this.triggerMethod("before:remove:region",a)}),this.listenTo(this.regionManager,"remove:region",function(a,b){delete this[a],this.triggerMethod("remove:region",a,b)})},_getImmediateChildren:function(){return c.chain(this.regionManager.getRegions()).pluck("currentView").compact().value()}}),e.Behavior=e.Object.extend({constructor:function(a,b){this.view=b,this.defaults=c.result(this,"defaults")||{},this.options=c.extend({},this.defaults,a),e.Object.apply(this,arguments)},$:function(){return this.view.$.apply(this.view,arguments)},destroy:function(){this.stopListening()},proxyViewProperties:function(a){this.$el=a.$el,this.el=a.el}}),e.Behaviors=function(a,b){function c(a,d){return b.isObject(a.behaviors)?(d=c.parseBehaviors(a,d||b.result(a,"behaviors")),c.wrap(a,d,b.keys(f)),d):{}}function d(a,c){this._view=a,this._viewUI=b.result(a,"ui"),this._behaviors=c,this._triggers={}}var e=/^(\S+)\s*(.*)$/,f={behaviorTriggers:function(a,b){var c=new d(this,b);return c.buildBehaviorTriggers()},behaviorEvents:function(c,d){var f={},g=this._uiBindings||b.result(this,"ui");return b.each(d,function(c,d){var h={},i=b.clone(b.result(c,"events"))||{},j=c._uiBindings||b.result(c,"ui"),k=b.extend({},g,j);i=a.normalizeUIKeys(i,k);var l=0;b.each(i,function(a,f){var g=f.match(e),i=g[1]+"."+[this.cid,d,l++," "].join(""),j=g[2],k=i+j,m=b.isFunction(a)?a:c[a];h[k]=b.bind(m,c)},this),f=b.extend(f,h)},this),f}};return b.extend(c,{behaviorsLookup:function(){throw new a.Error({message:"You must define where your behaviors are stored.",url:"marionette.behaviors.html#behaviorslookup"})},getBehaviorClass:function(b,d){return b.behaviorClass?b.behaviorClass:a._getValue(c.behaviorsLookup,this,[b,d])[d]},parseBehaviors:function(a,d){return b.chain(d).map(function(d,e){var f=c.getBehaviorClass(d,e),g=new f(d,a),h=c.parseBehaviors(a,b.result(g,"behaviors"));return[g].concat(h)}).flatten().value()},wrap:function(a,c,d){b.each(d,function(d){a[d]=b.partial(f[d],a[d],c)})}}),b.extend(d.prototype,{buildBehaviorTriggers:function(){return b.each(this._behaviors,this._buildTriggerHandlersForBehavior,this),this._triggers},_buildTriggerHandlersForBehavior:function(c,d){var e=b.extend({},this._viewUI,b.result(c,"ui")),f=b.clone(b.result(c,"triggers"))||{};f=a.normalizeUIKeys(f,e),b.each(f,b.bind(this._setHandlerForBehavior,this,c,d))},_setHandlerForBehavior:function(a,b,c,d){var e=d.replace(/^\S+/,function(a){return a+".behaviortriggers"+b});this._triggers[e]=this._view._buildViewTrigger(c)}}),c}(e,c),e.AppRouter=b.Router.extend({constructor:function(a){this.options=a||{},b.Router.apply(this,arguments);var c=this.getOption("appRoutes"),d=this._getController();this.processAppRoutes(d,c),this.on("route",this._processOnRoute,this)},appRoute:function(a,b){var c=this._getController();this._addAppRoute(c,a,b)},_processOnRoute:function(a,b){if(c.isFunction(this.onRoute)){var d=c.invert(this.getOption("appRoutes"))[a];this.onRoute(a,d,b)}},processAppRoutes:function(a,b){if(b){var d=c.keys(b).reverse();c.each(d,function(c){this._addAppRoute(a,c,b[c])},this)}},_getController:function(){return this.getOption("controller")},_addAppRoute:function(a,b,d){var f=a[d];if(!f)throw new e.Error('Method "'+d+'" was not found on the controller');this.route(b,d,c.bind(f,a))},getOption:e.proxyGetOption,triggerMethod:e.triggerMethod,bindEntityEvents:e.proxyBindEntityEvents,unbindEntityEvents:e.proxyUnbindEntityEvents}),e.Application=e.Object.extend({constructor:function(a){this._initializeRegions(a),this._initCallbacks=new e.Callbacks,this.submodules={},c.extend(this,a),this._initChannel(),e.Object.call(this,a)},execute:function(){this.commands.execute.apply(this.commands,arguments)},request:function(){return this.reqres.request.apply(this.reqres,arguments)},addInitializer:function(a){this._initCallbacks.add(a)},start:function(a){this.triggerMethod("before:start",a),this._initCallbacks.run(a,this),this.triggerMethod("start",a)},addRegions:function(a){return this._regionManager.addRegions(a)},emptyRegions:function(){return this._regionManager.emptyRegions()},removeRegion:function(a){return this._regionManager.removeRegion(a)},getRegion:function(a){return this._regionManager.get(a)},getRegions:function(){return this._regionManager.getRegions()},module:function(a,b){var d=e.Module.getClass(b),f=c.toArray(arguments);return f.unshift(this),d.create.apply(d,f)},getRegionManager:function(){return new e.RegionManager},_initializeRegions:function(a){var b=c.isFunction(this.regions)?this.regions(a):this.regions||{};this._initRegionManager();var d=e.getOption(a,"regions");return c.isFunction(d)&&(d=d.call(this,a)),c.extend(b,d),this.addRegions(b),this},_initRegionManager:function(){this._regionManager=this.getRegionManager(),this._regionManager._parent=this,this.listenTo(this._regionManager,"before:add:region",function(){e._triggerMethod(this,"before:add:region",arguments)}),this.listenTo(this._regionManager,"add:region",function(a,b){this[a]=b,e._triggerMethod(this,"add:region",arguments)}),this.listenTo(this._regionManager,"before:remove:region",function(){e._triggerMethod(this,"before:remove:region",arguments)}),this.listenTo(this._regionManager,"remove:region",function(a){delete this[a],e._triggerMethod(this,"remove:region",arguments)})},_initChannel:function(){this.channelName=c.result(this,"channelName")||"global",this.channel=c.result(this,"channel")||b.Wreqr.radio.channel(this.channelName),this.vent=c.result(this,"vent")||this.channel.vent,this.commands=c.result(this,"commands")||this.channel.commands,this.reqres=c.result(this,"reqres")||this.channel.reqres}}),e.Module=function(a,b,d){this.moduleName=a,this.options=c.extend({},this.options,d),this.initialize=d.initialize||this.initialize,this.submodules={},this._setupInitializersAndFinalizers(),this.app=b,c.isFunction(this.initialize)&&this.initialize(a,b,this.options)},e.Module.extend=e.extend,c.extend(e.Module.prototype,b.Events,{startWithParent:!0,initialize:function(){},addInitializer:function(a){this._initializerCallbacks.add(a)},addFinalizer:function(a){this._finalizerCallbacks.add(a)},start:function(a){this._isInitialized||(c.each(this.submodules,function(b){b.startWithParent&&b.start(a)}),this.triggerMethod("before:start",a),this._initializerCallbacks.run(a,this),this._isInitialized=!0,this.triggerMethod("start",a))},stop:function(){this._isInitialized&&(this._isInitialized=!1,this.triggerMethod("before:stop"),c.invoke(this.submodules,"stop"),this._finalizerCallbacks.run(void 0,this),this._initializerCallbacks.reset(),this._finalizerCallbacks.reset(),this.triggerMethod("stop"))},addDefinition:function(a,b){this._runModuleDefinition(a,b)},_runModuleDefinition:function(a,d){if(a){var f=c.flatten([this,this.app,b,e,b.$,c,d]);a.apply(this,f)}},_setupInitializersAndFinalizers:function(){this._initializerCallbacks=new e.Callbacks,this._finalizerCallbacks=new e.Callbacks},triggerMethod:e.triggerMethod}),c.extend(e.Module,{create:function(a,b,d){var e=a,f=c.rest(arguments,3);b=b.split(".");var g=b.length,h=[];return h[g-1]=d,c.each(b,function(b,c){var g=e;e=this._getModule(g,b,a,d),this._addModuleDefinition(g,e,h[c],f)},this),e},_getModule:function(a,b,d,e,f){var g=c.extend({},e),h=this.getClass(e),i=a[b];return i||(i=new h(b,d,g),a[b]=i,a.submodules[b]=i),i},getClass:function(a){var b=e.Module;return a?a.prototype instanceof b?a:a.moduleClass||b:b},_addModuleDefinition:function(a,b,c,d){var e=this._getDefine(c),f=this._getStartWithParent(c,b);e&&b.addDefinition(e,d),this._addStartWithParent(a,b,f)},_getStartWithParent:function(a,b){var d;return c.isFunction(a)&&a.prototype instanceof e.Module?(d=b.constructor.prototype.startWithParent,c.isUndefined(d)?!0:d):c.isObject(a)?(d=a.startWithParent,c.isUndefined(d)?!0:d):!0},_getDefine:function(a){return!c.isFunction(a)||a.prototype instanceof e.Module?c.isObject(a)?a.define:null:a},_addStartWithParent:function(a,b,c){b.startWithParent=b.startWithParent&&c,b.startWithParent&&!b.startWithParentIsConfigured&&(b.startWithParentIsConfigured=!0,a.addInitializer(function(a){b.startWithParent&&b.start(a)}))}}),e}),function(a){"function"==typeof define&&define.amd?define(["backbone","underscore"],a):"object"==typeof exports?module.exports=a(require("backbone"),require("underscore")):a(window.Backbone,window._)}(function(a,b){var c=a.Router.prototype.route,d=function(){};b.extend(a.Router.prototype,{before:d,after:d,route:function(a,e,f){f||(f=this[e]);var g=b.bind(function(){var c,e=[a,b.toArray(arguments)];if(c=b.isFunction(this.before)?this.before:"undefined"!=typeof this.before[a]?this.before[a]:d,c.apply(this,e)!==!1){f&&f.apply(this,arguments);var g;g=b.isFunction(this.after)?this.after:"undefined"!=typeof this.after[a]?this.after[a]:d,g.apply(this,e)}},this);return c.call(this,a,e,g)}})}),function(a,b,c,d,e,f,g){"use strict";"object"==typeof d?e.exports=f(c("underscore"),c("backbone"),c("jquery")):"function"==typeof b&&b.amd?b(["underscore","backbone","jquery"],function(b,c,d){return b=b===g?a._:b,c=c===g?a.Backbone:c,d=d===g?a.$:d,a.Backbone=f(b,c,d)}):a.returnExportsGlobal=f(a._,a.Backbone,a.$)}(this,this.define,this.require,this.exports,this.module,function(a,b,c,d){"use strict";var e=function(b){this.options=b!==d?b:{},this.namespaceDelimiter=b!==d&&b.namespaceDelimiter!==d?b.namespaceDelimiter:this.namespaceDelimiter,this.contentType=b!==d&&b.contentType!==d?b.contentType:this.contentType,a.bindAll(this)},f=b.Model.prototype.constructor,g=b.sync,h={};return e.prototype={options:{},charset:"iso-8859-1",namespace:"",namespaceDelimiter:"/",contentType:"application/json",url:null,responseID:null,exceptions:{404:{code:-1,message:"404"},500:{code:-2,message:"500"},typeMissmatch:{ +code:-3,message:"Type missmatch"},badResponseId:{code:-4,message:"Bad response ID"},noResponse:{code:-5,message:"No response"},noDefError:{code:-6,message:"No error defined"},renderError:function(a,b){return{code:b!==d?-7:b,message:a?"No error defined":a}}},onSuccess:function(b,c,e){if(a.isFunction(b)===!0){if(null===e||e===d)return this.handleExceptions(this.exceptions.noResponse),this;null!==e&&c!==String(e.id)&&this.handleExceptions(this.exceptions.badResponseId),b.apply(this,[e.result,e.error])}else this.onError(e)},onError:function(a,b){return null===b||b===d?(this.handleExceptions(this.exceptions.noResponse),this):void(null!==b.error&&d!==b.error?this.handleExceptions(b.error):this.handleExceptions(this.exceptions.noDefError))},query:function(b,e,f){var g=String((new Date).getTime()),h=null;return this.responseID=g,h=(a.isArray(e)||a.isObject(e))&&a.isString(b)?c.ajax({contentType:this.contentType+"; charset="+this.charset,type:"POST",dataType:"json",url:this.url,data:JSON.stringify({jsonrpc:"2.0",method:this.namespace+this.namespaceDelimiter+b,id:g,params:e}),statusCode:{404:a.bind(function(){this.handleExceptions(this.exceptions[404])},this),500:a.bind(function(){this.handleExceptions(this.exceptions[500])},this)},success:a.bind(function(a,b,c){null!==a&&a.error!==d?this.onError(f,a,b,c):this.onSuccess(f,g,a,b,c)},this),error:a.bind(function(a,b,c){404!==a.status&&500!==a.status&&this.onError(f,a,b,c)},this)}):this.handleExceptions(this.exceptions.typeMissmatch)},checkMethods:function(c,e,f,g,i,j,k){var l=this,m=this.options&&this.options.useNamedParameters===!0,n=null,o=!1,p=null,q=[],r={},s=null,t=f;return m=f.options&&f.options.useNamedParameters?f.options.useNamedParameters:m,m&&(q={},a.isFunction(f.args)&&(t=f.args())),g="delete"===g?"remove":g,a.isArray(f.methods[g])||a.isFunction(f.methods[g])?(a.isFunction(f.methods[g])?(a.isString(h[f.get("_rpcId")])||a.each(h[f.get("_rpcId")],function(a,b){f.get(b)!==a&&(r[b]=!0)}),h[f.get("_rpcId")]=f.toJSON(),n=a.bind(f.methods[g],f)(r,i)):n=f.methods[g],a.isArray(n[0])&&(o=!0),o!==!0?(s=a.clone(n),p=s.shift(),s.length>0?a.each(s,function(c){""===c?a.isArray(q)&&q.push(""):f instanceof b.Collection?t!==d&&t[c]!==d?q=l.addParam(q,t,c,a.isFunction(t[c]),!1):i[c]!==d&&(q=l.addParam(q,i,c,!1,!1)):f.get(c)!==d?q=l.addParam(q,f,c,!1,!0):i[c]!==d&&(q=l.addParam(q,i,c,!1,!1))}):q=a.isArray(q)?[]:{},c(p,q,j,k)):(a.each(n,function(b){var d=a.clone(b);return p=null,q=[],p=d.shift(),a.each(d,function(a){q.push(f.get(a))}),c(p,q,j,k)}),null)):this.handleExceptions(this.exceptions.typeMissmatch)},addParam:function(b,c,e,f,g){var h;return h=g?c.get(e):f?c[e]():c[e],a.isArray(b)?b.push(h):h!==d&&(b[e]=h),b},invoke:function(c,e,f){var g={success:function(b){e.trigger("called:"+c,e,b),f!==d&&a.isFunction(f.success)&&f.success(e,b)},error:function(b,e){b.trigger("error",b,e),b.trigger("error:"+c,b,e),f!==d&&a.isFunction(f.error)&&f.error(b,e)}};return b.sync(c,e,g),this},defaultExceptionHandler:function(a){throw"Error code: "+a.code+" - message: "+a.message},handleExceptions:function(b){var c=a.isFunction(this.options.exceptionHandler)?this.options.exceptionHandler:this.defaultExceptionHandler;return c.call(this,b),this}},b.Rpc=e,b.Model=b.Model.extend({constructor:function(b){this.rpc!==d&&a.isFunction(this.rpc.invoke)===!0&&this.methods!==d&&a.each(this.methods,a.bind(function(b,c){1!=={read:1,create:1,remove:1,update:1}[c]&&(this[c]=a.bind(function(a){return this.rpc.invoke(c,this,a),this},this))},this)),f.apply(this,arguments)}}),b.sync=function(c){var e=null,f=function(g,i,j){var k=function(c,e){return null!==e&&e!==d?(j.error(i,e),this):(i instanceof b.Collection&&c!==d&&null!==c&&("object"==typeof c[0]?a.each(c,function(b,d){b._rpcId=a.uniqueId("rpc_"),c[d]=b,h[b._rpcId]=b}):a.each(c,function(a,b){h[b]=a})),i instanceof b.Model&&c!==d&&null!==c&&(c._rpcId=a.uniqueId("rpc_"),h[c._rpcId]=c),(c===d||null===c)&&(c=[]),i.parsers!==d&&i.parsers[g]!==d&&a.isFunction(i.parsers[g])&&i.parsers[g].apply(i,[c]),void j.success(c))},l=function(a){j.error(i,a)};if(i.rpc instanceof c){if(e=i.rpc,e.url=a.isFunction(i.url)?i.url():i.url,a.isString(i.namespace)===!0&&(e.namespace=i.namespace),i.methods===d)throw"Backbone.Rpc Error: No Method(s) given!";return"object"!=typeof i.params&&(i.params={}),e.checkMethods(e.query,i.params,i,g,j,k,l)}return f.previous.apply(i,arguments)};return f.previous=g,f}(e),b}),function(a,b){if("function"==typeof define&&define.amd)define(["underscore","backbone","jquery"],function(a,c,d){return b(a,c,d)});else if("undefined"!=typeof exports){var c=require("underscore"),d=require("backbone"),e=require("jquery");module.exports=b(c,d,e)}else b(a._,a.Backbone,a.jQuery)}(this,function(a,b,c){"use strict";var d=b.Syphon,e=b.Syphon={};e.VERSION="0.5.0",e.noConflict=function(){return b.Syphon=d,this},e.ignoredTypes=["button","submit","reset","fieldset"],e.serialize=function(b,d){var e={},h=i(d),k=f(b,h);return a.each(k,function(a){var b=c(a),d=g(b),f=h.keyExtractors.get(d),i=f(b),k=h.inputReaders.get(d),l=k(b),m=h.keyAssignmentValidators.get(d);if(m(b,i,l)){var n=h.keySplitter(i);e=j(e,n,l)}}),e},e.deserialize=function(b,d,e){var h=i(e),j=f(b,h),l=k(h,d);a.each(j,function(a){var b=c(a),d=g(b),e=h.keyExtractors.get(d),f=e(b),i=h.inputWriters.get(d),j=l[f];i(b,j)})};var f=function(b,d){var e=h(b),f=e.elements;return f=a.reject(f,function(b){var e,f=g(b),h=d.keyExtractors.get(f),i=h(c(b)),j=a.include(d.ignoredTypes,f),k=a.include(d.include,i),l=a.include(d.exclude,i);return e=k?!1:d.include?!0:l||j})},g=function(a){var b,d=c(a),e=d[0].tagName,f=e;return"input"===e.toLowerCase()&&(b=d.attr("type"),f=b?b:"text"),f.toLowerCase()},h=function(b){return a.isUndefined(b.$el)&&"form"===b.tagName.toLowerCase()?b:b.$el.is("form")?b.el:b.$("form")[0]},i=function(b){var c=a.clone(b)||{};return c.ignoredTypes=a.clone(e.ignoredTypes),c.inputReaders=c.inputReaders||e.InputReaders,c.inputWriters=c.inputWriters||e.InputWriters,c.keyExtractors=c.keyExtractors||e.KeyExtractors,c.keySplitter=c.keySplitter||e.KeySplitter,c.keyJoiner=c.keyJoiner||e.KeyJoiner,c.keyAssignmentValidators=c.keyAssignmentValidators||e.KeyAssignmentValidators,c},j=function(b,c,d){if(!c)return b;var e=c.shift();return b[e]||(b[e]=a.isArray(e)?[]:{}),0===c.length&&(a.isArray(b[e])?b[e].push(d):b[e]=d),c.length>0&&j(b[e],c,d),b},k=function(b,c,d){var e={};return a.each(c,function(c,f){var g={};d&&(f=b.keyJoiner(d,f)),a.isArray(c)?(f+="[]",g[f]=c):a.isObject(c)?g=k(b,c,f):g[f]=c,a.extend(e,g)}),e},l=e.TypeRegistry=function(){this.registeredTypes={}};l.extend=b.Model.extend,a.extend(l.prototype,{get:function(a){return this.registeredTypes[a]||this.registeredTypes["default"]},register:function(a,b){this.registeredTypes[a]=b},registerDefault:function(a){this.registeredTypes["default"]=a},unregister:function(a){this.registeredTypes[a]&&delete this.registeredTypes[a]}});var m=e.KeyExtractorSet=l.extend(),n=e.KeyExtractors=new m;n.registerDefault(function(a){return a.prop("name")||""});var o=e.InputReaderSet=l.extend(),p=e.InputReaders=new o;p.registerDefault(function(a){return a.val()}),p.register("checkbox",function(a){return a.prop("checked")});var q=e.InputWriterSet=l.extend(),r=e.InputWriters=new q;r.registerDefault(function(a,b){a.val(b)}),r.register("checkbox",function(a,b){a.prop("checked",b)}),r.register("radio",function(a,b){a.prop("checked",a.val()===b.toString())});var s=e.KeyAssignmentValidatorSet=l.extend(),t=e.KeyAssignmentValidators=new s;return t.registerDefault(function(){return!0}),t.register("radio",function(a,b,c){return a.prop("checked")}),e.KeySplitter=function(a){var b,c=a.match(/[^\[\]]+/g);return a.indexOf("[]")===a.length-2&&(b=c.pop(),c.push([b])),c},e.KeyJoiner=function(a,b){return a+"["+b+"]"},b.Syphon}),function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.Wreqr,d=a.Wreqr={};return a.Wreqr.VERSION="1.3.2",a.Wreqr.noConflict=function(){return a.Wreqr=c,this},d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this)},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(b)return function(){return b.callback.apply(b.context,arguments)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,b),d.CommandStorage=function(){var c=function(a){this.options=a,this._commands={},b.isFunction(this.initialize)&&this.initialize(a)};return b.extend(c.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),c}(),d.Commands=function(a,b){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this),a.Handlers.prototype.constructor.apply(this,arguments)},execute:function(a){a=arguments[0];var c=b.rest(arguments);this.hasHandler(a)?this.getHandler(a).apply(this,c):this.storage.addCommand(a,c)},_executeCommands:function(a,c,d){var e=this.storage.getCommands(a);b.each(e.instances,function(a){c.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var c,d=a.storageType||this.storageType;c=b.isFunction(d)?new d:d,this.storage=c}})}(d,b),d.RequestResponse=function(a,b){return a.Handlers.extend({request:function(a){return this.hasHandler(a)?this.getHandler(a).apply(this,b.rest(arguments)):void 0}})}(d,b),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,b),d.Channel=function(c){var d=function(b){this.vent=new a.Wreqr.EventAggregator,this.reqres=new a.Wreqr.RequestResponse,this.commands=new a.Wreqr.Commands,this.channelName=b};return b.extend(d.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(a,b){return this._connect("vent",a,b),this},connectCommands:function(a,b){return this._connect("commands",a,b),this},connectRequests:function(a,b){return this._connect("reqres",a,b),this},_connect:function(a,c,d){if(c){d=d||this;var e="vent"===a?"on":"setHandler";b.each(c,function(c,f){this[a][e](f,b.bind(c,d))},this)}}}),d}(d),d.radio=function(a,b){var c=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};b.extend(c.prototype,{channel:function(a){if(!a)throw new Error("Channel must receive a name");return this._getChannel(a)},_getChannel:function(b){var c=this._channels[b];return c||(c=new a.Channel(b),this._channels[b]=c),c},_proxyMethods:function(){b.each(["vent","commands","reqres"],function(a){b.each(d[a],function(b){this[a][b]=e(this,a,b)},this)},this)}});var d={vent:["on","off","trigger","once","stopListening","listenTo","listenToOnce"],commands:["execute","setHandler","setHandlers","removeHandler","removeAllHandlers"],reqres:["request","setHandler","setHandlers","removeHandler","removeAllHandlers"]},e=function(a,c,d){return function(e){var f=a._getChannel(e)[c];return f[d].apply(f,b.rest(arguments))}};return new c}(d,b),a.Wreqr});var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(a){var b,c,d,e,f,g,h,i="",j=0;for(a=Base64._utf8_encode(a);j<a.length;)b=a.charCodeAt(j++),c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=b>>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i=i+this._keyStr.charAt(e)+this._keyStr.charAt(f)+this._keyStr.charAt(g)+this._keyStr.charAt(h);return i},decode:function(a){var b,c,d,e,f,g,h,i="",j=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");j<a.length;)e=this._keyStr.indexOf(a.charAt(j++)),f=this._keyStr.indexOf(a.charAt(j++)),g=this._keyStr.indexOf(a.charAt(j++)),h=this._keyStr.indexOf(a.charAt(j++)),b=e<<2|f>>4,c=(15&f)<<4|g>>2,d=(3&g)<<6|h,i+=String.fromCharCode(b),64!=g&&(i+=String.fromCharCode(c)),64!=h&&(i+=String.fromCharCode(d));return i=Base64._utf8_decode(i)},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b="",c=0,d=c1=c2=0;c<a.length;)d=a.charCodeAt(c),128>d?(b+=String.fromCharCode(d),c++):d>191&&224>d?(c2=a.charCodeAt(c+1),b+=String.fromCharCode((31&d)<<6|63&c2),c+=2):(c2=a.charCodeAt(c+1),c3=a.charCodeAt(c+2),b+=String.fromCharCode((15&d)<<12|(63&c2)<<6|63&c3),c+=3);return b}};Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|aft(er)?|from|hence)/i,subtract:/^(\-|bef(ore)?|ago)/i,yesterday:/^yes(terday)?/i,today:/^t(od(ay)?)?/i,tomorrow:/^tom(orrow)?/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^mn|min(ute)?s?/i,hour:/^h(our)?s?/i,week:/^w(eek)?s?/i,month:/^m(onth)?s?/i,day:/^d(ay)?s?/i,year:/^y(ear)?s?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a(?!u|p)|p)/i},timezones:[{name:"UTC",offset:"-000"},{name:"GMT",offset:"-000"},{name:"EST",offset:"-0500"},{name:"EDT",offset:"-0400"},{name:"CST",offset:"-0600"},{name:"CDT",offset:"-0500"},{name:"MST",offset:"-0700"},{name:"MDT",offset:"-0600"},{name:"PST",offset:"-0800"},{name:"PDT",offset:"-0700"}]},function(){var a=Date,b=a.prototype,c=a.CultureInfo,d=function(a,b){return b||(b=2),("000"+a).slice(-1*b)};b.clearTime=function(){return this.setHours(0),this.setMinutes(0),this.setSeconds(0),this.setMilliseconds(0),this},b.setTimeToNow=function(){var a=new Date;return this.setHours(a.getHours()),this.setMinutes(a.getMinutes()),this.setSeconds(a.getSeconds()),this.setMilliseconds(a.getMilliseconds()),this},a.today=function(){return(new Date).clearTime()},a.compare=function(a,b){if(isNaN(a)||isNaN(b))throw new Error(a+" - "+b);if(a instanceof Date&&b instanceof Date)return b>a?-1:a>b?1:0;throw new TypeError(a+" - "+b)},a.equals=function(a,b){return 0===a.compareTo(b)},a.getDayNumberFromName=function(a){for(var b=c.dayNames,d=c.abbreviatedDayNames,e=c.shortestDayNames,f=a.toLowerCase(),g=0;g<b.length;g++)if(b[g].toLowerCase()==f||d[g].toLowerCase()==f||e[g].toLowerCase()==f)return g;return-1},a.getMonthNumberFromName=function(a){for(var b=c.monthNames,d=c.abbreviatedMonthNames,e=a.toLowerCase(),f=0;f<b.length;f++)if(b[f].toLowerCase()==e||d[f].toLowerCase()==e)return f;return-1},a.isLeapYear=function(a){return a%4===0&&a%100!==0||a%400===0},a.getDaysInMonth=function(b,c){return[31,a.isLeapYear(b)?29:28,31,30,31,30,31,31,30,31,30,31][c]},a.getTimezoneAbbreviation=function(a){for(var b=c.timezones,d=0;d<b.length;d++)if(b[d].offset===a)return b[d].name;return null},a.getTimezoneOffset=function(a){for(var b=c.timezones,d=0;d<b.length;d++)if(b[d].name===a.toUpperCase())return b[d].offset;return null},b.clone=function(){return new Date(this.getTime())},b.compareTo=function(a){return Date.compare(this,a)},b.equals=function(a){return Date.equals(this,a||new Date)},b.between=function(a,b){return this.getTime()>=a.getTime()&&this.getTime()<=b.getTime()},b.isAfter=function(a){return 1===this.compareTo(a||new Date)},b.isBefore=function(a){return-1===this.compareTo(a||new Date)},b.isToday=function(){return this.isSameDay(new Date)},b.isSameDay=function(a){return this.clone().clearTime().equals(a.clone().clearTime())},b.addMilliseconds=function(a){return this.setMilliseconds(this.getMilliseconds()+a),this},b.addSeconds=function(a){return this.addMilliseconds(1e3*a)},b.addMinutes=function(a){return this.addMilliseconds(6e4*a)},b.addHours=function(a){return this.addMilliseconds(36e5*a)},b.addDays=function(a){return this.setDate(this.getDate()+a),this},b.addWeeks=function(a){return this.addDays(7*a)},b.addMonths=function(b){var c=this.getDate();return this.setDate(1),this.setMonth(this.getMonth()+b),this.setDate(Math.min(c,a.getDaysInMonth(this.getFullYear(),this.getMonth()))),this},b.addYears=function(a){return this.addMonths(12*a)},b.add=function(a){if("number"==typeof a)return this._orient=a,this;var b=a;return b.milliseconds&&this.addMilliseconds(b.milliseconds),b.seconds&&this.addSeconds(b.seconds),b.minutes&&this.addMinutes(b.minutes),b.hours&&this.addHours(b.hours),b.weeks&&this.addWeeks(b.weeks),b.months&&this.addMonths(b.months),b.years&&this.addYears(b.years),b.days&&this.addDays(b.days),this};var e,f,g;b.getWeek=function(){var a,b,c,d,h,i,j,k,l,m;return e=e?e:this.getFullYear(),f=f?f:this.getMonth()+1,g=g?g:this.getDate(),2>=f?(a=e-1,b=(a/4|0)-(a/100|0)+(a/400|0),c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0),l=b-c,h=0,i=g-1+31*(f-1)):(a=e,b=(a/4|0)-(a/100|0)+(a/400|0),c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0),l=b-c,h=l+1,i=g+(153*(f-3)+2)/5+58+l),j=(a+b)%7,d=(i+j-h)%7,k=i+3-d|0,m=0>k?53-((j-l)/5|0):k>364+l?1:(k/7|0)+1,e=f=g=null,m},b.getISOWeek=function(){return e=this.getUTCFullYear(),f=this.getUTCMonth()+1,g=this.getUTCDate(),d(this.getWeek())},b.setWeek=function(a){return this.moveToDayOfWeek(1).addWeeks(a-this.getWeek())},a._validate=function(a,b,c,d){if("undefined"==typeof a)return!1;if("number"!=typeof a)throw new TypeError(a+" is not a Number.");if(b>a||a>c)throw new RangeError(a+" is not a valid value for "+d+".");return!0},a.validateMillisecond=function(b){return a._validate(b,0,999,"millisecond")},a.validateSecond=function(b){return a._validate(b,0,59,"second")},a.validateMinute=function(b){return a._validate(b,0,59,"minute")},a.validateHour=function(b){return a._validate(b,0,23,"hour")},a.validateDay=function(b,c,d){return a._validate(b,1,a.getDaysInMonth(c,d),"day")},a.validateMonth=function(b){return a._validate(b,0,11,"month")},a.validateYear=function(b){return a._validate(b,0,9999,"year")},b.set=function(b){return a.validateMillisecond(b.millisecond)&&this.addMilliseconds(b.millisecond-this.getMilliseconds()),a.validateSecond(b.second)&&this.addSeconds(b.second-this.getSeconds()),a.validateMinute(b.minute)&&this.addMinutes(b.minute-this.getMinutes()),a.validateHour(b.hour)&&this.addHours(b.hour-this.getHours()),a.validateMonth(b.month)&&this.addMonths(b.month-this.getMonth()),a.validateYear(b.year)&&this.addYears(b.year-this.getFullYear()),a.validateDay(b.day,this.getFullYear(),this.getMonth())&&this.addDays(b.day-this.getDate()),b.timezone&&this.setTimezone(b.timezone),b.timezoneOffset&&this.setTimezoneOffset(b.timezoneOffset),b.week&&a._validate(b.week,0,53,"week")&&this.setWeek(b.week),this},b.moveToFirstDayOfMonth=function(){return this.set({day:1})},b.moveToLastDayOfMonth=function(){return this.set({day:a.getDaysInMonth(this.getFullYear(),this.getMonth())})},b.moveToNthOccurrence=function(a,b){var c=0;if(b>0)c=b-1;else if(-1===b)return this.moveToLastDayOfMonth(),this.getDay()!==a&&this.moveToDayOfWeek(a,-1),this;return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(a,1).addWeeks(c)},b.moveToDayOfWeek=function(a,b){var c=(a-this.getDay()+7*(b||1))%7;return this.addDays(0===c?c+=7*(b||1):c)},b.moveToMonth=function(a,b){var c=(a-this.getMonth()+12*(b||1))%12;return this.addMonths(0===c?c+=12*(b||1):c)},b.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/864e5)+1},b.getTimezone=function(){return a.getTimezoneAbbreviation(this.getUTCOffset())},b.setTimezoneOffset=function(a){var b=this.getTimezoneOffset(),c=-6*Number(a)/10;return this.addMinutes(c-b)},b.setTimezone=function(b){return this.setTimezoneOffset(a.getTimezoneOffset(b))},b.hasDaylightSavingTime=function(){return Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset()},b.isDaylightSavingTime=function(){return this.hasDaylightSavingTime()&&(new Date).getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset()},b.getUTCOffset=function(){var a,b=-10*this.getTimezoneOffset()/6;return 0>b?(a=(b-1e4).toString(),a.charAt(0)+a.substr(2)):(a=(b+1e4).toString(),"+"+a.substr(1))},b.getElapsed=function(a){return(a||new Date)-this},b.toISOString||(b.toISOString=function(){function a(a){return 10>a?"0"+a:a}return'"'+this.getUTCFullYear()+"-"+a(this.getUTCMonth()+1)+"-"+a(this.getUTCDate())+"T"+a(this.getUTCHours())+":"+a(this.getUTCMinutes())+":"+a(this.getUTCSeconds())+'Z"'}),b._toString=b.toString,b.toString=function(a){var b=this;if(a&&1==a.length){var e=c.formatPatterns;switch(b.t=b.toString,a){case"d":return b.t(e.shortDate);case"D":return b.t(e.longDate);case"F":return b.t(e.fullDateTime);case"m":return b.t(e.monthDay);case"r":return b.t(e.rfc1123);case"s":return b.t(e.sortableDateTime);case"t":return b.t(e.shortTime);case"T":return b.t(e.longTime);case"u":return b.t(e.universalSortableDateTime);case"y":return b.t(e.yearMonth)}}var f=function(a){switch(1*a){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th"}};return a?a.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(a){if("\\"===a.charAt(0))return a.replace("\\","");switch(b.h=b.getHours,a){case"hh":return d(b.h()<13?0===b.h()?12:b.h():b.h()-12);case"h":return b.h()<13?0===b.h()?12:b.h():b.h()-12;case"HH":return d(b.h());case"H":return b.h();case"mm":return d(b.getMinutes());case"m":return b.getMinutes();case"ss":return d(b.getSeconds());case"s":return b.getSeconds();case"yyyy":return d(b.getFullYear(),4);case"yy":return d(b.getFullYear());case"dddd":return c.dayNames[b.getDay()];case"ddd":return c.abbreviatedDayNames[b.getDay()];case"dd":return d(b.getDate());case"d":return b.getDate();case"MMMM":return c.monthNames[b.getMonth()];case"MMM":return c.abbreviatedMonthNames[b.getMonth()];case"MM":return d(b.getMonth()+1);case"M":return b.getMonth()+1;case"t":return b.h()<12?c.amDesignator.substring(0,1):c.pmDesignator.substring(0,1);case"tt":return b.h()<12?c.amDesignator:c.pmDesignator;case"S":return f(b.getDate());default:return a}}):this._toString()}}(),function(){var a=Date,b=a.prototype,c=a.CultureInfo,d=Number.prototype;b._orient=1,b._nth=null,b._is=!1,b._same=!1,b._isSecond=!1,d._dateElement="day",b.next=function(){return this._orient=1,this},a.next=function(){return a.today().next()},b.last=b.prev=b.previous=function(){return this._orient=-1,this},a.last=a.prev=a.previous=function(){return a.today().last()},b.is=function(){return this._is=!0,this},b.same=function(){return this._same=!0,this._isSecond=!1,this},b.today=function(){return this.same().day()},b.weekday=function(){return this._is?(this._is=!1,!this.is().sat()&&!this.is().sun()):!1},b.at=function(b){return"string"==typeof b?a.parse(this.toString("d")+" "+b):this.set(b)},d.fromNow=d.after=function(a){var b={};return b[this._dateElement]=this,(a?a.clone():new Date).add(b)},d.ago=d.before=function(a){var b={};return b[this._dateElement]=-1*this,(a?a.clone():new Date).add(b)};var e,f="sunday monday tuesday wednesday thursday friday saturday".split(/\s/),g="january february march april may june july august september october november december".split(/\s/),h="Millisecond Second Minute Hour Day Week Month Year".split(/\s/),i="Milliseconds Seconds Minutes Hours Date Week Month FullYear".split(/\s/),j="final first second third fourth fifth".split(/\s/);b.toObject=function(){for(var a={},b=0;b<h.length;b++)a[h[b].toLowerCase()]=this["get"+i[b]]();return a},a.fromObject=function(a){return a.week=null,Date.today().set(a)};for(var k=function(b){return function(){if(this._is)return this._is=!1,this.getDay()==b;if(null!==this._nth){this._isSecond&&this.addSeconds(-1*this._orient),this._isSecond=!1;var c=this._nth;this._nth=null;var d=this.clone().moveToLastDayOfMonth();if(this.moveToNthOccurrence(b,c),this>d)throw new RangeError(a.getDayName(b)+" does not occur "+c+" times in the month of "+a.getMonthName(d.getMonth())+" "+d.getFullYear()+".");return this}return this.moveToDayOfWeek(b,this._orient)}},l=function(b){return function(){var d=a.today(),e=b-d.getDay();return 0===b&&1===c.firstDayOfWeek&&0!==d.getDay()&&(e+=7),d.addDays(e)}},m=0;m<f.length;m++)a[f[m].toUpperCase()]=a[f[m].toUpperCase().substring(0,3)]=m,a[f[m]]=a[f[m].substring(0,3)]=l(m),b[f[m]]=b[f[m].substring(0,3)]=k(m);for(var n=function(a){return function(){return this._is?(this._is=!1,this.getMonth()===a):this.moveToMonth(a,this._orient)}},o=function(b){return function(){return a.today().set({month:b,day:1})}},p=0;p<g.length;p++)a[g[p].toUpperCase()]=a[g[p].toUpperCase().substring(0,3)]=p,a[g[p]]=a[g[p].substring(0,3)]=o(p),b[g[p]]=b[g[p].substring(0,3)]=n(p);for(var q=function(a){return function(){if(this._isSecond)return this._isSecond=!1,this;if(this._same){this._same=this._is=!1;for(var b=this.toObject(),c=(arguments[0]||new Date).toObject(),d="",e=a.toLowerCase(),f=h.length-1;f>-1;f--){if(d=h[f].toLowerCase(),b[d]!=c[d])return!1;if(e==d)break}return!0}return"s"!=a.substring(a.length-1)&&(a+="s"),this["add"+a](this._orient)}},r=function(a){return function(){return this._dateElement=a,this}},s=0;s<h.length;s++)e=h[s].toLowerCase(),b[e]=b[e+"s"]=q(h[s]),d[e]=d[e+"s"]=r(e);b._ss=q("Second");for(var t=function(a){return function(b){return this._same?this._ss(arguments[0]):b||0===b?this.moveToNthOccurrence(b,a):(this._nth=a,2!==a||void 0!==b&&null!==b?this:(this._isSecond=!0,this.addSeconds(this._orient)))}},u=0;u<j.length;u++)b[j[u]]=t(0===u?-1:u)}(),function(){Date.Parsing={Exception:function(a){this.message="Parse error at '"+a.substring(0,10)+" ...'"}};for(var a=Date.Parsing,b=a.Operators={rtoken:function(b){return function(c){var d=c.match(b);if(d)return[d[0],c.substring(d[0].length)];throw new a.Exception(c)}},token:function(a){return function(a){return b.rtoken(new RegExp("^s*"+a+"s*"))(a)}},stoken:function(a){return b.rtoken(new RegExp("^"+a))},until:function(a){return function(b){for(var c=[],d=null;b.length;){try{d=a.call(this,b)}catch(e){c.push(d[0]),b=d[1];continue}break}return[c,b]}},many:function(a){return function(b){for(var c=[],d=null;b.length;){try{d=a.call(this,b)}catch(e){return[c,b]}c.push(d[0]),b=d[1]}return[c,b]}},optional:function(a){return function(b){var c=null;try{c=a.call(this,b)}catch(d){return[null,b]}return[c[0],c[1]]}},not:function(b){return function(c){try{b.call(this,c)}catch(d){return[null,c]}throw new a.Exception(c)}},ignore:function(a){return a?function(b){var c=null;return c=a.call(this,b),[null,c[1]]}:null},product:function(){for(var a=arguments[0],c=Array.prototype.slice.call(arguments,1),d=[],e=0;e<a.length;e++)d.push(b.each(a[e],c));return d},cache:function(b){var c={},d=null;return function(e){try{d=c[e]=c[e]||b.call(this,e)}catch(f){d=c[e]=f}if(d instanceof a.Exception)throw d;return d}},any:function(){var b=arguments;return function(c){for(var d=null,e=0;e<b.length;e++)if(null!=b[e]){try{d=b[e].call(this,c)}catch(f){d=null}if(d)return d}throw new a.Exception(c)}},each:function(){var b=arguments;return function(c){for(var d=[],e=null,f=0;f<b.length;f++)if(null!=b[f]){try{e=b[f].call(this,c)}catch(g){throw new a.Exception(c)}d.push(e[0]),c=e[1]}return[d,c]}},all:function(){var a=arguments,b=b;return b.each(b.optional(a))},sequence:function(c,d,e){return d=d||b.rtoken(/^\s*/),e=e||null,1==c.length?c[0]:function(b){for(var f=null,g=null,h=[],i=0;i<c.length;i++){try{f=c[i].call(this,b)}catch(j){break}h.push(f[0]);try{g=d.call(this,f[1])}catch(k){g=null;break}b=g[1]}if(!f)throw new a.Exception(b);if(g)throw new a.Exception(g[1]);if(e)try{f=e.call(this,f[1])}catch(l){throw new a.Exception(f[1])}return[h,f?f[1]:b]}},between:function(a,c,d){d=d||a;var e=b.each(b.ignore(a),c,b.ignore(d));return function(a){var b=e.call(this,a);return[[b[0][0],r[0][2]],b[1]]}},list:function(a,c,d){return c=c||b.rtoken(/^\s*/),d=d||null,a instanceof Array?b.each(b.product(a.slice(0,-1),b.ignore(c)),a.slice(-1),b.ignore(d)):b.each(b.many(b.each(a,b.ignore(c))),px,b.ignore(d))},set:function(c,d,e){return d=d||b.rtoken(/^\s*/),e=e||null,function(f){for(var g=null,h=null,i=null,j=null,k=[[],f],l=!1,m=0;m<c.length;m++){i=null,h=null,g=null,l=1==c.length;try{g=c[m].call(this,f)}catch(n){continue}if(j=[[g[0]],g[1]],g[1].length>0&&!l)try{i=d.call(this,g[1])}catch(o){l=!0}else l=!0;if(l||0!==i[1].length||(l=!0),!l){for(var p=[],q=0;q<c.length;q++)m!=q&&p.push(c[q]);h=b.set(p,d).call(this,i[1]),h[0].length>0&&(j[0]=j[0].concat(h[0]),j[1]=h[1])}if(j[1].length<k[1].length&&(k=j),0===k[1].length)break}if(0===k[0].length)return k;if(e){try{i=e.call(this,k[1])}catch(r){throw new a.Exception(k[1])}k[1]=i[1]}return k}},forward:function(a,b){return function(c){return a[b].call(this,c)}},replace:function(a,b){return function(c){var d=a.call(this,c);return[b,d[1]]}},process:function(a,b){return function(c){var d=a.call(this,c);return[b.call(this,d[0]),d[1]]}},min:function(b,c){return function(d){var e=c.call(this,d);if(e[0].length<b)throw new a.Exception(d);return e}}},c=function(a){return function(){var b=null,c=[];if(arguments.length>1?b=Array.prototype.slice.call(arguments):arguments[0]instanceof Array&&(b=arguments[0]),!b)return a.apply(null,arguments);for(var d=0,e=b.shift();d<e.length;d++)return b.unshift(e[d]),c.push(a.apply(null,b)),b.shift(),c}},d="optional not ignore cache".split(/\s/),e=0;e<d.length;e++)b[d[e]]=c(b[d[e]]);for(var f=function(a){return function(){return arguments[0]instanceof Array?a.apply(null,arguments[0]):a.apply(null,arguments)}},g="each any all".split(/\s/),h=0;h<g.length;h++)b[g[h]]=f(b[g[h]])}(),function(){var a=Date,b=(a.prototype,a.CultureInfo),c=function(a){for(var b=[],d=0;d<a.length;d++)a[d]instanceof Array?b=b.concat(c(a[d])):a[d]&&b.push(a[d]);return b};a.Grammar={},a.Translator={hour:function(a){return function(){this.hour=Number(a)}},minute:function(a){return function(){this.minute=Number(a)}},second:function(a){return function(){this.second=Number(a)}},meridian:function(a){ +return function(){this.meridian=a.slice(0,1).toLowerCase()}},timezone:function(a){return function(){var b=a.replace(/[^\d\+\-]/g,"");b.length?this.timezoneOffset=Number(b):this.timezone=a.toLowerCase()}},day:function(a){var b=a[0];return function(){this.day=Number(b.match(/\d+/)[0])}},month:function(a){return function(){this.month=3==a.length?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(a)/4:Number(a)-1}},year:function(a){return function(){var c=Number(a);this.year=a.length>2?c:c+(c+2e3<b.twoDigitYearMax?2e3:1900)}},rday:function(a){return function(){switch(a){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0,this.now=!0}}},finishExact:function(b){b=b instanceof Array?b:[b];for(var c=0;c<b.length;c++)b[c]&&b[c].call(this);var d=new Date;if(!this.hour&&!this.minute||this.month||this.year||this.day||(this.day=d.getDate()),this.year||(this.year=d.getFullYear()),this.month||0===this.month||(this.month=d.getMonth()),this.day||(this.day=1),this.hour||(this.hour=0),this.minute||(this.minute=0),this.second||(this.second=0),this.meridian&&this.hour&&("p"==this.meridian&&this.hour<12?this.hour=this.hour+12:"a"==this.meridian&&12==this.hour&&(this.hour=0)),this.day>a.getDaysInMonth(this.year,this.month))throw new RangeError(this.day+" is not a valid value for days.");var e=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);return this.timezone?e.set({timezone:this.timezone}):this.timezoneOffset&&e.set({timezoneOffset:this.timezoneOffset}),e},finish:function(b){if(b=b instanceof Array?c(b):[b],0===b.length)return null;for(var d=0;d<b.length;d++)"function"==typeof b[d]&&b[d].call(this);var e=a.today();if(this.now&&!this.unit&&!this.operator)return new Date;this.now&&(e=new Date);var f,g,h,i=!!(this.days&&null!==this.days||this.orient||this.operator);if(h="past"==this.orient||"subtract"==this.operator?-1:1,this.now||-1=="hour minute second".indexOf(this.unit)||e.setTimeToNow(),(this.month||0===this.month)&&-1!="year day hour minute second".indexOf(this.unit)&&(this.value=this.month+1,this.month=null,i=!0),!i&&this.weekday&&!this.day&&!this.days){var j=Date[this.weekday]();this.day=j.getDate(),this.month||(this.month=j.getMonth()),this.year=j.getFullYear()}if(i&&this.weekday&&"month"!=this.unit&&(this.unit="day",f=a.getDayNumberFromName(this.weekday)-e.getDay(),g=7,this.days=f?(f+h*g)%g:h*g),this.month&&"day"==this.unit&&this.operator&&(this.value=this.month+1,this.month=null),null!=this.value&&null!=this.month&&null!=this.year&&(this.day=1*this.value),this.month&&!this.day&&this.value&&(e.set({day:1*this.value}),i||(this.day=1*this.value)),this.month||!this.value||"month"!=this.unit||this.now||(this.month=this.value,i=!0),i&&(this.month||0===this.month)&&"year"!=this.unit&&(this.unit="month",f=this.month-e.getMonth(),g=12,this.months=f?(f+h*g)%g:h*g,this.month=null),this.unit||(this.unit="day"),!this.value&&this.operator&&null!==this.operator&&this[this.unit+"s"]&&null!==this[this.unit+"s"]?this[this.unit+"s"]=this[this.unit+"s"]+("add"==this.operator?1:-1)+(this.value||0)*h:(null==this[this.unit+"s"]||null!=this.operator)&&(this.value||(this.value=1),this[this.unit+"s"]=this.value*h),this.meridian&&this.hour&&("p"==this.meridian&&this.hour<12?this.hour=this.hour+12:"a"==this.meridian&&12==this.hour&&(this.hour=0)),this.weekday&&!this.day&&!this.days){var j=Date[this.weekday]();this.day=j.getDate(),j.getMonth()!==e.getMonth()&&(this.month=j.getMonth())}return!this.month&&0!==this.month||this.day||(this.day=1),this.orient||this.operator||"week"!=this.unit||!this.value||this.day||this.month?(i&&this.timezone&&this.day&&this.days&&(this.day=this.days),i?e.add(this):e.set(this)):Date.today().setWeek(this.value)}};var d,e=a.Parsing.Operators,f=a.Grammar,g=a.Translator;f.datePartDelimiter=e.rtoken(/^([\s\-\.\,\/\x27]+)/),f.timePartDelimiter=e.stoken(":"),f.whiteSpace=e.rtoken(/^\s*/),f.generalDelimiter=e.rtoken(/^(([\s\,]|at|@|on)+)/);var h={};f.ctoken=function(a){var c=h[a];if(!c){for(var d=b.regexPatterns,f=a.split(/\s+/),g=[],i=0;i<f.length;i++)g.push(e.replace(e.rtoken(d[f[i]]),f[i]));c=h[a]=e.any.apply(null,g)}return c},f.ctoken2=function(a){return e.rtoken(b.regexPatterns[a])},f.h=e.cache(e.process(e.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),g.hour)),f.hh=e.cache(e.process(e.rtoken(/^(0[0-9]|1[0-2])/),g.hour)),f.H=e.cache(e.process(e.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),g.hour)),f.HH=e.cache(e.process(e.rtoken(/^([0-1][0-9]|2[0-3])/),g.hour)),f.m=e.cache(e.process(e.rtoken(/^([0-5][0-9]|[0-9])/),g.minute)),f.mm=e.cache(e.process(e.rtoken(/^[0-5][0-9]/),g.minute)),f.s=e.cache(e.process(e.rtoken(/^([0-5][0-9]|[0-9])/),g.second)),f.ss=e.cache(e.process(e.rtoken(/^[0-5][0-9]/),g.second)),f.hms=e.cache(e.sequence([f.H,f.m,f.s],f.timePartDelimiter)),f.t=e.cache(e.process(f.ctoken2("shortMeridian"),g.meridian)),f.tt=e.cache(e.process(f.ctoken2("longMeridian"),g.meridian)),f.z=e.cache(e.process(e.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),g.timezone)),f.zz=e.cache(e.process(e.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),g.timezone)),f.zzz=e.cache(e.process(f.ctoken2("timezone"),g.timezone)),f.timeSuffix=e.each(e.ignore(f.whiteSpace),e.set([f.tt,f.zzz])),f.time=e.each(e.optional(e.ignore(e.stoken("T"))),f.hms,f.timeSuffix),f.d=e.cache(e.process(e.each(e.rtoken(/^([0-2]\d|3[0-1]|\d)/),e.optional(f.ctoken2("ordinalSuffix"))),g.day)),f.dd=e.cache(e.process(e.each(e.rtoken(/^([0-2]\d|3[0-1])/),e.optional(f.ctoken2("ordinalSuffix"))),g.day)),f.ddd=f.dddd=e.cache(e.process(f.ctoken("sun mon tue wed thu fri sat"),function(a){return function(){this.weekday=a}})),f.M=e.cache(e.process(e.rtoken(/^(1[0-2]|0\d|\d)/),g.month)),f.MM=e.cache(e.process(e.rtoken(/^(1[0-2]|0\d)/),g.month)),f.MMM=f.MMMM=e.cache(e.process(f.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),g.month)),f.y=e.cache(e.process(e.rtoken(/^(\d\d?)/),g.year)),f.yy=e.cache(e.process(e.rtoken(/^(\d\d)/),g.year)),f.yyy=e.cache(e.process(e.rtoken(/^(\d\d?\d?\d?)/),g.year)),f.yyyy=e.cache(e.process(e.rtoken(/^(\d\d\d\d)/),g.year)),d=function(){return e.each(e.any.apply(null,arguments),e.not(f.ctoken2("timeContext")))},f.day=d(f.d,f.dd),f.month=d(f.M,f.MMM),f.year=d(f.yyyy,f.yy),f.orientation=e.process(f.ctoken("past future"),function(a){return function(){this.orient=a}}),f.operator=e.process(f.ctoken("add subtract"),function(a){return function(){this.operator=a}}),f.rday=e.process(f.ctoken("yesterday tomorrow today now"),g.rday),f.unit=e.process(f.ctoken("second minute hour day week month year"),function(a){return function(){this.unit=a}}),f.value=e.process(e.rtoken(/^\d\d?(st|nd|rd|th)?/),function(a){return function(){this.value=a.replace(/\D/g,"")}}),f.expression=e.set([f.rday,f.operator,f.value,f.unit,f.orientation,f.ddd,f.MMM]),d=function(){return e.set(arguments,f.datePartDelimiter)},f.mdy=d(f.ddd,f.month,f.day,f.year),f.ymd=d(f.ddd,f.year,f.month,f.day),f.dmy=d(f.ddd,f.day,f.month,f.year),f.date=function(a){return(f[b.dateElementOrder]||f.mdy).call(this,a)},f.format=e.process(e.many(e.any(e.process(e.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(b){if(f[b])return f[b];throw a.Parsing.Exception(b)}),e.process(e.rtoken(/^[^dMyhHmstz]+/),function(a){return e.ignore(e.stoken(a))}))),function(a){return e.process(e.each.apply(null,a),g.finishExact)});var i={},j=function(a){return i[a]=i[a]||f.format(a)[0]};f.formats=function(a){if(a instanceof Array){for(var b=[],c=0;c<a.length;c++)b.push(j(a[c]));return e.any.apply(null,b)}return j(a)},f._formats=f.formats(['"yyyy-MM-ddTHH:mm:ssZ"',"yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-ddTHH:mm:ssz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mmZ","yyyy-MM-ddTHH:mmz","yyyy-MM-ddTHH:mm","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","MMddyyyy","ddMMyyyy","Mddyyyy","ddMyyyy","Mdyyyy","dMyyyy","yyyy","Mdyy","dMyy","d"]),f._start=e.process(e.set([f.date,f.time,f.expression],f.generalDelimiter,f.whiteSpace),g.finish),f.start=function(a){try{var b=f._formats.call({},a);if(0===b[1].length)return b}catch(c){}return f._start.call({},a)},a._parse=a.parse,a.parse=function(b){var c=null;if(!b)return null;if(b instanceof Date)return b;try{c=a.Grammar.start.call({},b.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"))}catch(d){return null}return 0===c[1].length?c[0]:null},a.getParseFunction=function(b){var c=a.Grammar.formats(b);return function(a){var b=null;try{b=c.call({},a)}catch(d){return null}return 0===b[1].length?b[0]:null}},a.parseExact=function(b,c){return a.getParseFunction(c)(b)}}(),function(a,b){function c(a){return l.PF.compile(a||"nplurals=2; plural=(n != 1);")}function d(a,b){this._key=a,this._i18n=b}var e=Array.prototype,f=Object.prototype,g=e.slice,h=f.hasOwnProperty,i=e.forEach,j={},k={forEach:function(a,b,c){var d,e,f;if(null!==a)if(i&&a.forEach===i)a.forEach(b,c);else if(a.length===+a.length){for(d=0,e=a.length;e>d;d++)if(d in a&&b.call(c,a[d],d,a)===j)return}else for(f in a)if(h.call(a,f)&&b.call(c,a[f],f,a)===j)return},extend:function(a){return this.forEach(g.call(arguments,1),function(b){for(var c in b)a[c]=b[c]}),a}},l=function(a){if(this.defaults={locale_data:{messages:{"":{domain:"messages",lang:"en",plural_forms:"nplurals=2; plural=(n != 1);"}}},domain:"messages",debug:!1},this.options=k.extend({},this.defaults,a),this.textdomain(this.options.domain),a.domain&&!this.options.locale_data[this.options.domain])throw new Error("Text domain set to non-existent domain: `"+a.domain+"`")};l.context_delimiter=String.fromCharCode(4),k.extend(d.prototype,{onDomain:function(a){return this._domain=a,this},withContext:function(a){return this._context=a,this},ifPlural:function(a,b){return this._val=a,this._pkey=b,this},fetch:function(a){return"[object Array]"!={}.toString.call(a)&&(a=[].slice.call(arguments,0)),(a&&a.length?l.sprintf:function(a){return a})(this._i18n.dcnpgettext(this._domain,this._context,this._key,this._pkey,this._val),a)}}),k.extend(l.prototype,{translate:function(a){return new d(a,this)},textdomain:function(a){return a?void(this._textdomain=a):this._textdomain},gettext:function(a){return this.dcnpgettext.call(this,b,b,a)},dgettext:function(a,c){return this.dcnpgettext.call(this,a,b,c)},dcgettext:function(a,c){return this.dcnpgettext.call(this,a,b,c)},ngettext:function(a,c,d){return this.dcnpgettext.call(this,b,b,a,c,d)},dngettext:function(a,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},dcngettext:function(a,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},pgettext:function(a,c){return this.dcnpgettext.call(this,b,a,c)},dpgettext:function(a,b,c){return this.dcnpgettext.call(this,a,b,c)},dcpgettext:function(a,b,c){return this.dcnpgettext.call(this,a,b,c)},npgettext:function(a,c,d,e){return this.dcnpgettext.call(this,b,a,c,d,e)},dnpgettext:function(a,b,c,d,e){return this.dcnpgettext.call(this,a,b,c,d,e)},dcnpgettext:function(a,b,d,e,f){e=e||d,a=a||this._textdomain;var g;if(!this.options)return g=new l,g.dcnpgettext.call(g,void 0,void 0,d,e,f);if(!this.options.locale_data)throw new Error("No locale data provided.");if(!this.options.locale_data[a])throw new Error("Domain `"+a+"` was not found.");if(!this.options.locale_data[a][""])throw new Error("No locale meta information provided.");if(!d)throw new Error("No translation key found.");var h,i,j,k=b?b+l.context_delimiter+d:d,m=this.options.locale_data,n=m[a],o=(m.messages||this.defaults.locale_data.messages)[""],p=n[""].plural_forms||n[""]["Plural-Forms"]||n[""]["plural-forms"]||o.plural_forms||o["Plural-Forms"]||o["plural-forms"];if(void 0===f)j=0;else{if("number"!=typeof f&&(f=parseInt(f,10),isNaN(f)))throw new Error("The number that was passed in is not a number.");j=c(p)(f)}if(!n)throw new Error("No domain named `"+a+"` could be found.");return h=n[k],!h||j>h.length?(this.options.missing_key_callback&&this.options.missing_key_callback(k,a),i=[d,e],this.options.debug===!0&&console.log(i[c(p)(f)]),i[c()(f)]):(i=h[j],i?i:(i=[d,e],i[c()(f)]))}});var m=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function b(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")}var c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e,f,g,h,i,j,k,l=1,n=c.length,o="",p=[];for(f=0;n>f;f++)if(o=a(c[f]),"string"===o)p.push(c[f]);else if("array"===o){if(h=c[f],h[2])for(e=d[l],g=0;g<h[2].length;g++){if(!e.hasOwnProperty(h[2][g]))throw m('[sprintf] property "%s" does not exist',h[2][g]);e=e[h[2][g]]}else e=h[1]?d[h[1]]:d[l++];if(/[^s]/.test(h[8])&&"number"!=a(e))throw m("[sprintf] expecting number but found %s",a(e));switch(("undefined"==typeof e||null===e)&&(e=""),h[8]){case"b":e=e.toString(2);break;case"c":e=String.fromCharCode(e);break;case"d":e=parseInt(e,10);break;case"e":e=h[7]?e.toExponential(h[7]):e.toExponential();break;case"f":e=h[7]?parseFloat(e).toFixed(h[7]):parseFloat(e);break;case"o":e=e.toString(8);break;case"s":e=(e=String(e))&&h[7]?e.substring(0,h[7]):e;break;case"u":e=Math.abs(e);break;case"x":e=e.toString(16);break;case"X":e=e.toString(16).toUpperCase()}e=/[def]/.test(h[8])&&h[3]&&e>=0?"+"+e:e,j=h[4]?"0"==h[4]?"0":h[4].charAt(1):" ",k=h[6]-String(e).length,i=h[6]?b(j,k):"",p.push(h[5]?e+i:i+e)}return p.join("")},c.cache={},c.parse=function(a){for(var b=a,c=[],d=[],e=0;b;){if(null!==(c=/^[^\x25]+/.exec(b)))d.push(c[0]);else if(null!==(c=/^\x25{2}/.exec(b)))d.push("%");else{if(null===(c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b)))throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if(null===(h=/^([a-z_][a-z_\d]*)/i.exec(g)))throw"[sprintf] huh?";for(f.push(h[1]);""!==(g=g.substring(h[0].length));)if(null!==(h=/^\.([a-z_][a-z_\d]*)/i.exec(g)))f.push(h[1]);else{if(null===(h=/^\[(\d+)\]/.exec(g)))throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(3===e)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},c}(),n=function(a,b){return b.unshift(a),m.apply(null,b)};l.parse_plural=function(a,b){return a=a.replace(/n/g,b),l.parse_expression(a)},l.sprintf=function(a,b){return"[object Array]"=={}.toString.call(b)?n(a,[].slice.call(b)):m.apply(this,[].slice.call(arguments))},l.prototype.sprintf=function(){return l.sprintf.apply(this,arguments)},l.PF={},l.PF.parse=function(a){var b=l.PF.extractPluralExpr(a);return l.PF.parser.parse.call(l.PF.parser,b)},l.PF.compile=function(a){function b(a){return a===!0?1:a?a:0}var c=l.PF.parse(a);return function(a){return b(l.PF.interpreter(c)(a))}},l.PF.interpreter=function(a){return function(b){switch(a.type){case"GROUP":return l.PF.interpreter(a.expr)(b);case"TERNARY":return l.PF.interpreter(a.expr)(b)?l.PF.interpreter(a.truthy)(b):l.PF.interpreter(a.falsey)(b);case"OR":return l.PF.interpreter(a.left)(b)||l.PF.interpreter(a.right)(b);case"AND":return l.PF.interpreter(a.left)(b)&&l.PF.interpreter(a.right)(b);case"LT":return l.PF.interpreter(a.left)(b)<l.PF.interpreter(a.right)(b);case"GT":return l.PF.interpreter(a.left)(b)>l.PF.interpreter(a.right)(b);case"LTE":return l.PF.interpreter(a.left)(b)<=l.PF.interpreter(a.right)(b);case"GTE":return l.PF.interpreter(a.left)(b)>=l.PF.interpreter(a.right)(b);case"EQ":return l.PF.interpreter(a.left)(b)==l.PF.interpreter(a.right)(b);case"NEQ":return l.PF.interpreter(a.left)(b)!=l.PF.interpreter(a.right)(b);case"MOD":return l.PF.interpreter(a.left)(b)%l.PF.interpreter(a.right)(b);case"VAR":return b;case"NUM":return a.val;default:throw new Error("Invalid Token found.")}}},l.PF.extractPluralExpr=function(a){a=a.replace(/^\s\s*/,"").replace(/\s\s*$/,""),/;\s*$/.test(a)||(a=a.concat(";"));var b,c=/nplurals\=(\d+);/,d=/plural\=(.*);/,e=a.match(c),f={};if(!(e.length>1))throw new Error("nplurals not found in plural_forms string: "+a);if(f.nplurals=e[1],a=a.replace(c,""),b=a.match(d),!(b&&b.length>1))throw new Error("`plural` expression not found: "+a);return b[1]},l.PF.parser=function(){var a={trace:function(){},yy:{},symbols_:{error:2,expressions:3,e:4,EOF:5,"?":6,":":7,"||":8,"&&":9,"<":10,"<=":11,">":12,">=":13,"!=":14,"==":15,"%":16,"(":17,")":18,n:19,NUMBER:20,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",6:"?",7:":",8:"||",9:"&&",10:"<",11:"<=",12:">",13:">=",14:"!=",15:"==",16:"%",17:"(",18:")",19:"n",20:"NUMBER"},productions_:[0,[3,2],[4,5],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,1],[4,1]],performAction:function(a,b,c,d,e,f,g){var h=f.length-1;switch(e){case 1:return{type:"GROUP",expr:f[h-1]};case 2:this.$={type:"TERNARY",expr:f[h-4],truthy:f[h-2],falsey:f[h]};break;case 3:this.$={type:"OR",left:f[h-2],right:f[h]};break;case 4:this.$={type:"AND",left:f[h-2],right:f[h]};break;case 5:this.$={type:"LT",left:f[h-2],right:f[h]};break;case 6:this.$={type:"LTE",left:f[h-2],right:f[h]};break;case 7:this.$={type:"GT",left:f[h-2],right:f[h]};break;case 8:this.$={type:"GTE",left:f[h-2],right:f[h]};break;case 9:this.$={type:"NEQ",left:f[h-2],right:f[h]};break;case 10:this.$={type:"EQ",left:f[h-2],right:f[h]};break;case 11:this.$={type:"MOD",left:f[h-2],right:f[h]};break;case 12:this.$={type:"GROUP",expr:f[h-1]};break;case 13:this.$={type:"VAR"};break;case 14:this.$={type:"NUM",val:Number(a)}}},table:[{3:1,4:2,17:[1,3],19:[1,4],20:[1,5]},{1:[3]},{5:[1,6],6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{4:17,17:[1,3],19:[1,4],20:[1,5]},{5:[2,13],6:[2,13],7:[2,13],8:[2,13],9:[2,13],10:[2,13],11:[2,13],12:[2,13],13:[2,13],14:[2,13],15:[2,13],16:[2,13],18:[2,13]},{5:[2,14],6:[2,14],7:[2,14],8:[2,14],9:[2,14],10:[2,14],11:[2,14],12:[2,14],13:[2,14],14:[2,14],15:[2,14],16:[2,14],18:[2,14]},{1:[2,1]},{4:18,17:[1,3],19:[1,4],20:[1,5]},{4:19,17:[1,3],19:[1,4],20:[1,5]},{4:20,17:[1,3],19:[1,4],20:[1,5]},{4:21,17:[1,3],19:[1,4],20:[1,5]},{4:22,17:[1,3],19:[1,4],20:[1,5]},{4:23,17:[1,3],19:[1,4],20:[1,5]},{4:24,17:[1,3],19:[1,4],20:[1,5]},{4:25,17:[1,3],19:[1,4],20:[1,5]},{4:26,17:[1,3],19:[1,4],20:[1,5]},{4:27,17:[1,3],19:[1,4],20:[1,5]},{6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[1,28]},{6:[1,7],7:[1,29],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{5:[2,3],6:[2,3],7:[2,3],8:[2,3],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,3]},{5:[2,4],6:[2,4],7:[2,4],8:[2,4],9:[2,4],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,4]},{5:[2,5],6:[2,5],7:[2,5],8:[2,5],9:[2,5],10:[2,5],11:[2,5],12:[2,5],13:[2,5],14:[2,5],15:[2,5],16:[1,16],18:[2,5]},{5:[2,6],6:[2,6],7:[2,6],8:[2,6],9:[2,6],10:[2,6],11:[2,6],12:[2,6],13:[2,6],14:[2,6],15:[2,6],16:[1,16],18:[2,6]},{5:[2,7],6:[2,7],7:[2,7],8:[2,7],9:[2,7],10:[2,7],11:[2,7],12:[2,7],13:[2,7],14:[2,7],15:[2,7],16:[1,16],18:[2,7]},{5:[2,8],6:[2,8],7:[2,8],8:[2,8],9:[2,8],10:[2,8],11:[2,8],12:[2,8],13:[2,8],14:[2,8],15:[2,8],16:[1,16],18:[2,8]},{5:[2,9],6:[2,9],7:[2,9],8:[2,9],9:[2,9],10:[2,9],11:[2,9],12:[2,9],13:[2,9],14:[2,9],15:[2,9],16:[1,16],18:[2,9]},{5:[2,10],6:[2,10],7:[2,10],8:[2,10],9:[2,10],10:[2,10],11:[2,10],12:[2,10],13:[2,10],14:[2,10],15:[2,10],16:[1,16],18:[2,10]},{5:[2,11],6:[2,11],7:[2,11],8:[2,11],9:[2,11],10:[2,11],11:[2,11],12:[2,11],13:[2,11],14:[2,11],15:[2,11],16:[2,11],18:[2,11]},{5:[2,12],6:[2,12],7:[2,12],8:[2,12],9:[2,12],10:[2,12],11:[2,12],12:[2,12],13:[2,12],14:[2,12],15:[2,12],16:[2,12],18:[2,12]},{4:30,17:[1,3],19:[1,4],20:[1,5]},{5:[2,2],6:[1,7],7:[2,2],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,2]}],defaultActions:{6:[2,1]},parseError:function(a,b){throw new Error(a)},parse:function(a){function b(a){e.length=e.length-2*a,f.length=f.length-a,g.length=g.length-a}function c(){var a;return a=d.lexer.lex()||1,"number"!=typeof a&&(a=d.symbols_[a]||a),a}var d=this,e=[0],f=[null],g=[],h=this.table,i="",j=0,k=0,l=0,m=2,n=1;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var o=this.lexer.yylloc;g.push(o),"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var p,q,r,s,t,u,v,w,x,y={};;){if(r=e[e.length-1],this.defaultActions[r]?s=this.defaultActions[r]:(null==p&&(p=c()),s=h[r]&&h[r][p]),"undefined"==typeof s||!s.length||!s[0]){if(!l){x=[];for(u in h[r])this.terminals_[u]&&u>2&&x.push("'"+this.terminals_[u]+"'");var z="";z=this.lexer.showPosition?"Parse error on line "+(j+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+x.join(", ")+", got '"+this.terminals_[p]+"'":"Parse error on line "+(j+1)+": Unexpected "+(1==p?"end of input":"'"+(this.terminals_[p]||p)+"'"),this.parseError(z,{text:this.lexer.match,token:this.terminals_[p]||p,line:this.lexer.yylineno,loc:o,expected:x})}if(3==l){if(p==n)throw new Error(z||"Parsing halted.");k=this.lexer.yyleng,i=this.lexer.yytext,j=this.lexer.yylineno,o=this.lexer.yylloc,p=c()}for(;;){if(m.toString()in h[r])break;if(0==r)throw new Error(z||"Parsing halted.");b(1),r=e[e.length-1]}q=p,p=m,r=e[e.length-1],s=h[r]&&h[r][m],l=3}if(s[0]instanceof Array&&s.length>1)throw new Error("Parse Error: multiple actions possible at state: "+r+", token: "+p);switch(s[0]){case 1:e.push(p),f.push(this.lexer.yytext),g.push(this.lexer.yylloc),e.push(s[1]),p=null,q?(p=q,q=null):(k=this.lexer.yyleng,i=this.lexer.yytext,j=this.lexer.yylineno,o=this.lexer.yylloc,l>0&&l--);break;case 2:if(v=this.productions_[s[1]][1],y.$=f[f.length-v],y._$={first_line:g[g.length-(v||1)].first_line,last_line:g[g.length-1].last_line,first_column:g[g.length-(v||1)].first_column,last_column:g[g.length-1].last_column},t=this.performAction.call(y,i,k,j,this.yy,s[1],f,g),"undefined"!=typeof t)return t;v&&(e=e.slice(0,-1*v*2),f=f.slice(0,-1*v),g=g.slice(0,-1*v)),e.push(this.productions_[s[1]][0]),f.push(y.$),g.push(y._$),w=h[e[e.length-2]][e[e.length-1]],e.push(w);break;case 3:return!0}}return!0}},b=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parseError)throw new Error(a);this.yy.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.match+=a,this.matched+=a;var b=a.match(/\n/);return b&&this.yylineno++,this._input=this._input.slice(1),a},unput:function(a){return this._input=a+this._input,this},more:function(){return this._more=!0,this},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c;this._more||(this.yytext="",this.match="");for(var d=this._currentRules(),e=0;e<d.length;e++)if(b=this._input.match(this.rules[d[e]]))return c=b[0].match(/\n.*/g),c&&(this.yylineno+=c.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:c?c[c.length-1].length-1:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,d[e],this.conditionStack[this.conditionStack.length-1]),a?a:void 0;return""===this._input?this.EOF:void this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.performAction=function(a,b,c,d){switch(c){case 0:break;case 1:return 20;case 2:return 19;case 3:return 8;case 4:return 9;case 5:return 6;case 6:return 7;case 7:return 11;case 8:return 13;case 9:return 10;case 10:return 12;case 11:return 14;case 12:return 15;case 13:return 16;case 14:return 17;case 15:return 18;case 16:return 5;case 17:return"INVALID"}},a.rules=[/^\s+/,/^[0-9]+(\.[0-9]+)?\b/,/^n\b/,/^\|\|/,/^&&/,/^\?/,/^:/,/^<=/,/^>=/,/^</,/^>/,/^!=/,/^==/,/^%/,/^\(/,/^\)/,/^$/,/^./],a.conditions={INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],inclusive:!0}},a}();return a.lexer=b,a}(),"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=l),exports.Jed=l):("function"==typeof define&&define.amd&&define(function(){return l}),a.Jed=l)}(this),function(a){function b(a){return{jsonrpc:"2.0",method:a.method||"",params:a.params||{},id:g++}}function c(c){var d=a.isArray(c)?c.map(b):b(c);return JSON.stringify(d)}function d(a){return a.sort(e)}function e(a,b){return a.id<b.id?-1:1}function f(b,e){var f=new a.Deferred;e=e||{};var g=e.success||h,i=e.error||h;delete e.success,delete e.error;var j=a.isArray(b),k=a.extend({url:(j?b[0].url:b.url)||a.jsonrpc.defaultUrl,contentType:"application/json",dataType:"text",dataFilter:function(a,b){return JSON.parse(a)},type:"POST",processData:!1,data:c(b),success:function(a){if(j){var b=d(a);return g(b),void f.resolve(b)}if(a.hasOwnProperty("error"))return i(a.error),void f.reject(a.error);if(a.hasOwnProperty("result"))return g(a.result),void f.resolve(a.result);throw"Invalid response returned"},error:function(a,b,c){var d=null;if("timeout"===c)d={status:b,code:-32e3,message:"Request Timeout",data:null};else try{var e=JSON.parse(a.responseText);d=e.error}catch(g){d={status:b,code:-32603,message:c,data:a.responseText}}i(d),f.reject(d)}},e);return a.ajax(k),f.promise()}var g=1,h=function(){};a.extend({jsonrpc:f}),a.jsonrpc.defaultUrl="/jsonrpc"}(jQuery),!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document),function(a){"use strict";function b(a,b){return Math.round(a/b)*b}function c(a){return"number"==typeof a&&!isNaN(a)&&isFinite(a)}function d(a){var b=Math.pow(10,7);return Number((Math.round(a*b)/b).toFixed(7))}function e(a,b,c){a.addClass(b),setTimeout(function(){a.removeClass(b)},c)}function f(a){return Math.max(Math.min(a,100),0)}function g(b){return a.isArray(b)?b:[b]}function h(a){var b=a.split(".");return b.length>1?b[1].length:0}function i(a,b){return 100/(b-a)}function j(a,b){return 100*b/(a[1]-a[0])}function k(a,b){return j(a,a[0]<0?b+Math.abs(a[0]):b-a[0])}function l(a,b){return b*(a[1]-a[0])/100+a[0]}function m(a,b){for(var c=1;a>=b[c];)c+=1;return c}function n(a,b,c){if(c>=a.slice(-1)[0])return 100;var d,e,f,g,h=m(c,a);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],f+k([d,e],c)/i(f,g)}function o(a,b,c){if(c>=100)return a.slice(-1)[0];var d,e,f,g,h=m(c,b);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],l([d,e],(c-f)*i(f,g))}function p(a,c,d,e){if(100===e)return e;var f,g,h=m(e,a);return d?(f=a[h-1],g=a[h],e-f>(g-f)/2?g:f):c[h-1]?a[h-1]+b(e-a[h-1],c[h-1]):e}function q(a,b,d){var e;if("number"==typeof b&&(b=[b]),"[object Array]"!==Object.prototype.toString.call(b))throw new Error("noUiSlider: 'range' contains invalid value.");if(e="min"===a?0:"max"===a?100:parseFloat(a),!c(e)||!c(b[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");d.xPct.push(e),d.xVal.push(b[0]),e?d.xSteps.push(isNaN(b[1])?!1:b[1]):isNaN(b[1])||(d.xSteps[0]=b[1])}function r(a,b,c){return b?void(c.xSteps[a]=j([c.xVal[a],c.xVal[a+1]],b)/i(c.xPct[a],c.xPct[a+1])):!0}function s(a,b,c,d){this.xPct=[],this.xVal=[],this.xSteps=[d||!1],this.xNumSteps=[!1],this.snap=b,this.direction=c;var e,f=[];for(e in a)a.hasOwnProperty(e)&&f.push([a[e],e]);for(f.sort(function(a,b){return a[0]-b[0]}),e=0;e<f.length;e++)q(f[e][1],f[e][0],this);for(this.xNumSteps=this.xSteps.slice(0),e=0;e<this.xNumSteps.length;e++)r(e,this.xNumSteps[e],this)}function t(a,b){if(!c(b))throw new Error("noUiSlider: 'step' is not numeric.");a.singleStep=b}function u(b,c){if("object"!=typeof c||a.isArray(c))throw new Error("noUiSlider: 'range' is not an object.");if(void 0===c.min||void 0===c.max)throw new Error("noUiSlider: Missing 'min' or 'max' in 'range'.");b.spectrum=new s(c,b.snap,b.dir,b.singleStep)}function v(b,c){if(c=g(c),!a.isArray(c)||!c.length||c.length>2)throw new Error("noUiSlider: 'start' option is incorrect."); +b.handles=c.length,b.start=c}function w(a,b){if(a.snap=b,"boolean"!=typeof b)throw new Error("noUiSlider: 'snap' option must be a boolean.")}function x(a,b){if(a.animate=b,"boolean"!=typeof b)throw new Error("noUiSlider: 'animate' option must be a boolean.")}function y(a,b){if("lower"===b&&1===a.handles)a.connect=1;else if("upper"===b&&1===a.handles)a.connect=2;else if(b===!0&&2===a.handles)a.connect=3;else{if(b!==!1)throw new Error("noUiSlider: 'connect' option doesn't match handle count.");a.connect=0}}function z(a,b){switch(b){case"horizontal":a.ort=0;break;case"vertical":a.ort=1;break;default:throw new Error("noUiSlider: 'orientation' option is invalid.")}}function A(a,b){if(!c(b))throw new Error("noUiSlider: 'margin' option must be numeric.");if(a.margin=a.spectrum.getMargin(b),!a.margin)throw new Error("noUiSlider: 'margin' option is only supported on linear sliders.")}function B(a,b){if(!c(b))throw new Error("noUiSlider: 'limit' option must be numeric.");if(a.limit=a.spectrum.getMargin(b),!a.limit)throw new Error("noUiSlider: 'limit' option is only supported on linear sliders.")}function C(a,b){switch(b){case"ltr":a.dir=0;break;case"rtl":a.dir=1,a.connect=[0,2,1,3][a.connect];break;default:throw new Error("noUiSlider: 'direction' option was not recognized.")}}function D(a,b){if("string"!=typeof b)throw new Error("noUiSlider: 'behaviour' must be a string containing options.");var c=b.indexOf("tap")>=0,d=b.indexOf("drag")>=0,e=b.indexOf("fixed")>=0,f=b.indexOf("snap")>=0;a.events={tap:c||f,drag:d,fixed:e,snap:f}}function E(a,b){if(a.format=b,"function"==typeof b.to&&"function"==typeof b.from)return!0;throw new Error("noUiSlider: 'format' requires 'to' and 'from' methods.")}function F(b){var c,d={margin:0,limit:0,animate:!0,format:V};return c={step:{r:!1,t:t},start:{r:!0,t:v},connect:{r:!0,t:y},direction:{r:!0,t:C},snap:{r:!1,t:w},animate:{r:!1,t:x},range:{r:!0,t:u},orientation:{r:!1,t:z},margin:{r:!1,t:A},limit:{r:!1,t:B},behaviour:{r:!0,t:D},format:{r:!1,t:E}},b=a.extend({connect:!1,direction:"ltr",behaviour:"tap",orientation:"horizontal"},b),a.each(c,function(a,c){if(void 0===b[a]){if(c.r)throw new Error("noUiSlider: '"+a+"' is required.");return!0}c.t(d,b[a])}),d.style=d.ort?"top":"left",d}function G(a,b,c){var d=a+b[0],e=a+b[1];return c?(0>d&&(e+=Math.abs(d)),e>100&&(d-=e-100),[f(d),f(e)]):[d,e]}function H(a){a.preventDefault();var b,c,d=0===a.type.indexOf("touch"),e=0===a.type.indexOf("mouse"),f=0===a.type.indexOf("pointer"),g=a;return 0===a.type.indexOf("MSPointer")&&(f=!0),a.originalEvent&&(a=a.originalEvent),d&&(b=a.changedTouches[0].pageX,c=a.changedTouches[0].pageY),(e||f)&&(f||void 0!==window.pageXOffset||(window.pageXOffset=document.documentElement.scrollLeft,window.pageYOffset=document.documentElement.scrollTop),b=a.clientX+window.pageXOffset,c=a.clientY+window.pageYOffset),g.points=[b,c],g.cursor=e,g}function I(b,c){var d=a("<div><div/></div>").addClass(U[2]),e=["-lower","-upper"];return b&&e.reverse(),d.children().addClass(U[3]+" "+U[3]+e[c]),d}function J(a,b,c){switch(a){case 1:b.addClass(U[7]),c[0].addClass(U[6]);break;case 3:c[1].addClass(U[6]);case 2:c[0].addClass(U[7]);case 0:b.addClass(U[6])}}function K(a,b,c){var d,e=[];for(d=0;a>d;d+=1)e.push(I(b,d).appendTo(c));return e}function L(b,c,d){return d.addClass([U[0],U[8+b],U[4+c]].join(" ")),a("<div/>").appendTo(d).addClass(U[1])}function M(b,c,d){function i(){return C[["width","height"][c.ort]]()}function j(a){var b,c=[E.val()];for(b=0;b<a.length;b+=1)E.trigger(a[b],c)}function k(a){return 1===a.length?a[0]:c.dir?a.reverse():a}function l(a){return function(b,c){E.val([a?null:c,a?c:null],!0)}}function m(b){var c=a.inArray(b,N);E[0].linkAPI&&E[0].linkAPI[b]&&E[0].linkAPI[b].change(M[c],D[c].children(),E)}function n(b,d){var e=a.inArray(b,N);return d&&d.appendTo(D[e].children()),c.dir&&c.handles>1&&(e=1===e?0:1),l(e)}function o(){var a,b;for(a=0;a<N.length;a+=1)this.linkAPI&&this.linkAPI[b=N[a]]&&this.linkAPI[b].reconfirm(b)}function p(a,b,d,e){return a=a.replace(/\s/g,S+" ")+S,b.on(a,function(a){return E.attr("disabled")?!1:E.hasClass(U[14])?!1:(a=H(a),a.calcPoint=a.points[c.ort],void d(a,e))})}function q(a,b){var c,d=b.handles||D,e=!1,f=100*(a.calcPoint-b.start)/i(),g=d[0][0]!==D[0][0]?1:0;c=G(f,b.positions,d.length>1),e=v(d[0],c[g],1===d.length),d.length>1&&(e=v(d[1],c[g?0:1],!1)||e),e&&j(["slide"])}function r(b){a("."+U[15]).removeClass(U[15]),b.cursor&&a("body").css("cursor","").off(S),Q.off(S),E.removeClass(U[12]),j(["set","change"])}function s(b,c){1===c.handles.length&&c.handles[0].children().addClass(U[15]),b.stopPropagation(),p(T.move,Q,q,{start:b.calcPoint,handles:c.handles,positions:[F[0],F[D.length-1]]}),p(T.end,Q,r,null),b.cursor&&(a("body").css("cursor",a(b.target).css("cursor")),D.length>1&&E.addClass(U[12]),a("body").on("selectstart"+S,!1))}function t(b){var d,f=b.calcPoint,g=0;b.stopPropagation(),a.each(D,function(){g+=this.offset()[c.style]}),g=g/2>f||1===D.length?0:1,f-=C.offset()[c.style],d=100*f/i(),c.events.snap||e(E,U[14],300),v(D[g],d),j(["slide","set","change"]),c.events.snap&&s(b,{handles:[D[g]]})}function u(a){var b,c;if(!a.fixed)for(b=0;b<D.length;b+=1)p(T.start,D[b].children(),s,{handles:[D[b]]});a.tap&&p(T.start,C,t,{handles:D}),a.drag&&(c=C.find("."+U[7]).addClass(U[10]),a.fixed&&(c=c.add(C.children().not(c).children())),p(T.start,c,s,{handles:D}))}function v(a,b,d){var e=a[0]!==D[0][0]?1:0,g=F[0]+c.margin,h=F[1]-c.margin,i=F[0]+c.limit,j=F[1]-c.limit;return D.length>1&&(b=e?Math.max(b,g):Math.min(b,h)),d!==!1&&c.limit&&D.length>1&&(b=e?Math.min(b,i):Math.max(b,j)),b=I.getStep(b),b=f(parseFloat(b.toFixed(7))),b===F[e]?!1:(a.css(c.style,b+"%"),a.is(":first-child")&&a.toggleClass(U[17],b>50),F[e]=b,M[e]=I.fromStepping(b),m(N[e]),!0)}function w(a,b){var d,e,f;for(c.limit&&(a+=1),d=0;a>d;d+=1)e=d%2,f=b[e],null!==f&&f!==!1&&("number"==typeof f&&(f=String(f)),f=c.format.from(f),(f===!1||isNaN(f)||v(D[e],I.toStepping(f),d===3-c.dir)===!1)&&m(N[e]))}function x(a){if(E[0].LinkIsEmitting)return this;var b,d=g(a);return c.dir&&c.handles>1&&d.reverse(),c.animate&&-1!==F[0]&&e(E,U[14],300),b=D.length>1?3:1,1===d.length&&(b=1),w(b,d),j(["set"]),this}function y(){var a,b=[];for(a=0;a<c.handles;a+=1)b[a]=c.format.to(M[a]);return k(b)}function z(){return a(this).off(S).removeClass(U.join(" ")).empty(),delete this.LinkUpdate,delete this.LinkConfirm,delete this.LinkDefaultFormatter,delete this.LinkDefaultFlag,delete this.reappend,delete this.vGet,delete this.vSet,delete this.getCurrentStep,delete this.getInfo,delete this.destroy,d}function A(){var b=a.map(F,function(a,b){var c=I.getApplicableStep(a),d=h(String(c[2])),e=M[b],f=100===a?null:c[2],g=Number((e-c[2]).toFixed(d)),i=0===a?null:g>=c[1]?c[2]:c[0]||!1;return[[i,f]]});return k(b)}function B(){return d}var C,D,E=a(b),F=[-1,-1],I=c.spectrum,M=[],N=["lower","upper"].slice(0,c.handles);if(c.dir&&N.reverse(),b.LinkUpdate=m,b.LinkConfirm=n,b.LinkDefaultFormatter=c.format,b.LinkDefaultFlag="lower",b.reappend=o,E.hasClass(U[0]))throw new Error("Slider was already initialized.");C=L(c.dir,c.ort,E),D=K(c.handles,c.dir,C),J(c.connect,E,D),u(c.events),b.vSet=x,b.vGet=y,b.destroy=z,b.getCurrentStep=A,b.getOriginalOptions=B,b.getInfo=function(){return[I,c.style,c.ort]},E.val(c.start)}function N(a){var b=F(a,this);return this.each(function(){M(this,b,a)})}function O(b){return this.each(function(){if(!this.destroy)return void a(this).noUiSlider(b);var c=a(this).val(),d=this.destroy(),e=a.extend({},d,b);a(this).noUiSlider(e),this.reappend(),d.start===e.start&&a(this).val(c)})}function P(){return this[0][arguments.length?"vSet":"vGet"].apply(this[0],arguments)}var Q=a(document),R=a.fn.val,S=".nui",T=window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"},U=["noUi-target","noUi-base","noUi-origin","noUi-handle","noUi-horizontal","noUi-vertical","noUi-background","noUi-connect","noUi-ltr","noUi-rtl","noUi-dragable","","noUi-state-drag","","noUi-state-tap","noUi-active","","noUi-stacking"];s.prototype.getMargin=function(a){return 2===this.xPct.length?j(this.xVal,a):!1},s.prototype.toStepping=function(a){return a=n(this.xVal,this.xPct,a),this.direction&&(a=100-a),a},s.prototype.fromStepping=function(a){return this.direction&&(a=100-a),d(o(this.xVal,this.xPct,a))},s.prototype.getStep=function(a){return this.direction&&(a=100-a),a=p(this.xPct,this.xSteps,this.snap,a),this.direction&&(a=100-a),a},s.prototype.getApplicableStep=function(a){var b=m(a,this.xPct),c=100===a?2:1;return[this.xNumSteps[b-2],this.xVal[b-c],this.xNumSteps[b-c]]},s.prototype.convert=function(a){return this.getStep(this.toStepping(a))};var V={to:function(a){return a.toFixed(2)},from:Number};a.fn.val=function(b){function c(a){return a.hasClass(U[0])?P:R}if(!arguments.length){var d=a(this[0]);return c(d).call(d)}var e=a.isFunction(b);return this.each(function(d){var f=b,g=a(this);e&&(f=b.call(this,d,g.val())),c(g).call(g,f)})},a.fn.noUiSlider=function(a,b){switch(a){case"step":return this[0].getCurrentStep();case"options":return this[0].getOriginalOptions()}return(b?O:N).call(this,a)}}(window.jQuery||window.Zepto),function(a){"use strict";"object"==typeof exports?a(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b=function(a){if(a=a||"once","string"!=typeof a)throw new Error("The jQuery Once id parameter must be a string");return a};a.fn.once=function(c){var d="jquery-once-"+b(c);return this.filter(function(){return a(this).data(d)!==!0}).data(d,!0)},a.fn.removeOnce=function(a){return this.findOnce(a).removeData("jquery-once-"+b(a))},a.fn.findOnce=function(c){var d="jquery-once-"+b(c);return this.filter(function(){return a(this).data(d)===!0})}}),function(a){var b=a(window);a.fn.visible=function(a,c,d){if(!(this.length<1)){var e=this.length>1?this.eq(0):this,f=e.get(0),g=b.width(),h=b.height(),d=d?d:"both",i=c===!0?f.offsetWidth*f.offsetHeight:!0;if("function"==typeof f.getBoundingClientRect){var j=f.getBoundingClientRect(),k=j.top>=0&&j.top<h,l=j.bottom>0&&j.bottom<=h,m=j.left>=0&&j.left<g,n=j.right>0&&j.right<=g,o=a?k||l:k&&l,p=a?m||n:m&&n;if("both"===d)return i&&o&&p;if("vertical"===d)return i&&o;if("horizontal"===d)return i&&p}else{var q=b.scrollTop(),r=q+h,s=b.scrollLeft(),t=s+g,u=e.offset(),v=u.top,w=v+e.height(),x=u.left,y=x+e.width(),z=a===!0?w:v,A=a===!0?v:w,B=a===!0?y:x,C=a===!0?x:y;if("both"===d)return!!i&&r>=A&&z>=q&&t>=C&&B>=s;if("vertical"===d)return!!i&&r>=A&&z>=q;if("horizontal"===d)return!!i&&t>=C&&B>=s}}}}(jQuery),window.JST||(window.JST={});var prettyPrint=function(){var a={el:function(b,c){var d,e=document.createElement(b);if(c=a.merge({},c),c&&c.style){c.style;a.applyCSS(e,c.style),delete c.style}for(d in c)c.hasOwnProperty(d)&&(e[d]=c[d]);return e},applyCSS:function(a,b){for(var c in b)if(b.hasOwnProperty(c))try{a.style[c]=b[c]}catch(d){}},txt:function(a){return document.createTextNode(a)},row:function(b,c,d){d=d||"td";var e,f=a.count(b,null)+1,g=a.el("tr"),h={style:a.getStyles(d,c),colSpan:f,onmouseover:function(){var b=this.parentNode.childNodes;a.forEach(b,function(b){"td"===b.nodeName.toLowerCase()&&a.applyCSS(b,a.getStyles("td_hover",c))})},onmouseout:function(){var b=this.parentNode.childNodes;a.forEach(b,function(b){"td"===b.nodeName.toLowerCase()&&a.applyCSS(b,a.getStyles("td",c))})}};return a.forEach(b,function(b){null!==b&&(e=a.el(d,h),b.nodeType?e.appendChild(b):e.innerHTML=a.shorten(b.toString()),g.appendChild(e))}),g},hRow:function(b,c){return a.row(b,c,"th")},table:function(b,c){b=b||[];var d={thead:{style:a.getStyles("thead",c)},tbody:{style:a.getStyles("tbody",c)},table:{style:a.getStyles("table",c)}},e=a.el("table",d.table),f=a.el("thead",d.thead),g=a.el("tbody",d.tbody);return b.length&&(e.appendChild(f),f.appendChild(a.hRow(b,c))),e.appendChild(g),{node:e,tbody:g,thead:f,appendChild:function(a){this.tbody.appendChild(a)},addRow:function(b,d,e){return this.appendChild(a.row.call(a,b,d||c,e)),this}}},shorten:function(a){return a},htmlentities:function(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")},merge:function(b,c){"object"!=typeof b&&(b={});for(var d in c)if(c.hasOwnProperty(d)){var e=c[d];if("object"==typeof e){b[d]=a.merge(b[d],e);continue}b[d]=e}for(var f=2,g=arguments.length;g>f;f++)a.merge(b,arguments[f]);return b},count:function(a,b){for(var c=0,d=0,e=a.length;e>d;d++)a[d]===b&&c++;return c},thead:function(a){return a.getElementsByTagName("thead")[0]},forEach:function(a,b,c){c||(c=b);for(var d=a.length,e=-1;++e<d&&c(a[e],e,a)!==!1;);return!0},type:function(a){try{if(null===a)return"null";if(void 0===a)return"undefined";var b=Object.prototype.toString.call(a).match(/\s(.+?)\]/)[1].toLowerCase();return a.nodeType?1===a.nodeType?"domelement":"domnode":/^(string|number|array|regexp|function|date|boolean)$/.test(b)?b:"object"==typeof a?a.jquery&&"string"==typeof a.jquery?"jquery":"object":a===window||a===document?"object":"default"}catch(c){return"default"}},within:function(a){return{is:function(b){for(var c in a)if(a[c]===b)return c;return""}}},common:{circRef:function(c,d,e){return a.expander("[POINTS BACK TO <strong>"+d+"</strong>]","Click to show this item anyway",function(){this.parentNode.appendChild(b(c,{maxDepth:1}))})},depthReached:function(c,d){return a.expander("[DEPTH REACHED]","Click to show this item anyway",function(){try{this.parentNode.appendChild(b(c,{maxDepth:1}))}catch(d){this.parentNode.appendChild(a.table(["ERROR OCCURED DURING OBJECT RETRIEVAL"],"error").addRow([d.message]).node)}})}},getStyles:function(c,d){return d=b.settings.styles[d]||{},a.merge({},b.settings.styles["default"][c],d[c])},expander:function(b,c,d){return a.el("a",{innerHTML:a.shorten(b)+' <b style="visibility:hidden;">[+]</b>',title:c,onmouseover:function(){this.getElementsByTagName("b")[0].style.visibility="visible"},onmouseout:function(){this.getElementsByTagName("b")[0].style.visibility="hidden"},onclick:function(){return this.style.display="none",d.call(this),!1},style:{cursor:"pointer"}})},stringify:function(b){var c,d=a.type(b),e=!0;if("array"===d)return c="[",a.forEach(b,function(b,d){c+=(0===d?"":", ")+a.stringify(b)}),c+"]";if("object"==typeof b){c="{";for(var f in b)b.hasOwnProperty(f)&&(c+=(e?"":", ")+f+":"+a.stringify(b[f]),e=!1);return c+"}"}return"regexp"===d?"/"+b.source+"/":"string"===d?'"'+b.replace(/"/g,'\\"')+'"':b.toString()},headerGradient:function(){var a=document.createElement("canvas");if(!a.getContext)return"";var b=a.getContext("2d");a.height=30,a.width=1;var c=b.createLinearGradient(0,0,0,30);c.addColorStop(0,"rgba(0,0,0,0)"),c.addColorStop(1,"rgba(0,0,0,0.25)"),b.fillStyle=c,b.fillRect(0,0,1,30);var d=a.toDataURL&&a.toDataURL();return"url("+(d||"")+")"}()},b=function(c,d){d=d||{};var e=a.merge({},b.config,d),f=a.el("div"),g=(b.config,0),h={},i=!1;b.settings=e;var j={string:function(b){return a.txt('"'+a.shorten(b.replace(/"/g,'\\"'))+'"')},number:function(b){return a.txt(b)},regexp:function(b){var c=a.table(["RegExp",null],"regexp"),d=a.table(),f=a.expander("/"+b.source+"/","Click to show more",function(){this.parentNode.appendChild(c.node)});return d.addRow(["g",b.global]).addRow(["i",b.ignoreCase]).addRow(["m",b.multiline]),c.addRow(["source","/"+b.source+"/"]).addRow(["flags",d.node]).addRow(["lastIndex",b.lastIndex]),e.expanded?c.node:f},domelement:function(b,c){var d=a.table(["DOMElement",null],"domelement"),f=["id","className","innerHTML","src","href"],g=b.nodeName||"";return d.addRow(["tag","<"+g.toLowerCase()+">"]),a.forEach(f,function(c){b[c]&&d.addRow([c,a.htmlentities(b[c])])}),e.expanded?d.node:a.expander("DOMElement ("+g.toLowerCase()+")","Click to show more",function(){this.parentNode.appendChild(d.node)})},domnode:function(b){var c=a.table(["DOMNode",null],"domelement"),d=a.htmlentities((b.data||"UNDEFINED").replace(/\n/g,"\\n"));return c.addRow(["nodeType",b.nodeType+" ("+b.nodeName+")"]).addRow(["data",d]),e.expanded?c.node:a.expander("DOMNode","Click to show more",function(){this.parentNode.appendChild(c.node)})},jquery:function(a,b,c){return j.array(a,b,c,!0)},object:function(b,c,d){var f=a.within(h).is(b);if(f)return a.common.circRef(b,f,e);if(h[d||"TOP"]=b,c===e.maxDepth)return a.common.depthReached(b,e);var g=a.table(["Object",null],"object"),k=!0;for(var l in b)if(!b.hasOwnProperty||b.hasOwnProperty(l)){var m=b[l],n=a.type(m);k=!1;try{g.addRow([l,j[n](m,c+1,l)],n)}catch(o){window.console&&window.console.log&&console.log(o.message)}}k?g.addRow(["<small>[empty]</small>"]):g.thead.appendChild(a.hRow(["key","value"],"colHeader"));var p=e.expanded||i?g.node:a.expander(a.stringify(b),"Click to show more",function(){this.parentNode.appendChild(g.node)});return i=!0,p},array:function(b,c,d,f){var g=a.within(h).is(b);if(g)return a.common.circRef(b,g);if(h[d||"TOP"]=b,c===e.maxDepth)return a.common.depthReached(b);var i=f?"jQuery":"Array",k=a.table([i+"("+b.length+")",null],f?"jquery":i.toLowerCase()),l=!0,m=0;return f&&k.addRow(["selector",b.selector]),a.forEach(b,function(d,f){return e.maxArray>=0&&++m>e.maxArray?(k.addRow([f+".."+(b.length-1),j[a.type(d)]("...",c+1,f)]),!1):(l=!1,void k.addRow([f,j[a.type(d)](d,c+1,f)]))}),f||(l?k.addRow(["<small>[empty]</small>"]):k.thead.appendChild(a.hRow(["index","value"],"colHeader"))),e.expanded?k.node:a.expander(a.stringify(b),"Click to show more",function(){this.parentNode.appendChild(k.node)})},"function":function(b,c,d){var f=a.within(h).is(b);if(f)return a.common.circRef(b,f);h[d||"TOP"]=b;var g=a.table(["Function",null],"function"),i=(a.table(["Arguments"]),b.toString().match(/\((.+?)\)/)),j=b.toString().match(/\(.*?\)\s+?\{?([\S\s]+)/)[1].replace(/\}?$/,"");return g.addRow(["arguments",i?i[1].replace(/[^\w_,\s]/g,""):"<small>[none/native]</small>"]).addRow(["body",j]),e.expanded?g.node:a.expander("function(){...}","Click to see more about this function.",function(){this.parentNode.appendChild(g.node)})},date:function(b){var c=a.table(["Date",null],"date"),d=b.toString().split(/\s/);return c.addRow(["Time",d[4]]).addRow(["Date",d.slice(0,4).join("-")]),e.expanded?c.node:a.expander("Date (timestamp): "+ +b,"Click to see a little more info about this date",function(){this.parentNode.appendChild(c.node)})},"boolean":function(b){return a.txt(b.toString().toUpperCase())},undefined:function(){return a.txt("UNDEFINED")},"null":function(){return a.txt("NULL")},"default":function(){return a.txt("prettyPrint: TypeNotFound Error")}};return f.appendChild(j[e.forceObject?"object":a.type(c)](c,g)),f};return b.config={expanded:!0,forceObject:!1,maxDepth:3,maxArray:-1,styles:{array:{th:{backgroundColor:"#A4C18B",color:"white"}},"function":{th:{backgroundColor:"#D82525"}},regexp:{th:{backgroundColor:"#E2F3FB",color:"#000"}},object:{th:{backgroundColor:"#8DA3AD"}},jquery:{th:{backgroundColor:"#FBF315"}},error:{th:{backgroundColor:"red",color:"yellow"}},domelement:{th:{backgroundColor:"#F3801E"}},date:{th:{backgroundColor:"#A725D8"}},colHeader:{th:{backgroundColor:"#EEE",color:"#aaa",textTransform:"uppercase",fontSize:"80%",padding:"2px 5px"}},"default":{table:{borderCollapse:"collapse",width:"100%"},td:{padding:"5px",fontSize:"12px",backgroundColor:"rgba(255,255,255,0.5)",color:"#222",border:"1px solid #ddd",verticalAlign:"top",fontFamily:'"Consolas","Lucida Console",Courier,mono',whiteSpace:"nowrap"},td_hover:{},th:{padding:"5px",fontSize:"12px",backgroundColor:"#222",color:"#EEE",textAlign:"left",border:"1px solid #ddd",verticalAlign:"top",fontFamily:'"Consolas","Lucida Console",Courier,mono',backgroundRepeat:"repeat-x"}}}},b}();!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){this.el=a,this.options=b=b||{};var d={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1};for(var e in d)!(e in b)&&(b[e]=d[e]);var g=b.group;g&&"object"==typeof g||(g=b.group={name:g}),["pull","put"].forEach(function(a){a in g||(g[a]=!0)}),M.forEach(function(d){b[d]=c(this,b[d]||N),f(a,d.substr(2).toLowerCase(),b[d])},this),b.groups=" "+g.name+(g.put.join?" "+g.put.join(" "):"")+" ",a[F]=b;for(var h in this)"_"===h.charAt(0)&&(this[h]=c(this,this[h]));f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),f(a,"dragover",this),f(a,"dragenter",this),Q.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){s&&s.state!==a&&(i(s,"display",a?"none":""),!a&&s.state&&t.insertBefore(s,q),s.state=a)}function c(a,b){var c=P.call(arguments,2);return b.bind?b.bind.apply(b,[a].concat(c)):function(){return b.apply(a,c.concat(P.call(arguments)))}}function d(a,b,c){if(a){c=c||H,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")\\s","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function e(a){a.dataTransfer.dropEffect="move",a.preventDefault()}function f(a,b,c){a.addEventListener(b,c,!1)}function g(a,b,c){a.removeEventListener(b,c,!1)}function h(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(/\s+/g," ").replace(" "+b+" ","");a.className=d+(c?" "+b:"")}}function i(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return H.defaultView&&H.defaultView.getComputedStyle?c=H.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function j(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function k(a){a.draggable=!1}function l(){K=!1}function m(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return b.clientY-(d.top+d.height)>5&&c}function n(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function o(a){for(var b=0;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function p(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E={},F="Sortable"+(new Date).getTime(),G=window,H=G.document,I=G.parseInt,J=!!("draggable"in H.createElement("div")),K=!1,L=function(a,b,c,d,e,f){var g=H.createEvent("Event");g.initEvent(b,!0,!0),g.item=c||a,g.from=d||a,g.clone=s,g.oldIndex=e,g.newIndex=f,a.dispatchEvent(g)},M="onAdd onUpdate onRemove onStart onEnd onFilter onSort".split(" "),N=function(){},O=Math.abs,P=[].slice,Q=[],R=p(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(w!==c&&(v=b.scroll,w=c,v===!0)){v=c;do if(v.offsetWidth<v.scrollWidth||v.offsetHeight<v.scrollHeight)break;while(v=v.parentNode)}v&&(d=v,e=v.getBoundingClientRect(),f=(O(e.right-j)<=h)-(O(e.left-j)<=h),g=(O(e.bottom-k)<=h)-(O(e.top-k)<=h)),f||g||(f=(h>=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=G)),(E.vx!==f||E.vy!==g||E.el!==d)&&(E.el=d,E.vx=f,E.vy=g,clearInterval(E.pid),d&&(E.pid=setInterval(function(){d===G?G.scrollTo(G.scrollX+f*i,G.scrollY+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30);return a.prototype={constructor:a,_dragStarted:function(){t&&q&&(h(q,this.options.ghostClass,!0),a.active=this,L(t,"start",q,t,z))},_onTapStart:function(a){var b=a.type,c=a.touches&&a.touches[0],e=(c||a).target,g=e,h=this.options,i=this.el,l=h.filter;if(!("mousedown"===b&&0!==a.button||h.disabled)&&(e=d(e,h.draggable,i))){if(z=o(e),"function"==typeof l){if(l.call(this,a,e,this))return L(g,"filter",e,i,z),void a.preventDefault()}else if(l&&(l=l.split(",").some(function(a){return a=d(g,a.trim(),i),a?(L(a,"filter",e,i,z),!0):void 0})))return void a.preventDefault();if((!h.handle||d(g,h.handle,i))&&e&&!q&&e.parentNode===i){C=a,t=this.el,q=e,u=q.nextSibling,B=this.options.group,q.draggable=!0,h.ignore.split(",").forEach(function(a){j(e,a.trim(),k)}),c&&(C={target:e,clientX:c.clientX,clientY:c.clientY},this._onDragStart(C,"touch"),a.preventDefault()),f(H,"mouseup",this._onDrop),f(H,"touchend",this._onDrop),f(H,"touchcancel",this._onDrop),f(q,"dragend",this),f(t,"dragstart",this._onDragStart),J||this._onDragStart(C,!0);try{H.selection?H.selection.empty():window.getSelection().removeAllRanges()}catch(m){}}}},_emulateDragOver:function(){if(D){i(r,"display","none");var a=H.elementFromPoint(D.clientX,D.clientY),b=a,c=" "+this.options.group.name,d=Q.length;if(b)do{if(b[F]&&b[F].groups.indexOf(c)>-1){for(;d--;)Q[d]({clientX:D.clientX,clientY:D.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);i(r,"display","")}},_onTouchMove:function(a){if(C){var b=a.touches?a.touches[0]:a,c=b.clientX-C.clientX,d=b.clientY-C.clientY,e=a.touches?"translate3d("+c+"px,"+d+"px,0)":"translate("+c+"px,"+d+"px)";D=b,i(r,"webkitTransform",e),i(r,"mozTransform",e),i(r,"msTransform",e),i(r,"transform",e),a.preventDefault()}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;if(this._offUpEvents(),"clone"==B.pull&&(s=q.cloneNode(!0),i(s,"display","none"),t.insertBefore(s,q)),b){var e,g=q.getBoundingClientRect(),h=i(q);r=q.cloneNode(!0),i(r,"top",g.top-I(h.marginTop,10)),i(r,"left",g.left-I(h.marginLeft,10)),i(r,"width",g.width),i(r,"height",g.height),i(r,"opacity","0.8"),i(r,"position","fixed"),i(r,"zIndex","100000"),t.appendChild(r),e=r.getBoundingClientRect(),i(r,"width",2*g.width-e.width),i(r,"height",2*g.height-e.height),"touch"===b?(f(H,"touchmove",this._onTouchMove),f(H,"touchend",this._onDrop),f(H,"touchcancel",this._onDrop)):(f(H,"mousemove",this._onTouchMove),f(H,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,150)}else c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,q)),f(H,"drop",this);setTimeout(this._dragStarted,0)},_onDragOver:function(a){var c,e,f,g=this.el,h=this.options,j=h.group,k=j.put,n=B===j,o=h.sort;if(q&&(void 0!==a.preventDefault&&(a.preventDefault(),!h.dragoverBubble&&a.stopPropagation()),B&&!h.disabled&&(n?o||(f=!t.contains(q)):B.pull&&k&&(B.name===j.name||k.indexOf&&~k.indexOf(B.name)))&&(void 0===a.rootEl||a.rootEl===this.el))){if(R(a,h,this.el),K)return;if(c=d(a.target,h.draggable,g),e=q.getBoundingClientRect(),f)return b(!0),void(s||u?t.insertBefore(q,s||u):o||t.appendChild(q));if(0===g.children.length||g.children[0]===r||g===a.target&&(c=m(g,a))){if(c){if(c.animated)return;v=c.getBoundingClientRect()}b(n),g.appendChild(q),this._animate(e,q),c&&this._animate(v,c)}else if(c&&!c.animated&&c!==q&&void 0!==c.parentNode[F]){x!==c&&(x=c,y=i(c));var p,v=c.getBoundingClientRect(),w=v.right-v.left,z=v.bottom-v.top,A=/left|right|inline/.test(y.cssFloat+y.display),C=c.offsetWidth>q.offsetWidth,D=c.offsetHeight>q.offsetHeight,E=(A?(a.clientX-v.left)/w:(a.clientY-v.top)/z)>.5,G=c.nextElementSibling;K=!0,setTimeout(l,30),b(n),p=A?c.previousElementSibling===q&&!C||E&&C:G!==q&&!D||E&&D,p&&!G?g.appendChild(q):c.parentNode.insertBefore(q,p?G:c),this._animate(e,q),this._animate(v,c)}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();i(b,"transition","none"),i(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,i(b,"transition","all "+c+"ms"),i(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){i(b,"transition",""),i(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){g(H,"mouseup",this._onDrop),g(H,"touchmove",this._onTouchMove),g(H,"touchend",this._onDrop),g(H,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(E.pid),g(H,"drop",this),g(H,"mousemove",this._onTouchMove),g(c,"dragstart",this._onDragStart),this._offUpEvents(),b&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation(),r&&r.parentNode.removeChild(r),q&&(g(q,"dragend",this),k(q),h(q,this.options.ghostClass,!1),t!==q.parentNode?(A=o(q),L(q.parentNode,"sort",q,t,z,A),L(t,"sort",q,t,z,A),L(q,"add",q,t,z,A),L(t,"remove",q,t,z,A)):(s&&s.parentNode.removeChild(s),q.nextSibling!==u&&(A=o(q),L(t,"update",q,t,z,A),L(t,"sort",q,t,z,A))),a.active&&L(t,"end",q,t,z,A)),t=q=r=u=s=v=w=C=D=x=y=B=a.active=null,this.save())},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?(this._onDragOver(a),e(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],c=this.el.children,e=0,f=c.length;f>e;e++)a=c[e],d(a,this.options.draggable,this.el)&&b.push(a.getAttribute("data-id")||n(a));return b},sort:function(a){var b={},c=this.el;this.toArray().forEach(function(a,e){var f=c.children[e];d(f,this.options.draggable,c)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(c.removeChild(b[a]),c.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return d(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:void(c[a]=b)},destroy:function(){var a=this.el,b=this.options;M.forEach(function(c){g(a,c.substr(2).toLowerCase(),b[c])}),g(a,"mousedown",this._onTapStart),g(a,"touchstart",this._onTapStart),g(a,"dragover",this),g(a,"dragenter",this),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),Q.splice(Q.indexOf(this._onDragOver),1),this._onDrop(),this.el=null}},a.utils={on:f,off:g,css:i,find:j,bind:c,is:function(a,b){return!!d(a,b,a)},throttle:p,closest:d,toggleClass:h,dispatchEvent:L,index:o},a.version="1.1.1",a.create=function(b,c){return new a(b,c)},a}),function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";a.fn.sortable=function(b){var c;return this.each(function(){var d=a(this),e=d.data("sortable");if(e||!(b instanceof Object)&&b||(e=new Sortable(this,b),d.data("sortable",e)),e){if("widget"===b)return e;"destroy"===b?(e.destroy(),d.removeData("sortable")):b in e&&(c=e[e].apply(e,[].slice.call(arguments,1)))}}),void 0===c?this:c}});var XBBCODE=function(){function a(){i=[];var a,b,c;for(a in h)if(h.hasOwnProperty(a)){for("*"===a?i.push("\\"+a):(i.push(a),h[a].noParse&&u.push(a)),h[a].validChildLookup={},h[a].validParentLookup={},h[a].restrictParentsTo=h[a].restrictParentsTo||[],h[a].restrictChildrenTo=h[a].restrictChildrenTo||[],c=h[a].restrictChildrenTo.length,b=0;c>b;b++)h[a].validChildLookup[h[a].restrictChildrenTo[b]]=!0;for(c=h[a].restrictParentsTo.length,b=0;c>b;b++)h[a].validParentLookup[h[a].restrictParentsTo[b]]=!0}j=new RegExp("<bbcl=([0-9]+) ("+i.join("|")+")([ =][^>]*?)?>((?:.|[\\r\\n])*?)<bbcl=\\1 /\\2>","gi"),k=new RegExp("\\[("+i.join("|")+")([ =][^\\]]*?)?\\]([^\\[]*?)\\[/\\1\\]","gi"),l=new RegExp("\\[("+u.join("|")+")([ =][^\\]]*?)?\\]([\\s\\S]*?)\\[/\\1\\]","gi"),function(){for(var a=[],b=0;b<i.length;b++)"\\*"!==i[b]&&a.push("/"+i[b]);m=new RegExp("(\\[)((?:"+i.join("|")+")(?:[ =][^\\]]*?)?)(\\])","gi"),n=new RegExp("(\\[)("+a.join("|")+")(\\])","gi")}()}function b(a,c,d,e,f,g,k){k=k||[],d++;var l,m,n,o,p=new RegExp("(<bbcl="+d+" )("+i.join("|")+")([ =>])","gi"),q=new RegExp("(<bbcl="+d+" )("+i.join("|")+")([ =>])","i"),r=g.match(p)||[],s=h[a]||{};for(p.lastIndex=0,r||(g=""),n=0;n<r.length;n++)q.lastIndex=0,o=r[n].match(q)[2].toLowerCase(),s&&s.restrictChildrenTo&&s.restrictChildrenTo.length>0&&(s.validChildLookup[o]||(m='The tag "'+o+'" is not allowed as a child of the tag "'+a+'".',k.push(m))),l=h[o]||{},l.restrictParentsTo.length>0&&(l.validParentLookup[a]||(m='The tag "'+a+'" is not allowed as a parent of the tag "'+o+'".', +k.push(m)));return g=g.replace(j,function(a,c,d,e,f){return k=b(d.toLowerCase(),a,c,d,e,f,k),a}),k}function c(a){return a=a.replace(/\<([^\>][^\>]*?)\>/gi,function(a,b){var c=b.match(/^bbcl=([0-9]+) /);return null===c?"<bbcl=0 "+b+">":"<"+b.replace(/^(bbcl=)([0-9]+)/,function(a,b,c){return b+(parseInt(c,10)+1)})+">"})}function d(a){return a.replace(/<bbcl=[0-9]+ \/\*>/gi,"").replace(/<bbcl=[0-9]+ /gi,"[").replace(/>/gi,"]")}function e(a){var b=a.text;return b=b.replace(j,v)}function f(a){for(a=a.replace(/\[(?!\*[ =\]]|list([ =][^\]]*)?\]|\/list[\]])/gi,"<"),a=a.replace(/\[(?=list([ =][^\]]*)?\]|\/list[\]])/gi,">");a!==(a=a.replace(/>list([ =][^\]]*)?\]([^>]*?)(>\/list])/gi,function(a,b,c){for(var d=a;d!==(d=d.replace(/\[\*\]([^\[]*?)(\[\*\]|>\/list])/i,function(a,b,c){return c=">/list]"===c.toLowerCase()?"</*]</list]":"</*][*]","<*]"+b+c})););return d=d.replace(/>/g,"<")})););return a=a.replace(/</g,"[")}function g(a){for(;a!==(a=a.replace(k,function(a,b,d,e){return a=a.replace(/\[/g,"<"),a=a.replace(/\]/g,">"),c(a)})););return a}var h,i,j,k,l,m,n,o={},p=/^(?:https?|file|c):(?:\/{1,3}|\\{1})[-a-zA-Z0-9:;@#%&()~_?\+=\/\\\.]*$/,q=/^(?:aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)$/,r=/^#?[a-fA-F0-9]{6}$/,s=/[^\s@]+@[^\s@]+\.[^\s@]+/,t=/^([a-z][a-z0-9_]+|"[a-z][a-z0-9_\s]+")$/i,u=[];h={b:{openTag:function(a,b){return'<span class="xbbcode-b">'},closeTag:function(a,b){return"</span>"}},bbcode:{openTag:function(a,b){return""},closeTag:function(a,b){return""}},center:{openTag:function(a,b){return'<span class="xbbcode-center">'},closeTag:function(a,b){return"</span>"}},code:{openTag:function(a,b){return'<span class="xbbcode-code">'},closeTag:function(a,b){return"</span>"},noParse:!0},color:{openTag:function(a,b){var c=a.substr(1).toLowerCase()||"black";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="black"),'<span style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},email:{openTag:function(a,b){var c;return c=a?a.substr(1):b.replace(/<.*?>/g,""),s.lastIndex=0,s.test(c)?'<a href="mailto:'+c+'">':"<a>"},closeTag:function(a,b){return"</a>"}},face:{openTag:function(a,b){var c=a.substr(1)||"inherit";return t.lastIndex=0,t.test(c)||(c="inherit"),'<span style="font-family:'+c+'">'},closeTag:function(a,b){return"</span>"}},font:{openTag:function(a,b){var c=a.substr(1)||"inherit";return t.lastIndex=0,t.test(c)||(c="inherit"),'<span style="font-family:'+c+'">'},closeTag:function(a,b){return"</span>"}},i:{openTag:function(a,b){return'<span class="xbbcode-i">'},closeTag:function(a,b){return"</span>"}},img:{openTag:function(a,b){var c=b;return p.lastIndex=0,p.test(c)||(c=""),'<img src="'+c+'" />'},closeTag:function(a,b){return""},displayContent:!1},justify:{openTag:function(a,b){return'<span class="xbbcode-justify">'},closeTag:function(a,b){return"</span>"}},large:{openTag:function(a,b){var a=a||"",c=a.substr(1)||"inherit";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="inherit"),'<span class="xbbcode-size-36" style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},left:{openTag:function(a,b){return'<span class="xbbcode-left">'},closeTag:function(a,b){return"</span>"}},li:{openTag:function(a,b){return"<li>"},closeTag:function(a,b){return"</li>"},restrictParentsTo:["list","ul","ol"]},list:{openTag:function(a,b){return"<ul>"},closeTag:function(a,b){return"</ul>"},restrictChildrenTo:["*","li"]},noparse:{openTag:function(a,b){return""},closeTag:function(a,b){return""},noParse:!0},ol:{openTag:function(a,b){return"<ol>"},closeTag:function(a,b){return"</ol>"},restrictChildrenTo:["*","li"]},php:{openTag:function(a,b){return'<span class="xbbcode-code">'},closeTag:function(a,b){return"</span>"},noParse:!0},quote:{openTag:function(a,b){return'<blockquote class="xbbcode-blockquote">'},closeTag:function(a,b){return"</blockquote>"}},right:{openTag:function(a,b){return'<span class="xbbcode-right">'},closeTag:function(a,b){return"</span>"}},s:{openTag:function(a,b){return'<span class="xbbcode-s">'},closeTag:function(a,b){return"</span>"}},size:{openTag:function(a,b){var c=parseInt(a.substr(1),10)||0;return(4>c||c>40)&&(c=14),'<span class="xbbcode-size-'+c+'">'},closeTag:function(a,b){return"</span>"}},small:{openTag:function(a,b){var a=a||"",c=a.substr(1)||"inherit";return q.lastIndex=0,r.lastIndex=0,q.test(c)||(r.test(c)?"#"!==c.substr(0,1)&&(c="#"+c):c="inherit"),'<span class="xbbcode-size-10" style="color:'+c+'">'},closeTag:function(a,b){return"</span>"}},sub:{openTag:function(a,b){return"<sub>"},closeTag:function(a,b){return"</sub>"}},sup:{openTag:function(a,b){return"<sup>"},closeTag:function(a,b){return"</sup>"}},table:{openTag:function(a,b){return'<table class="xbbcode-table">'},closeTag:function(a,b){return"</table>"},restrictChildrenTo:["tbody","thead","tfoot","tr"]},tbody:{openTag:function(a,b){return"<tbody>"},closeTag:function(a,b){return"</tbody>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},tfoot:{openTag:function(a,b){return"<tfoot>"},closeTag:function(a,b){return"</tfoot>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},thead:{openTag:function(a,b){return'<thead class="xbbcode-thead">'},closeTag:function(a,b){return"</thead>"},restrictChildrenTo:["tr"],restrictParentsTo:["table"]},td:{openTag:function(a,b){return'<td class="xbbcode-td">'},closeTag:function(a,b){return"</td>"},restrictParentsTo:["tr"]},th:{openTag:function(a,b){return'<th class="xbbcode-th">'},closeTag:function(a,b){return"</th>"},restrictParentsTo:["tr"]},tr:{openTag:function(a,b){return'<tr class="xbbcode-tr">'},closeTag:function(a,b){return"</tr>"},restrictChildrenTo:["td","th"],restrictParentsTo:["table","tbody","tfoot","thead"]},u:{openTag:function(a,b){return'<span class="xbbcode-u">'},closeTag:function(a,b){return"</span>"}},ul:{openTag:function(a,b){return"<ul>"},closeTag:function(a,b){return"</ul>"},restrictChildrenTo:["*","li"]},url:{openTag:function(a,b){var c;return c=a?a.substr(1):b.replace(/<.*?>/g,""),p.lastIndex=0,p.test(c)||(c="#"),'<a href="'+c+'">'},closeTag:function(a,b){return"</a>"}},"*":{openTag:function(a,b){return"<li>"},closeTag:function(a,b){return"</li>"},restrictParentsTo:["list","ul","ol"]}},a();var v=function(a,b,c,e,f){c=c.toLowerCase();var g=h[c].noParse?d(f):f.replace(j,v),i=h[c].openTag(e,g),k=h[c].closeTag(e,g);return h[c].displayContent===!1&&(g=""),i+g+k};return o.tags=function(){return h},o.addTags=function(b){var c;for(c in b)h[c]=b[c];a()},o.process=function(a){var c={html:"",error:!1},d=[];for(a.text=a.text.replace(/</g,"<"),a.text=a.text.replace(/>/g,">"),a.text=a.text.replace(m,function(a,b,c,d){return"<"+c+">"}),a.text=a.text.replace(n,function(a,b,c,d){return"<"+c+">"}),a.text=a.text.replace(/\[/g,"["),a.text=a.text.replace(/\]/g,"]"),a.text=a.text.replace(/</g,"["),a.text=a.text.replace(/>/g,"]");a.text!==(a.text=a.text.replace(l,function(a,b,c,d){return d=d.replace(/\[/g,"["),d=d.replace(/\]/g,"]"),c=c||"",d=d||"","["+b+c+"]"+d+"[/"+b+"]"})););return a.text=f(a.text),a.text=g(a.text),d=b("bbcode",a.text,-1,"","",a.text),c.html=e(a),(-1!==c.html.indexOf("[")||-1!==c.html.indexOf("]"))&&d.push("Some tags appear to be misaligned."),a.removeMisalignedTags&&(c.html=c.html.replace(/\[.*?\]/g,"")),a.addInLineBreaks&&(c.html='<div style="white-space:pre;">'+c.html+"</div>"),c.html=c.html.replace("[","["),c.html=c.html.replace("]","]"),c.error=0!==d.length,c.errorQueue=d,c},o}();+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.1",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"), +!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{input:!0,ripples:!0,checkbox:!0,togglebutton:!0,radio:!0,arrive:!0,autofill:!0,withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",togglebuttonElements:".togglebutton > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=ripple></span><span class=check></span>")},togglebutton:function(b){a(b?b:this.options.togglebuttonElements).filter(":notmdproc").data("mdproc",!0).after("<span class=toggle></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if(b.attr("data-hint")&&b.after("<div class=hint>"+b.attr("data-hint")+"</div>"),(null===b.val()||"undefined"==b.val()||""===b.val())&&b.addClass("empty"),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input[type=checkbox]",function(){a(this).blur()}).on("keydown paste",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()&&b[0].checkValidity()?b.addClass("empty"):b.removeClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(b){a(b?b:this.options.withRipples).ripples()},autofill:function(){var b=setInterval(function(){a("input[type!=checkbox]").each(function(){a(this).val()&&a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input").not("[type=file]");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})},init:function(){a.ripples&&this.options.ripples&&this.ripples(),this.options.input&&this.input(),this.options.checkbox&&this.checkbox(),this.options.togglebutton&&this.togglebutton(),this.options.radio&&this.radio(),this.options.autofill&&this.autofill(),document.arrive&&this.options.arrive&&(a(document).arrive(this.options.inputElements,function(){a.material.input(a(this))}),a(document).arrive(this.options.checkboxElements,function(){a.material.checkbox(a(this))}),a(document).arrive(this.options.radioElements,function(){a.material.radio(a(this))}),a(document).arrive(this.options.togglebuttonElements,function(){a.material.togglebutton(a(this))}))}}}(jQuery),function(a,b,c,d){"use strict";function e(b,c){g=this,this.element=a(b),this.options=a.extend({},h,c),this._defaults=h,this._name=f,this.init()}var f="ripples",g=null,h={};e.prototype.init=function(){var c=this.element;c.on("mousedown touchstart",function(d){if(g.isTouch()&&"mousedown"===d.type)return!1;c.find(".ripple-wrapper").length||c.append('<div class="ripple-wrapper"></div>');var e=c.children(".ripple-wrapper"),f=g.getRelY(e,d),h=g.getRelX(e,d);if(f||h){var i=g.getRipplesColor(),j=a("<div></div>");j.addClass("ripple").css({left:h,top:f,"background-color":i}),e.append(j),function(){return b.getComputedStyle(j[0]).opacity}(),g.rippleOn(j),setTimeout(function(){g.rippleEnd(j)},500),c.on("mouseup mouseleave touchend",function(){j.data("mousedown","off"),"off"===j.data("animating")&&g.rippleOut(j)})}})},e.prototype.getNewSize=function(a){var b=this.element;return Math.max(b.outerWidth(),b.outerHeight())/a.outerWidth()*2.5},e.prototype.getRelX=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1!==b.touches.length?b.touches[0].pageX-c.left:!1):b.pageX-c.left},e.prototype.getRelY=function(a,b){var c=a.offset();return g.isTouch()?(b=b.originalEvent,1!==b.touches.length?b.touches[0].pageY-c.top:!1):b.pageY-c.top},e.prototype.getRipplesColor=function(){var a,c=this.element;return a=this.options&&this.options.color?this.options.color:c.data("ripple-color")?c.data("ripple-color"):b.getComputedStyle(c[0]).color},e.prototype.hasTransitionSupport=function(){var a=c.body||c.documentElement,b=a.style,e=b.transition!==d||b.WebkitTransition!==d||b.MozTransition!==d||b.MsTransition!==d||b.OTransition!==d;return e},e.prototype.isTouch=function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},e.prototype.rippleEnd=function(a){a.data("animating","off"),"off"===a.data("mousedown")&&g.rippleOut(a)},e.prototype.rippleOut=function(a){a.off(),g.hasTransitionSupport()?a.addClass("ripple-out"):a.animate({opacity:0},100,function(){a.trigger("transitionend")}),a.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",function(){a.remove()})},e.prototype.rippleOn=function(a){var b=g.getNewSize(a),c=this.element;g.hasTransitionSupport()?a.css({"-ms-transform":"scale("+b+")","-moz-transform":"scale("+b+")","-webkit-transform":"scale("+b+")",transform:"scale("+b+")"}).addClass("ripple-on").data("animating","on").data("mousedown","on"):a.animate({width:2*Math.max(c.outerWidth(),c.outerHeight()),height:2*Math.max(c.outerWidth(),c.outerHeight()),"margin-left":-1*Math.max(c.outerWidth(),c.outerHeight()),"margin-top":-1*Math.max(c.outerWidth(),c.outerHeight()),opacity:.2},500,function(){a.trigger("transitionend")})},a.fn.ripples=function(b){return this.each(function(){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b))})}}(jQuery,window,document),function(a){function b(a){return"undefined"!=typeof a&&null!==a?!0:!1}a(document).ready(function(){a("body").append("<div id=snackbar-container/>")}),a(document).on("click","[data-toggle=snackbar]",function(){a(this).snackbar("toggle")}).on("click","#snackbar-container .snackbar",function(){a(this).snackbar("hide")}),a.snackbar=function(c){if(b(c)&&c===Object(c)){var d;d=b(c.id)?a("#"+c.id):a("<div/>").attr("id","snackbar"+Date.now()).attr("class","snackbar");var e=d.hasClass("snackbar-opened");b(c.style)?d.attr("class","snackbar "+c.style):d.attr("class","snackbar"),c.timeout=b(c.timeout)?c.timeout:3e3,b(c.content)&&(d.find(".snackbar-content").length?d.find(".snackbar-content").text(c.content):d.prepend("<span class=snackbar-content>"+c.content+"</span>")),b(c.id)?d.insertAfter("#snackbar-container .snackbar:last-child"):d.appendTo("#snackbar-container"),b(c.action)&&"toggle"==c.action&&(e?c.action="hide":c.action="show");var f=Date.now();d.data("animationId1",f),setTimeout(function(){d.data("animationId1")===f&&(b(c.action)&&"show"!=c.action?b(c.action)&&"hide"==c.action&&d.removeClass("snackbar-opened"):d.addClass("snackbar-opened"))},50);var g=Date.now();return d.data("animationId2",g),0!==c.timeout&&setTimeout(function(){d.data("animationId2")===g&&d.removeClass("snackbar-opened")},c.timeout),d}return!1},a.fn.snackbar=function(c){var d={};if(this.hasClass("snackbar"))return d.id=this.attr("id"),("show"===c||"hide"===c||"toggle"==c)&&(d.action=c),a.snackbar(d);b(c)&&"show"!==c&&"hide"!==c&&"toggle"!=c||(d={content:a(this).attr("data-content"),style:a(this).attr("data-style"),timeout:a(this).attr("data-timeout")}),b(c)&&(d.id=this.attr("data-snackbar-id"),("show"===c||"hide"===c||"toggle"==c)&&(d.action=c));var e=a.snackbar(d);return this.attr("data-snackbar-id",e.attr("id")),e}}(jQuery),function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){if(!d)var d={map:function(a,b){var c={};return b?a.map(function(a,d){return c.index=d,b.call(c,a)}):a.slice()},naturalOrder:function(a,b){return b>a?-1:a>b?1:0},sum:function(a,b){var c={};return a.reduce(b?function(a,d,e){return c.index=e,a+b.call(c,d)}:function(a,b){return a+b},0)},max:function(a,b){return Math.max.apply(null,b?d.map(a,b):a)}};var e=function(){function a(a,b,c){return(a<<2*j)+(b<<j)+c}function b(a){function b(){c.sort(a),d=!0}var c=[],d=!1;return{push:function(a){c.push(a),d=!1},peek:function(a){return d||b(),void 0===a&&(a=c.length-1),c[a]},pop:function(){return d||b(),c.pop()},size:function(){return c.length},map:function(a){return c.map(a)},debug:function(){return d||b(),c}}}function c(a,b,c,d,e,f,g){var h=this;h.r1=a,h.r2=b,h.g1=c,h.g2=d,h.b1=e,h.b2=f,h.histo=g}function e(){this.vboxes=new b(function(a,b){return d.naturalOrder(a.vbox.count()*a.vbox.volume(),b.vbox.count()*b.vbox.volume())})}function f(b){var c,d,e,f,g=1<<3*j,h=new Array(g);return b.forEach(function(b){d=b[0]>>k,e=b[1]>>k,f=b[2]>>k,c=a(d,e,f),h[c]=(h[c]||0)+1}),h}function g(a,b){var d,e,f,g=1e6,h=0,i=1e6,j=0,l=1e6,m=0;return a.forEach(function(a){d=a[0]>>k,e=a[1]>>k,f=a[2]>>k,g>d?g=d:d>h&&(h=d),i>e?i=e:e>j&&(j=e),l>f?l=f:f>m&&(m=f)}),new c(g,h,i,j,l,m,b)}function h(b,c){function e(a){var b,d,e,f,g,h=a+"1",i=a+"2",k=0;for(j=c[h];j<=c[i];j++)if(p[j]>o/2){for(e=c.copy(),f=c.copy(),b=j-c[h],d=c[i]-j,g=d>=b?Math.min(c[i]-1,~~(j+d/2)):Math.max(c[h],~~(j-1-b/2));!p[g];)g++;for(k=q[g];!k&&p[g-1];)k=q[--g];return e[i]=g,f[h]=e[i]+1,[e,f]}}if(c.count()){var f=c.r2-c.r1+1,g=c.g2-c.g1+1,h=c.b2-c.b1+1,i=d.max([f,g,h]);if(1==c.count())return[c.copy()];var j,k,l,m,n,o=0,p=[],q=[];if(i==f)for(j=c.r1;j<=c.r2;j++){for(m=0,k=c.g1;k<=c.g2;k++)for(l=c.b1;l<=c.b2;l++)n=a(j,k,l),m+=b[n]||0;o+=m,p[j]=o}else if(i==g)for(j=c.g1;j<=c.g2;j++){for(m=0,k=c.r1;k<=c.r2;k++)for(l=c.b1;l<=c.b2;l++)n=a(k,j,l),m+=b[n]||0;o+=m,p[j]=o}else for(j=c.b1;j<=c.b2;j++){for(m=0,k=c.r1;k<=c.r2;k++)for(l=c.g1;l<=c.g2;l++)n=a(k,l,j),m+=b[n]||0;o+=m,p[j]=o}return p.forEach(function(a,b){q[b]=o-a}),e(i==f?"r":i==g?"g":"b")}}function i(a,c){function i(a,b){for(var c,d=1,e=0;l>e;)if(c=a.pop(),c.count()){var f=h(j,c),g=f[0],i=f[1];if(!g)return;if(a.push(g),i&&(a.push(i),d++),d>=b)return;if(e++>l)return}else a.push(c),e++}if(!a.length||2>c||c>256)return!1;var j=f(a),k=0;j.forEach(function(){k++});var n=g(a,j),o=new b(function(a,b){return d.naturalOrder(a.count(),b.count())});o.push(n),i(o,m*c);for(var p=new b(function(a,b){return d.naturalOrder(a.count()*a.volume(),b.count()*b.volume())});o.size();)p.push(o.pop());i(p,c-p.size());for(var q=new e;p.size();)q.push(p.pop());return q}var j=5,k=8-j,l=1e3,m=.75;return c.prototype={volume:function(a){var b=this;return(!b._volume||a)&&(b._volume=(b.r2-b.r1+1)*(b.g2-b.g1+1)*(b.b2-b.b1+1)),b._volume},count:function(b){var c=this,d=c.histo;if(!c._count_set||b){var e,f,g,h=0;for(e=c.r1;e<=c.r2;e++)for(f=c.g1;f<=c.g2;f++)for(g=c.b1;g<=c.b2;g++)index=a(e,f,g),h+=d[index]||0;c._count=h,c._count_set=!0}return c._count},copy:function(){var a=this;return new c(a.r1,a.r2,a.g1,a.g2,a.b1,a.b2,a.histo)},avg:function(b){var c=this,d=c.histo;if(!c._avg||b){var e,f,g,h,i,k=0,l=1<<8-j,m=0,n=0,o=0;for(f=c.r1;f<=c.r2;f++)for(g=c.g1;g<=c.g2;g++)for(h=c.b1;h<=c.b2;h++)i=a(f,g,h),e=d[i]||0,k+=e,m+=e*(f+.5)*l,n+=e*(g+.5)*l,o+=e*(h+.5)*l;k?c._avg=[~~(m/k),~~(n/k),~~(o/k)]:c._avg=[~~(l*(c.r1+c.r2+1)/2),~~(l*(c.g1+c.g2+1)/2),~~(l*(c.b1+c.b2+1)/2)]}return c._avg},contains:function(a){var b=this,c=a[0]>>k;return gval=a[1]>>k,bval=a[2]>>k,c>=b.r1&&c<=b.r2&&gval>=b.g1&&gval<=b.g2&&bval>=b.b1&&bval<=b.b2}},e.prototype={push:function(a){this.vboxes.push({vbox:a,color:a.avg()})},palette:function(){return this.vboxes.map(function(a){return a.color})},size:function(){return this.vboxes.size()},map:function(a){for(var b=this.vboxes,c=0;c<b.size();c++)if(b.peek(c).vbox.contains(a))return b.peek(c).color;return this.nearest(a)},nearest:function(a){for(var b,c,d,e=this.vboxes,f=0;f<e.size();f++)c=Math.sqrt(Math.pow(a[0]-e.peek(f).color[0],2)+Math.pow(a[1]-e.peek(f).color[1],2)+Math.pow(a[2]-e.peek(f).color[2],2)),(b>c||void 0===b)&&(b=c,d=e.peek(f).color);return d},forcebw:function(){var a=this.vboxes;a.sort(function(a,b){return d.naturalOrder(d.sum(a.color),d.sum(b.color))});var b=a[0].color;b[0]<5&&b[1]<5&&b[2]<5&&(a[0].color=[0,0,0]);var c=a.length-1,e=a[c].color;e[0]>251&&e[1]>251&&e[2]>251&&(a[c].color=[255,255,255])}},{quantize:i}}();b.exports=e.quantize},{}],2:[function(a,b,c){(function(){var b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}},f=[].slice;window.Swatch=c=function(){function a(a,b){this.rgb=a,this.population=b}return a.prototype.hsl=void 0,a.prototype.rgb=void 0,a.prototype.population=1,a.yiq=0,a.prototype.getHsl=function(){return this.hsl?this.hsl:this.hsl=d.rgbToHsl(this.rgb[0],this.rgb[1],this.rgb[2])},a.prototype.getPopulation=function(){return this.population},a.prototype.getRgb=function(){return this.rgb},a.prototype.getHex=function(){return"#"+((1<<24)+(this.rgb[0]<<16)+(this.rgb[1]<<8)+this.rgb[2]).toString(16).slice(1,7)},a.prototype.getTitleTextColor=function(){return this._ensureTextColors(),this.yiq<200?"#fff":"#000"},a.prototype.getBodyTextColor=function(){return this._ensureTextColors(),this.yiq<150?"#fff":"#000"},a.prototype._ensureTextColors=function(){return this.yiq?void 0:this.yiq=(299*this.rgb[0]+587*this.rgb[1]+114*this.rgb[2])/1e3},a}(),window.Vibrant=d=function(){function d(a,d,f){this.swatches=e(this.swatches,this);var g,h,i,j,k,l,m,n,o,p,q,r;for("undefined"==typeof d&&(d=64),"undefined"==typeof f&&(f=5),m=new b(a),n=m.getImageData(),q=n.data,p=m.getPixelCount(),h=[],l=0;p>l;)o=4*l,r=q[o+0],k=q[o+1],i=q[o+2],g=q[o+3],g>=125&&(r>250&&k>250&&i>250||h.push([r,k,i])),l+=f;j=this.quantize(h,d),this._swatches=j.vboxes.map(function(a){return function(a){return new c(a.color,a.vbox.count())}}(this)),this.maxPopulation=this.findMaxPopulation,this.generateVarationColors(),this.generateEmptySwatches(),m.removeCanvas()}return d.prototype.quantize=a("quantize"),d.prototype._swatches=[],d.prototype.TARGET_DARK_LUMA=.26,d.prototype.MAX_DARK_LUMA=.45,d.prototype.MIN_LIGHT_LUMA=.55,d.prototype.TARGET_LIGHT_LUMA=.74,d.prototype.MIN_NORMAL_LUMA=.3,d.prototype.TARGET_NORMAL_LUMA=.5,d.prototype.MAX_NORMAL_LUMA=.7,d.prototype.TARGET_MUTED_SATURATION=.3,d.prototype.MAX_MUTED_SATURATION=.4,d.prototype.TARGET_VIBRANT_SATURATION=1,d.prototype.MIN_VIBRANT_SATURATION=.35,d.prototype.WEIGHT_SATURATION=3,d.prototype.WEIGHT_LUMA=6,d.prototype.WEIGHT_POPULATION=1,d.prototype.VibrantSwatch=void 0,d.prototype.MutedSwatch=void 0,d.prototype.DarkVibrantSwatch=void 0,d.prototype.DarkMutedSwatch=void 0,d.prototype.LightVibrantSwatch=void 0,d.prototype.LightMutedSwatch=void 0,d.prototype.HighestPopulation=0,d.prototype.generateVarationColors=function(){return this.VibrantSwatch=this.findColorVariation(this.TARGET_NORMAL_LUMA,this.MIN_NORMAL_LUMA,this.MAX_NORMAL_LUMA,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.LightVibrantSwatch=this.findColorVariation(this.TARGET_LIGHT_LUMA,this.MIN_LIGHT_LUMA,1,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.DarkVibrantSwatch=this.findColorVariation(this.TARGET_DARK_LUMA,0,this.MAX_DARK_LUMA,this.TARGET_VIBRANT_SATURATION,this.MIN_VIBRANT_SATURATION,1),this.MutedSwatch=this.findColorVariation(this.TARGET_NORMAL_LUMA,this.MIN_NORMAL_LUMA,this.MAX_NORMAL_LUMA,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION),this.LightMutedSwatch=this.findColorVariation(this.TARGET_LIGHT_LUMA,this.MIN_LIGHT_LUMA,1,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION),this.DarkMutedSwatch=this.findColorVariation(this.TARGET_DARK_LUMA,0,this.MAX_DARK_LUMA,this.TARGET_MUTED_SATURATION,0,this.MAX_MUTED_SATURATION)},d.prototype.generateEmptySwatches=function(){var a;return void 0===this.VibrantSwatch&&void 0!==this.DarkVibrantSwatch&&(a=this.DarkVibrantSwatch.getHsl(),a[2]=this.TARGET_NORMAL_LUMA,this.VibrantSwatch=new c(d.hslToRgb(a[0],a[1],a[2]),0)),void 0===this.DarkVibrantSwatch&&void 0!==this.VibrantSwatch?(a=this.VibrantSwatch.getHsl(),a[2]=this.TARGET_DARK_LUMA,this.DarkVibrantSwatch=new c(d.hslToRgb(a[0],a[1],a[2]),0)):void 0},d.prototype.findMaxPopulation=function(){var a,b,c,d,e;for(c=0,d=this._swatches,a=0,b=d.length;b>a;a++)e=d[a],c=Math.max(c,e.getPopulation());return c},d.prototype.findColorVariation=function(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o;for(j=void 0,k=0,l=this._swatches,g=0,h=l.length;h>g;g++)n=l[g],m=n.getHsl()[1],i=n.getHsl()[2],m>=e&&f>=m&&i>=b&&c>=i&&!this.isAlreadySelected(n)&&(o=this.createComparisonValue(m,d,i,a,n.getPopulation(),this.HighestPopulation),(void 0===j||o>k)&&(j=n,k=o));return j},d.prototype.createComparisonValue=function(a,b,c,d,e,f){return this.weightedMean(this.invertDiff(a,b),this.WEIGHT_SATURATION,this.invertDiff(c,d),this.WEIGHT_LUMA,e/f,this.WEIGHT_POPULATION)},d.prototype.invertDiff=function(a,b){return 1-Math.abs(a-b)},d.prototype.weightedMean=function(){var a,b,c,d,e,g;for(e=1<=arguments.length?f.call(arguments,0):[],b=0,c=0,a=0;a<e.length;)d=e[a],g=e[a+1],b+=d*g,c+=g,a+=2;return b/c},d.prototype.swatches=function(){return{Vibrant:this.VibrantSwatch,Muted:this.MutedSwatch,DarkVibrant:this.DarkVibrantSwatch,DarkMuted:this.DarkMutedSwatch,LightVibrant:this.LightVibrantSwatch,LightMuted:this.LightMuted}},d.prototype.isAlreadySelected=function(a){return this.VibrantSwatch===a||this.DarkVibrantSwatch===a||this.LightVibrantSwatch===a||this.MutedSwatch===a||this.DarkMutedSwatch===a||this.LightMutedSwatch===a},d.rgbToHsl=function(a,b,c){var d,e,f,g,h,i;if(a/=255,b/=255,c/=255,g=Math.max(a,b,c),h=Math.min(a,b,c),e=void 0,i=void 0,f=(g+h)/2,g===h)e=i=0;else{switch(d=g-h,i=f>.5?d/(2-g-h):d/(g+h),g){case a:e=(b-c)/d+(c>b?6:0);break;case b:e=(c-a)/d+2;break;case c:e=(a-b)/d+4}e/=6}return[e,i,f]},d.hslToRgb=function(a,b,c){var d,e,f,g,h,i;return i=void 0,e=void 0,d=void 0,f=function(a,b,c){return 0>c&&(c+=1),c>1&&(c-=1),1/6>c?a+6*(b-a)*c:.5>c?b:2/3>c?a+(b-a)*(2/3-c)*6:a},0===b?i=e=d=c:(h=.5>c?c*(1+b):c+b-c*b,g=2*c-h,i=f(g,h,a+1/3),e=f(g,h,a),d=f(g,h,a-1/3)),[255*i,255*e,255*d]},d}(),window.CanvasImage=b=function(){function a(a){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),document.body.appendChild(this.canvas),this.width=this.canvas.width=a.width,this.height=this.canvas.height=a.height,this.context.drawImage(a,0,0,this.width,this.height)}return a.prototype.clear=function(){return this.context.clearRect(0,0,this.width,this.height)},a.prototype.update=function(a){return this.context.putImageData(a,0,0)},a.prototype.getPixelCount=function(){return this.width*this.height},a.prototype.getImageData=function(){return this.context.getImageData(0,0,this.width,this.height)},a.prototype.removeCanvas=function(){return this.canvas.parentNode.removeChild(this.canvas)},a}()}).call(this)},{quantize:1}]},{},[2]),function(a,b){"use strict";function c(c,d){function e(a){return qa.preferFlash&&ja&&!qa.ignoreFlash&&qa.flash[a]!==b&&qa.flash[a]}function f(a){return function(b){var c,d=this._s; +return d&&d._a?c=a.call(this,b):(d&&d.id?qa._wD(d.id+": Ignoring "+b.type):qa._wD(va+"Ignoring "+b.type),c=null),c}}this.setupOptions={url:c||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1e3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!1,noSWFCache:!1,idPrefix:"sound"},this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100},this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null},this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null},this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},opus:{type:["audio/ogg; codecs=opus","audio/opus"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}},this.movieID="sm2-container",this.id=d||"sm2movie",this.debugID="soundmanager-debug",this.debugURLParam=/([#?&])debug=1/i,this.versionNumber="V2.97a.20140901",this.version=null,this.movieURL=null,this.altURL=null,this.swfLoaded=!1,this.enabled=!1,this.oMC=null,this.sounds={},this.soundIDs=[],this.muted=!1,this.didFlashBlock=!1,this.filePattern=null,this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i},this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1},this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null},this.html5={usingFlash:null},this.flash={},this.html5Only=!1,this.ignoreFlash=!1;var g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa=this,ra=null,sa=null,ta="soundManager",ua=ta+": ",va="HTML5::",wa=navigator.userAgent,xa=a.location.href.toString(),ya=document,za=[],Aa=!0,Ba=!1,Ca=!1,Da=!1,Ea=!1,Fa=!1,Ga=0,Ha=["log","info","warn","error"],Ia=8,Ja=null,Ka=null,La=!1,Ma=!1,Na=0,Oa=null,Pa=[],Qa=null,Ra=Array.prototype.slice,Sa=!1,Ta=0,Ua=wa.match(/(ipad|iphone|ipod)/i),Va=wa.match(/android/i),Wa=wa.match(/msie/i),Xa=wa.match(/webkit/i),Ya=wa.match(/safari/i)&&!wa.match(/chrome/i),Za=wa.match(/opera/i),$a=wa.match(/(mobile|pre\/|xoom)/i)||Ua||Va,_a=!xa.match(/usehtml5audio/i)&&!xa.match(/sm2\-ignorebadua/i)&&Ya&&!wa.match(/silk/i)&&wa.match(/OS X 10_6_([3-7])/i),ab=a.console!==b&&console.log!==b,bb=ya.hasFocus!==b?ya.hasFocus():null,cb=Ya&&(ya.hasFocus===b||!ya.hasFocus()),db=!cb,eb=/(mp3|mp4|mpa|m4a|m4b)/i,fb=1e3,gb="about:blank",hb="data:audio/wave;base64,/UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQIAAAD//w==",ib=ya.location?ya.location.protocol.match(/http/i):null,jb=ib?"":"http://",kb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,lb=["mpeg4","aac","flv","mov","mp4","m4v","f4v","m4a","m4b","mp4v","3gp","3g2"],mb=new RegExp("\\.("+lb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i,this.useAltURL=!ib,R={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"},this.hasHTML5=function(){try{return Audio!==b&&(Za&&opera!==b&&opera.version()<10?new Audio(null):new Audio).canPlayType!==b}catch(a){return!1}}(),this.setup=function(a){var c=!qa.url;return a!==b&&Da&&Qa&&qa.ok()&&(a.flashVersion!==b||a.url!==b||a.html5Test!==b)&&V(O("setupLate")),q(a),a&&(c&&F&&a.url!==b&&qa.beginDelayedInit(),F||a.url===b||"complete"!==ya.readyState||setTimeout(D,1)),qa},this.ok=function(){return Qa?Da&&!Ea:qa.useHTML5Audio&&qa.hasHTML5},this.supported=this.ok,this.getMovie=function(b){return h(b)||ya[b]||a[b]},this.createSound=function(a,c){function d(){return h=T(h),qa.sounds[h.id]=new g(h),qa.soundIDs.push(h.id),qa.sounds[h.id]}var e,f,h,i=null;if(e=ta+".createSound(): ",f=e+O(Da?"notOK":"notReady"),!Da||!qa.ok())return V(f),!1;if(c!==b&&(a={id:a,url:c}),h=p(a),h.url=$(h.url),void 0===h.id&&(h.id=qa.setupOptions.idPrefix+Ta++),h.id.toString().charAt(0).match(/^[0-9]$/)&&qa._wD(e+O("badID",h.id),2),qa._wD(e+h.id+(h.url?" ("+h.url+")":""),1),W(h.id,!0))return qa._wD(e+h.id+" exists",1),qa.sounds[h.id];if(ba(h))i=d(),qa._wD(h.id+": Using HTML5"),i._setup_html5(h);else{if(qa.html5Only)return qa._wD(h.id+": No HTML5 support for this sound, and no Flash. Exiting."),d();if(qa.html5.usingFlash&&h.url&&h.url.match(/data\:/i))return qa._wD(h.id+": data: URIs not supported via Flash. Exiting."),d();l>8&&(null===h.isMovieStar&&(h.isMovieStar=!!(h.serverURL||(h.type?h.type.match(kb):!1)||h.url&&h.url.match(mb))),h.isMovieStar&&(qa._wD(e+"using MovieStar handling"),h.loops>1&&n("noNSLoop"))),h=U(h,e),i=d(),8===l?sa._createSound(h.id,h.loops||1,h.usePolicyFile):(sa._createSound(h.id,h.url,h.usePeakData,h.useWaveformData,h.useEQData,h.isMovieStar,h.isMovieStar?h.bufferTime:!1,h.loops||1,h.serverURL,h.duration||null,h.autoPlay,!0,h.autoLoad,h.usePolicyFile),h.serverURL||(i.connected=!0,h.onconnect&&h.onconnect.apply(i))),h.serverURL||!h.autoLoad&&!h.autoPlay||i.load(h)}return!h.serverURL&&h.autoPlay&&i.play(),i},this.destroySound=function(a,b){if(!W(a))return!1;var c,d=qa.sounds[a];for(d._iO={},d.stop(),d.unload(),c=0;c<qa.soundIDs.length;c++)if(qa.soundIDs[c]===a){qa.soundIDs.splice(c,1);break}return b||d.destruct(!0),d=null,delete qa.sounds[a],!0},this.load=function(a,b){return W(a)?qa.sounds[a].load(b):!1},this.unload=function(a){return W(a)?qa.sounds[a].unload():!1},this.onPosition=function(a,b,c,d){return W(a)?qa.sounds[a].onposition(b,c,d):!1},this.onposition=this.onPosition,this.clearOnPosition=function(a,b,c){return W(a)?qa.sounds[a].clearOnPosition(b,c):!1},this.play=function(a,b){var c=null,d=b&&!(b instanceof Object);if(!Da||!qa.ok())return V(ta+".play(): "+O(Da?"notOK":"notReady")),!1;if(W(a,d))d&&(b={url:b});else{if(!d)return!1;d&&(b={url:b}),b&&b.url&&(qa._wD(ta+'.play(): Attempting to create "'+a+'"',1),b.id=a,c=qa.createSound(b).play())}return null===c&&(c=qa.sounds[a].play(b)),c},this.start=this.play,this.setPosition=function(a,b){return W(a)?qa.sounds[a].setPosition(b):!1},this.stop=function(a){return W(a)?(qa._wD(ta+".stop("+a+")",1),qa.sounds[a].stop()):!1},this.stopAll=function(){var a;qa._wD(ta+".stopAll()",1);for(a in qa.sounds)qa.sounds.hasOwnProperty(a)&&qa.sounds[a].stop()},this.pause=function(a){return W(a)?qa.sounds[a].pause():!1},this.pauseAll=function(){var a;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].pause()},this.resume=function(a){return W(a)?qa.sounds[a].resume():!1},this.resumeAll=function(){var a;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].resume()},this.togglePause=function(a){return W(a)?qa.sounds[a].togglePause():!1},this.setPan=function(a,b){return W(a)?qa.sounds[a].setPan(b):!1},this.setVolume=function(a,b){return W(a)?qa.sounds[a].setVolume(b):!1},this.mute=function(a){var b=0;if(a instanceof String&&(a=null),a)return W(a)?(qa._wD(ta+'.mute(): Muting "'+a+'"'),qa.sounds[a].mute()):!1;for(qa._wD(ta+".mute(): Muting all sounds"),b=qa.soundIDs.length-1;b>=0;b--)qa.sounds[qa.soundIDs[b]].mute();return qa.muted=!0,!0},this.muteAll=function(){qa.mute()},this.unmute=function(a){var b;if(a instanceof String&&(a=null),a)return W(a)?(qa._wD(ta+'.unmute(): Unmuting "'+a+'"'),qa.sounds[a].unmute()):!1;for(qa._wD(ta+".unmute(): Unmuting all sounds"),b=qa.soundIDs.length-1;b>=0;b--)qa.sounds[qa.soundIDs[b]].unmute();return qa.muted=!1,!0},this.unmuteAll=function(){qa.unmute()},this.toggleMute=function(a){return W(a)?qa.sounds[a].toggleMute():!1},this.getMemoryUse=function(){var a=0;return sa&&8!==l&&(a=parseInt(sa._getMemoryUse(),10)),a},this.disable=function(c){var d;if(c===b&&(c=!1),Ea)return!1;for(Ea=!0,n("shutdown",1),d=qa.soundIDs.length-1;d>=0;d--)L(qa.sounds[qa.soundIDs[d]]);return o(c),ha.remove(a,"load",u),!0},this.canPlayMIME=function(a){var b;return qa.hasHTML5&&(b=ca({type:a})),!b&&Qa&&(b=a&&qa.ok()?!!((l>8?a.match(kb):null)||a.match(qa.mimePattern)):null),b},this.canPlayURL=function(a){var b;return qa.hasHTML5&&(b=ca({url:a})),!b&&Qa&&(b=a&&qa.ok()?!!a.match(qa.filePattern):null),b},this.canPlayLink=function(a){return a.type!==b&&a.type&&qa.canPlayMIME(a.type)?!0:qa.canPlayURL(a.href)},this.getSoundById=function(a,b){if(!a)return null;var c=qa.sounds[a];return c||b||qa._wD(ta+'.getSoundById(): Sound "'+a+'" not found.',2),c},this.onready=function(b,c){var d="onready",e=!1;if("function"!=typeof b)throw O("needFunction",d);return Da&&qa._wD(O("queue",d)),c||(c=a),s(d,b,c),t(),e=!0,e},this.ontimeout=function(b,c){var d="ontimeout",e=!1;if("function"!=typeof b)throw O("needFunction",d);return Da&&qa._wD(O("queue",d)),c||(c=a),s(d,b,c),t({type:d}),e=!0,e},this._writeDebug=function(a,c){var d,e,f="soundmanager-debug";return qa.debugMode?ab&&qa.useConsole&&(c&&"object"==typeof c?console.log(a,c):Ha[c]!==b?console[Ha[c]](a):console.log(a),qa.consoleOnly)?!0:(d=h(f))?(e=ya.createElement("div"),++Ga%2===0&&(e.className="sm2-alt"),c=c===b?0:parseInt(c,10),e.appendChild(ya.createTextNode(a)),c&&(c>=2&&(e.style.fontWeight="bold"),3===c&&(e.style.color="#ff3333")),d.insertBefore(e,d.firstChild),d=null,!0):!1:!1},-1!==xa.indexOf("sm2-debug=alert")&&(this._writeDebug=function(b){a.alert(b)}),this._wD=this._writeDebug,this._debug=function(){var a,b;for(n("currentObj",1),a=0,b=qa.soundIDs.length;b>a;a++)qa.sounds[qa.soundIDs[a]]._debug()},this.reboot=function(b,c){qa.soundIDs.length&&qa._wD("Destroying "+qa.soundIDs.length+" SMSound object"+(1!==qa.soundIDs.length?"s":"")+"...");var d,e,f;for(d=qa.soundIDs.length-1;d>=0;d--)qa.sounds[qa.soundIDs[d]].destruct();if(sa)try{Wa&&(Ka=sa.innerHTML),Ja=sa.parentNode.removeChild(sa)}catch(g){n("badRemove",2)}if(Ka=Ja=Qa=sa=null,qa.enabled=F=Da=La=Ma=Ba=Ca=Ea=Sa=qa.swfLoaded=!1,qa.soundIDs=[],qa.sounds={},Ta=0,b)za=[];else for(d in za)if(za.hasOwnProperty(d))for(e=0,f=za[d].length;f>e;e++)za[d][e].fired=!1;return c||qa._wD(ta+": Rebooting..."),qa.html5={usingFlash:null},qa.flash={},qa.html5Only=!1,qa.ignoreFlash=!1,a.setTimeout(function(){C(),c||qa.beginDelayedInit()},20),qa},this.reset=function(){return n("reset"),qa.reboot(!0,!0)},this.getMoviePercent=function(){return sa&&"PercentLoaded"in sa?sa.PercentLoaded():null},this.beginDelayedInit=function(){Fa=!0,D(),setTimeout(function(){return Ma?!1:(H(),B(),Ma=!0,!0)},20),v()},this.destruct=function(){qa._wD(ta+".destruct()"),qa.disable(!0)},g=function(a){var c,d,e,f,g,h,i,j,k,o,q=this,r=!1,s=[],t=0,u=null;k={duration:null,time:null},this.id=a.id,this.sID=this.id,this.url=a.url,this.options=p(a),this.instanceOptions=this.options,this._iO=this.instanceOptions,this.pan=this.options.pan,this.volume=this.options.volume,this.isHTML5=!1,this._a=null,o=this.url?!1:!0,this.id3={},this._debug=function(){qa._wD(q.id+": Merged options:",q.options)},this.load=function(a){var c,d=null;if(a!==b?q._iO=p(a,q.options):(a=q.options,q._iO=a,u&&u!==q.url&&(n("manURL"),q._iO.url=q.url,q.url=null)),q._iO.url||(q._iO.url=q.url),q._iO.url=$(q._iO.url),q.instanceOptions=q._iO,c=q._iO,qa._wD(q.id+": load ("+c.url+")"),!c.url&&!q.url)return qa._wD(q.id+": load(): url is unassigned. Exiting.",2),q;if(q.isHTML5||8!==l||q.url||c.autoPlay||qa._wD(q.id+": Flash 8 load() limitation: Wait for onload() before calling play().",1),c.url===q.url&&0!==q.readyState&&2!==q.readyState)return n("onURL",1),3===q.readyState&&c.onload&&pa(q,function(){c.onload.apply(q,[!!q.duration])}),q;if(q.loaded=!1,q.readyState=1,q.playState=0,q.id3={},ba(c))d=q._setup_html5(c),d._called_load?qa._wD(q.id+": Ignoring request to load again"):(q._html5_canplay=!1,q.url!==c.url&&(qa._wD(n("manURL")+": "+c.url),q._a.src=c.url,q.setPosition(0)),q._a.autobuffer="auto",q._a.preload="auto",q._a._called_load=!0);else{if(qa.html5Only)return qa._wD(q.id+": No flash support. Exiting."),q;if(q._iO.url&&q._iO.url.match(/data\:/i))return qa._wD(q.id+": data: URIs not supported via Flash. Exiting."),q;try{q.isHTML5=!1,q._iO=U(T(c)),q._iO.autoPlay&&(q._iO.position||q._iO.from)&&(qa._wD(q.id+": Disabling autoPlay because of non-zero offset case"),q._iO.autoPlay=!1),c=q._iO,8===l?sa._load(q.id,c.url,c.stream,c.autoPlay,c.usePolicyFile):sa._load(q.id,c.url,!!c.stream,!!c.autoPlay,c.loops||1,!!c.autoLoad,c.usePolicyFile)}catch(e){n("smError",2),m("onload",!1),I({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:!0})}}return q.url=c.url,q},this.unload=function(){return 0!==q.readyState&&(qa._wD(q.id+": unload()"),q.isHTML5?(f(),q._a&&(q._a.pause(),u=ea(q._a))):8===l?sa._unload(q.id,gb):sa._unload(q.id),c()),q},this.destruct=function(a){qa._wD(q.id+": Destruct"),q.isHTML5?(f(),q._a&&(q._a.pause(),ea(q._a),Sa||e(),q._a._s=null,q._a=null)):(q._iO.onfailure=null,sa._destroySound(q.id)),a||qa.destroySound(q.id,!0)},this.play=function(a,c){var d,e,f,i,k,m,n,s=!0,t=null;if(d=q.id+": play(): ",c=c===b?!0:c,a||(a={}),q.url&&(q._iO.url=q.url),q._iO=p(q._iO,q.options),q._iO=p(a,q._iO),q._iO.url=$(q._iO.url),q.instanceOptions=q._iO,!q.isHTML5&&q._iO.serverURL&&!q.connected)return q.getAutoPlay()||(qa._wD(d+" Netstream not connected yet - setting autoPlay"),q.setAutoPlay(!0)),q;if(ba(q._iO)&&(q._setup_html5(q._iO),g()),1!==q.playState||q.paused||(e=q._iO.multiShot,e?qa._wD(d+"Already playing (multi-shot)",1):(qa._wD(d+"Already playing (one-shot)",1),q.isHTML5&&q.setPosition(q._iO.position),t=q)),null!==t)return t;if(a.url&&a.url!==q.url&&(q.readyState||q.isHTML5||8!==l||!o?q.load(q._iO):o=!1),q.loaded?qa._wD(d.substr(0,d.lastIndexOf(":"))):0===q.readyState?(qa._wD(d+"Attempting to load"),q.isHTML5||qa.html5Only?q.isHTML5?q.load(q._iO):(qa._wD(d+"Unsupported type. Exiting."),t=q):(q._iO.autoPlay=!0,q.load(q._iO)),q.instanceOptions=q._iO):2===q.readyState?(qa._wD(d+"Could not load - exiting",2),t=q):qa._wD(d+"Loading - attempting to play..."),null!==t)return t;if(!q.isHTML5&&9===l&&q.position>0&&q.position===q.duration&&(qa._wD(d+"Sound at end, resetting to position:0"),a.position=0),q.paused&&q.position>=0&&(!q._iO.serverURL||q.position>0))qa._wD(d+"Resuming from paused state",1),q.resume();else{if(q._iO=p(a,q._iO),(!q.isHTML5&&null!==q._iO.position&&q._iO.position>0||null!==q._iO.from&&q._iO.from>0||null!==q._iO.to)&&0===q.instanceCount&&0===q.playState&&!q._iO.serverURL){if(i=function(){q._iO=p(a,q._iO),q.play(q._iO)},q.isHTML5&&!q._html5_canplay?(qa._wD(d+"Beginning load for non-zero offset case"),q.load({_oncanplay:i}),t=!1):q.isHTML5||q.loaded||q.readyState&&2===q.readyState||(qa._wD(d+"Preloading for non-zero offset case"),q.load({onload:i}),t=!1),null!==t)return t;q._iO=j()}(!q.instanceCount||q._iO.multiShotEvents||q.isHTML5&&q._iO.multiShot&&!Sa||!q.isHTML5&&l>8&&!q.getAutoPlay())&&q.instanceCount++,q._iO.onposition&&0===q.playState&&h(q),q.playState=1,q.paused=!1,q.position=q._iO.position===b||isNaN(q._iO.position)?0:q._iO.position,q.isHTML5||(q._iO=U(T(q._iO))),q._iO.onplay&&c&&(q._iO.onplay.apply(q),r=!0),q.setVolume(q._iO.volume,!0),q.setPan(q._iO.pan,!0),q.isHTML5?q.instanceCount<2?(g(),f=q._setup_html5(),q.setPosition(q._iO.position),f.play()):(qa._wD(q.id+": Cloning Audio() for instance #"+q.instanceCount+"..."),k=new Audio(q._iO.url),m=function(){ha.remove(k,"ended",m),q._onfinish(q),ea(k),k=null},n=function(){ha.remove(k,"canplay",n);try{k.currentTime=q._iO.position/fb}catch(a){V(q.id+": multiShot play() failed to apply position of "+q._iO.position/fb)}k.play()},ha.add(k,"ended",m),void 0!==q._iO.volume&&(k.volume=Math.max(0,Math.min(1,q._iO.volume/100))),q.muted&&(k.muted=!0),q._iO.position?ha.add(k,"canplay",n):k.play()):(s=sa._start(q.id,q._iO.loops||1,9===l?q.position:q.position/fb,q._iO.multiShot||!1),9!==l||s||(qa._wD(d+"No sound hardware, or 32-sound ceiling hit",2),q._iO.onplayerror&&q._iO.onplayerror.apply(q)))}return q},this.start=this.play,this.stop=function(a){var b,c=q._iO;return 1===q.playState&&(qa._wD(q.id+": stop()"),q._onbufferchange(0),q._resetOnPosition(0),q.paused=!1,q.isHTML5||(q.playState=0),i(),c.to&&q.clearOnPosition(c.to),q.isHTML5?q._a&&(b=q.position,q.setPosition(0),q.position=b,q._a.pause(),q.playState=0,q._onTimer(),f()):(sa._stop(q.id,a),c.serverURL&&q.unload()),q.instanceCount=0,q._iO={},c.onstop&&c.onstop.apply(q)),q},this.setAutoPlay=function(a){qa._wD(q.id+": Autoplay turned "+(a?"on":"off")),q._iO.autoPlay=a,q.isHTML5||(sa._setAutoPlay(q.id,a),a&&(q.instanceCount||1!==q.readyState||(q.instanceCount++,qa._wD(q.id+": Incremented instance count to "+q.instanceCount))))},this.getAutoPlay=function(){return q._iO.autoPlay},this.setPosition=function(a){a===b&&(a=0);var c,d,e=q.isHTML5?Math.max(a,0):Math.min(q.duration||q._iO.duration,Math.max(a,0));if(q.position=e,d=q.position/fb,q._resetOnPosition(q.position),q._iO.position=e,q.isHTML5){if(q._a){if(q._html5_canplay){if(q._a.currentTime!==d){qa._wD(q.id+": setPosition("+d+")");try{q._a.currentTime=d,(0===q.playState||q.paused)&&q._a.pause()}catch(f){qa._wD(q.id+": setPosition("+d+") failed: "+f.message,2)}}}else if(d)return qa._wD(q.id+": setPosition("+d+"): Cannot seek yet, sound not ready",2),q;q.paused&&q._onTimer(!0)}}else c=9===l?q.position:d,q.readyState&&2!==q.readyState&&sa._setPosition(q.id,c,q.paused||!q.playState,q._iO.multiShot);return q},this.pause=function(a){return q.paused||0===q.playState&&1!==q.readyState?q:(qa._wD(q.id+": pause()"),q.paused=!0,q.isHTML5?(q._setup_html5().pause(),f()):(a||a===b)&&sa._pause(q.id,q._iO.multiShot),q._iO.onpause&&q._iO.onpause.apply(q),q)},this.resume=function(){var a=q._iO;return q.paused?(qa._wD(q.id+": resume()"),q.paused=!1,q.playState=1,q.isHTML5?(q._setup_html5().play(),g()):(a.isMovieStar&&!a.serverURL&&q.setPosition(q.position),sa._pause(q.id,a.multiShot)),!r&&a.onplay?(a.onplay.apply(q),r=!0):a.onresume&&a.onresume.apply(q),q):q},this.togglePause=function(){return qa._wD(q.id+": togglePause()"),0===q.playState?(q.play({position:9!==l||q.isHTML5?q.position/fb:q.position}),q):(q.paused?q.resume():q.pause(),q)},this.setPan=function(a,c){return a===b&&(a=0),c===b&&(c=!1),q.isHTML5||sa._setPan(q.id,a),q._iO.pan=a,c||(q.pan=a,q.options.pan=a),q},this.setVolume=function(a,c){return a===b&&(a=100),c===b&&(c=!1),q.isHTML5?q._a&&(qa.muted&&!q.muted&&(q.muted=!0,q._a.muted=!0),q._a.volume=Math.max(0,Math.min(1,a/100))):sa._setVolume(q.id,qa.muted&&!q.muted||q.muted?0:a),q._iO.volume=a,c||(q.volume=a,q.options.volume=a),q},this.mute=function(){return q.muted=!0,q.isHTML5?q._a&&(q._a.muted=!0):sa._setVolume(q.id,0),q},this.unmute=function(){q.muted=!1;var a=q._iO.volume!==b;return q.isHTML5?q._a&&(q._a.muted=!1):sa._setVolume(q.id,a?q._iO.volume:q.options.volume),q},this.toggleMute=function(){return q.muted?q.unmute():q.mute()},this.onPosition=function(a,c,d){return s.push({position:parseInt(a,10),method:c,scope:d!==b?d:q,fired:!1}),q},this.onposition=this.onPosition,this.clearOnPosition=function(a,b){var c;if(a=parseInt(a,10),isNaN(a))return!1;for(c=0;c<s.length;c++)a===s[c].position&&(b&&b!==s[c].method||(s[c].fired&&t--,s.splice(c,1)))},this._processOnPosition=function(){var a,b,c=s.length;if(!c||!q.playState||t>=c)return!1;for(a=c-1;a>=0;a--)b=s[a],!b.fired&&q.position>=b.position&&(b.fired=!0,t++,b.method.apply(b.scope,[b.position]),c=s.length);return!0},this._resetOnPosition=function(a){var b,c,d=s.length;if(!d)return!1;for(b=d-1;b>=0;b--)c=s[b],c.fired&&a<=c.position&&(c.fired=!1,t--);return!0},j=function(){var a,b,c=q._iO,d=c.from,e=c.to;return b=function(){qa._wD(q.id+': "To" time of '+e+" reached."),q.clearOnPosition(e,b),q.stop()},a=function(){qa._wD(q.id+': Playing "from" '+d),null===e||isNaN(e)||q.onPosition(e,b)},null===d||isNaN(d)||(c.position=d,c.multiShot=!1,a()),c},h=function(){var a,b=q._iO.onposition;if(b)for(a in b)b.hasOwnProperty(a)&&q.onPosition(parseInt(a,10),b[a])},i=function(){var a,b=q._iO.onposition;if(b)for(a in b)b.hasOwnProperty(a)&&q.clearOnPosition(parseInt(a,10))},g=function(){q.isHTML5&&X(q)},f=function(){q.isHTML5&&Y(q)},c=function(a){a||(s=[],t=0),r=!1,q._hasTimer=null,q._a=null,q._html5_canplay=!1,q.bytesLoaded=null,q.bytesTotal=null,q.duration=q._iO&&q._iO.duration?q._iO.duration:null,q.durationEstimate=null,q.buffered=[],q.eqData=[],q.eqData.left=[],q.eqData.right=[],q.failures=0,q.isBuffering=!1,q.instanceOptions={},q.instanceCount=0,q.loaded=!1,q.metadata={},q.readyState=0,q.muted=!1,q.paused=!1,q.peakData={left:0,right:0},q.waveformData={left:[],right:[]},q.playState=0,q.position=null,q.id3={}},c(),this._onTimer=function(a){var b,c,d=!1,e={};return q._hasTimer||a?(q._a&&(a||(q.playState>0||1===q.readyState)&&!q.paused)&&(b=q._get_html5_duration(),b!==k.duration&&(k.duration=b,q.duration=b,d=!0),q.durationEstimate=q.duration,c=q._a.currentTime*fb||0,c!==k.time&&(k.time=c,d=!0),(d||a)&&q._whileplaying(c,e,e,e,e)),d):void 0},this._get_html5_duration=function(){var a=q._iO,b=q._a&&q._a.duration?q._a.duration*fb:a&&a.duration?a.duration:null,c=b&&!isNaN(b)&&b!==1/0?b:null;return c},this._apply_loop=function(a,b){!a.loop&&b>1&&qa._wD("Note: Native HTML5 looping is infinite.",1),a.loop=b>1?"loop":""},this._setup_html5=function(a){var b,e=p(q._iO,a),f=Sa?ra:q._a,g=decodeURI(e.url);if(Sa?g===decodeURI(ia)&&(b=!0):g===decodeURI(u)&&(b=!0),f){if(f._s)if(Sa)f._s&&f._s.playState&&!b&&f._s.stop();else if(!Sa&&g===decodeURI(u))return q._apply_loop(f,e.loops),f;b||(u&&c(!1),f.src=e.url,q.url=e.url,u=e.url,ia=e.url,f._called_load=!1)}else e.autoLoad||e.autoPlay?(q._a=new Audio(e.url),q._a.load()):q._a=Za&&opera.version()<10?new Audio(null):new Audio,f=q._a,f._called_load=!1,Sa&&(ra=f);return q.isHTML5=!0,q._a=f,f._s=q,d(),q._apply_loop(f,e.loops),e.autoLoad||e.autoPlay?q.load():(f.autobuffer=!1,f.preload="auto"),f},d=function(){function a(a,b,c){return q._a?q._a.addEventListener(a,b,c||!1):null}if(q._a._added_events)return!1;var b;q._a._added_events=!0;for(b in ma)ma.hasOwnProperty(b)&&a(b,ma[b]);return!0},e=function(){function a(a,b,c){return q._a?q._a.removeEventListener(a,b,c||!1):null}var b;qa._wD(q.id+": Removing event listeners"),q._a._added_events=!1;for(b in ma)ma.hasOwnProperty(b)&&a(b,ma[b])},this._onload=function(a){var b,c=!!a||!q.isHTML5&&8===l&&q.duration;return b=q.id+": ",qa._wD(b+(c?"onload()":"Failed to load / invalid sound?"+(q.duration?" -":" Zero-length duration reported.")+" ("+q.url+")"),c?1:2),c||q.isHTML5||(qa.sandbox.noRemote===!0&&qa._wD(b+O("noNet"),1),qa.sandbox.noLocal===!0&&qa._wD(b+O("noLocal"),1)),q.loaded=c,q.readyState=c?3:2,q._onbufferchange(0),q._iO.onload&&pa(q,function(){q._iO.onload.apply(q,[c])}),!0},this._onbufferchange=function(a){return 0===q.playState?!1:a&&q.isBuffering||!a&&!q.isBuffering?!1:(q.isBuffering=1===a,q._iO.onbufferchange&&(qa._wD(q.id+": Buffer state change: "+a),q._iO.onbufferchange.apply(q,[a])),!0)},this._onsuspend=function(){return q._iO.onsuspend&&(qa._wD(q.id+": Playback suspended"),q._iO.onsuspend.apply(q)),!0},this._onfailure=function(a,b,c){q.failures++,qa._wD(q.id+": Failure ("+q.failures+"): "+a),q._iO.onfailure&&1===q.failures?q._iO.onfailure(a,b,c):qa._wD(q.id+": Ignoring failure")},this._onwarning=function(a,b,c){q._iO.onwarning&&q._iO.onwarning(a,b,c)},this._onfinish=function(){var a=q._iO.onfinish;q._onbufferchange(0),q._resetOnPosition(0),q.instanceCount&&(q.instanceCount--,q.instanceCount||(i(),q.playState=0,q.paused=!1,q.instanceCount=0,q.instanceOptions={},q._iO={},f(),q.isHTML5&&(q.position=0)),(!q.instanceCount||q._iO.multiShotEvents)&&a&&(qa._wD(q.id+": onfinish()"),pa(q,function(){a.apply(q)})))},this._whileloading=function(a,b,c,d){var e=q._iO;q.bytesLoaded=a,q.bytesTotal=b,q.duration=Math.floor(c),q.bufferLength=d,q.isHTML5||e.isMovieStar?q.durationEstimate=q.duration:e.duration?q.durationEstimate=q.duration>e.duration?q.duration:e.duration:q.durationEstimate=parseInt(q.bytesTotal/q.bytesLoaded*q.duration,10),q.isHTML5||(q.buffered=[{start:0,end:q.duration}]),(3!==q.readyState||q.isHTML5)&&e.whileloading&&e.whileloading.apply(q)},this._whileplaying=function(a,c,d,e,f){var g,h=q._iO;return isNaN(a)||null===a?!1:(q.position=Math.max(0,a),q._processOnPosition(),!q.isHTML5&&l>8&&(h.usePeakData&&c!==b&&c&&(q.peakData={left:c.leftPeak,right:c.rightPeak}),h.useWaveformData&&d!==b&&d&&(q.waveformData={left:d.split(","),right:e.split(",")}),h.useEQData&&f!==b&&f&&f.leftEQ&&(g=f.leftEQ.split(","),q.eqData=g,q.eqData.left=g,f.rightEQ!==b&&f.rightEQ&&(q.eqData.right=f.rightEQ.split(",")))),1===q.playState&&(q.isHTML5||8!==l||q.position||!q.isBuffering||q._onbufferchange(0),h.whileplaying&&h.whileplaying.apply(q)),!0)},this._oncaptiondata=function(a){qa._wD(q.id+": Caption data received."),q.captiondata=a,q._iO.oncaptiondata&&q._iO.oncaptiondata.apply(q,[a])},this._onmetadata=function(a,b){qa._wD(q.id+": Metadata received.");var c,d,e={};for(c=0,d=a.length;d>c;c++)e[a[c]]=b[c];q.metadata=e,console.log("updated metadata",q.metadata),q._iO.onmetadata&&q._iO.onmetadata.call(q,q.metadata)},this._onid3=function(a,b){qa._wD(q.id+": ID3 data received.");var c,d,e=[];for(c=0,d=a.length;d>c;c++)e[a[c]]=b[c];q.id3=p(q.id3,e),q._iO.onid3&&q._iO.onid3.apply(q)},this._onconnect=function(a){a=1===a,qa._wD(q.id+": "+(a?"Connected.":"Failed to connect? - "+q.url),a?1:2),q.connected=a,a&&(q.failures=0,W(q.id)&&(q.getAutoPlay()?q.play(b,q.getAutoPlay()):q._iO.autoLoad&&q.load()),q._iO.onconnect&&q._iO.onconnect.apply(q,[a]))},this._ondataerror=function(a){q.playState>0&&(qa._wD(q.id+": Data error: "+a),q._iO.ondataerror&&q._iO.ondataerror.apply(q))},this._debug()},G=function(){return ya.body||ya.getElementsByTagName("div")[0]},h=function(a){return ya.getElementById(a)},p=function(a,c){var d,e,f=a||{};d=c===b?qa.defaultOptions:c;for(e in d)d.hasOwnProperty(e)&&f[e]===b&&("object"!=typeof d[e]||null===d[e]?f[e]=d[e]:f[e]=p(f[e],d[e]));return f},pa=function(b,c){b.isHTML5||8!==l?c():a.setTimeout(c,0)},r={onready:1,ontimeout:1,defaultOptions:1,flash9Options:1,movieStarOptions:1},q=function(a,c){var d,e=!0,f=c!==b,g=qa.setupOptions,h=r;if(a===b){e=[];for(d in g)g.hasOwnProperty(d)&&e.push(d);for(d in h)h.hasOwnProperty(d)&&("object"==typeof qa[d]?e.push(d+": {...}"):qa[d]instanceof Function?e.push(d+": function() {...}"):e.push(d));return qa._wD(O("setup",e.join(", "))),!1}for(d in a)if(a.hasOwnProperty(d))if("object"!=typeof a[d]||null===a[d]||a[d]instanceof Array||a[d]instanceof RegExp)f&&h[c]!==b?qa[c][d]=a[d]:g[d]!==b?(qa.setupOptions[d]=a[d],qa[d]=a[d]):h[d]===b?(V(O(qa[d]===b?"setupUndef":"setupError",d),2),e=!1):qa[d]instanceof Function?qa[d].apply(qa,a[d]instanceof Array?a[d]:[a[d]]):qa[d]=a[d];else{if(h[d]!==b)return q(a[d],d);V(O(qa[d]===b?"setupUndef":"setupError",d),2),e=!1}return e},ha=function(){function b(a){var b=Ra.call(a),c=b.length;return f?(b[1]="on"+b[1],c>3&&b.pop()):3===c&&b.push(!1),b}function c(a,b){var c=a.shift(),d=[g[b]];f?c[d](a[0],a[1]):c[d].apply(c,a)}function d(){c(b(arguments),"add")}function e(){c(b(arguments),"remove")}var f=a.attachEvent,g={add:f?"attachEvent":"addEventListener",remove:f?"detachEvent":"removeEventListener"};return{add:d,remove:e}}(),ma={abort:f(function(){qa._wD(this._s.id+": abort")}),canplay:f(function(){var a,c=this._s;if(c._html5_canplay)return!0;if(c._html5_canplay=!0,qa._wD(c.id+": canplay"),c._onbufferchange(0),a=c._iO.position===b||isNaN(c._iO.position)?null:c._iO.position/fb,this.currentTime!==a){qa._wD(c.id+": canplay: Setting position to "+a);try{this.currentTime=a}catch(d){qa._wD(c.id+": canplay: Setting position of "+a+" failed: "+d.message,2)}}c._iO._oncanplay&&c._iO._oncanplay()}),canplaythrough:f(function(){var a=this._s;a.loaded||(a._onbufferchange(0),a._whileloading(a.bytesLoaded,a.bytesTotal,a._get_html5_duration()),a._onload(!0))}),durationchange:f(function(){var a,b=this._s;a=b._get_html5_duration(),isNaN(a)||a===b.duration||(qa._wD(this._s.id+": durationchange ("+a+")"+(b.duration?", previously "+b.duration:"")),b.durationEstimate=b.duration=a)}),ended:f(function(){var a=this._s;qa._wD(a.id+": ended"),a._onfinish()}),error:f(function(){qa._wD(this._s.id+": HTML5 error, code "+this.error.code),this._s._onload(!1)}),loadeddata:f(function(){var a=this._s;qa._wD(a.id+": loadeddata"),a._loaded||Ya||(a.duration=a._get_html5_duration())}),loadedmetadata:f(function(){qa._wD(this._s.id+": loadedmetadata")}),loadstart:f(function(){qa._wD(this._s.id+": loadstart"),this._s._onbufferchange(1)}),play:f(function(){this._s._onbufferchange(0)}),playing:f(function(){qa._wD(this._s.id+": playing "+String.fromCharCode(9835)),this._s._onbufferchange(0)}),progress:f(function(a){var b,c,d,e=this._s,f=0,g="progress"===a.type,h=a.target.buffered,i=a.loaded||0,j=a.total||1;if(e.buffered=[],h&&h.length){for(b=0,c=h.length;c>b;b++)e.buffered.push({start:h.start(b)*fb,end:h.end(b)*fb});if(f=(h.end(0)-h.start(0))*fb,i=Math.min(1,f/(a.target.duration*fb)),g&&h.length>1){for(d=[],c=h.length,b=0;c>b;b++)d.push(a.target.buffered.start(b)*fb+"-"+a.target.buffered.end(b)*fb);qa._wD(this._s.id+": progress, timeRanges: "+d.join(", "))}g&&!isNaN(i)&&qa._wD(this._s.id+": progress, "+Math.floor(100*i)+"% loaded")}isNaN(i)||(e._whileloading(i,j,e._get_html5_duration()),i&&j&&i===j&&ma.canplaythrough.call(this,a))}),ratechange:f(function(){qa._wD(this._s.id+": ratechange")}),suspend:f(function(a){var b=this._s;qa._wD(this._s.id+": suspend"),ma.progress.call(this,a),b._onsuspend()}),stalled:f(function(){qa._wD(this._s.id+": stalled")}),timeupdate:f(function(){this._s._onTimer()}),waiting:f(function(){var a=this._s;qa._wD(this._s.id+": waiting"),a._onbufferchange(1)})},ba=function(a){var b;return b=a&&(a.type||a.url||a.serverURL)?a.serverURL||a.type&&e(a.type)?!1:a.type?ca({type:a.type}):ca({url:a.url})||qa.html5Only||a.url.match(/data\:/i):!1},ea=function(a){var b;return a&&(b=Ya?gb:qa.html5.canPlayType("audio/wav")?hb:gb,a.src=b,void 0!==a._called_unload&&(a._called_load=!1)),Sa&&(ia=null),b},ca=function(a){if(!qa.useHTML5Audio||!qa.hasHTML5)return!1;var c,d,f,g,h=a.url||null,i=a.type||null,j=qa.audioFormats;if(i&&qa.html5[i]!==b)return qa.html5[i]&&!e(i);if(!da){da=[];for(g in j)j.hasOwnProperty(g)&&(da.push(g),j[g].related&&(da=da.concat(j[g].related)));da=new RegExp("\\.("+da.join("|")+")(\\?.*)?$","i")}return f=h?h.toLowerCase().match(da):null,f&&f.length?f=f[1]:i?(d=i.indexOf(";"),f=(-1!==d?i.substr(0,d):i).substr(6)):c=!1,f&&qa.html5[f]!==b?c=qa.html5[f]&&!e(f):(i="audio/"+f,c=qa.html5.canPlayType({type:i}),qa.html5[f]=c,c=c&&qa.html5[i]&&!e(i)),c},ga=function(){function a(a){var b,c,d=!1,e=!1;if(!g||"function"!=typeof g.canPlayType)return d;if(a instanceof Array){for(f=0,c=a.length;c>f;f++)(qa.html5[a[f]]||g.canPlayType(a[f]).match(qa.html5Test))&&(e=!0,qa.html5[a[f]]=!0,qa.flash[a[f]]=!!a[f].match(eb));d=e}else b=g&&"function"==typeof g.canPlayType?g.canPlayType(a):!1,d=!(!b||!b.match(qa.html5Test));return d}if(!qa.useHTML5Audio||!qa.hasHTML5)return qa.html5.usingFlash=!0,Qa=!0,!1;var c,d,e,f,g=Audio!==b?Za&&opera.version()<10?new Audio(null):new Audio:null,h={};e=qa.audioFormats;for(c in e)if(e.hasOwnProperty(c)&&(d="audio/"+c,h[c]=a(e[c].type),h[d]=h[c],c.match(eb)?(qa.flash[c]=!0,qa.flash[d]=!0):(qa.flash[c]=!1,qa.flash[d]=!1),e[c]&&e[c].related))for(f=e[c].related.length-1;f>=0;f--)h["audio/"+e[c].related[f]]=h[c],qa.html5[e[c].related[f]]=h[c],qa.flash[e[c].related[f]]=h[c];return h.canPlayType=g?a:null, +qa.html5=p(qa.html5,h),qa.html5.usingFlash=aa(),Qa=qa.html5.usingFlash,!0},A={notReady:"Unavailable - wait until onready() has fired.",notOK:"Audio support is not available.",domError:ta+"exception caught while appending SWF to DOM.",spcWmode:"Removing wmode, preventing known SWF loading issue(s)",swf404:ua+"Verify that %s is a valid path.",tryDebug:"Try "+ta+".debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:ua+"Non-HTTP page ("+ya.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, e.g. c:/sm2/ or /users/me/sm2/",waitFocus:ua+"Special case: Waiting for SWF to load with window focus...",waitForever:ua+"Waiting indefinitely for Flash (will recover if unblocked)...",waitSWF:ua+"Waiting for 100% SWF load...",needFunction:ua+"Function object expected for %s",badID:'Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:ua+"_debug(): Current sound objects",waitOnload:ua+"Waiting for window.onload()",docLoaded:ua+"Document already loaded",onload:ua+"initComplete(): calling soundManager.onload()",onloadOK:ta+".onload() complete",didInit:ua+"init(): Already called?",secNote:"Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",badRemove:ua+"Failed to remove Flash node.",shutdown:ta+".disable(): Shutting down",queue:ua+"Queueing %s handler",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+R.swfTimedout+" CSS...",fbLoaded:"Flash loaded",fbHandler:ua+"flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:ta+".load(): current URL already assigned.",badFV:ta+'.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",needFlash:ua+"Fatal error: Flash is needed to play some required formats, but is not available.",gotFocus:ua+"Got window focus.",policy:"Enabling usePolicyFile for data access",setup:ta+".setup(): allowed parameters: %s",setupError:ta+'.setup(): "%s" cannot be assigned with this method.',setupUndef:ta+'.setup(): Could not find option "%s"',setupLate:ta+".setup(): url, flashVersion and html5Test property changes will not take effect until reboot().",noURL:ua+"Flash URL required. Call soundManager.setup({url:...}) to get started.",sm2Loaded:"SoundManager 2: Ready. "+String.fromCharCode(10003),reset:ta+".reset(): Removing event callbacks",mobileUA:"Mobile UA detected, preferring HTML5 by default.",globalHTML5:"Using singleton HTML5 Audio() pattern for this device."},O=function(){var a,b,c,d,e;if(a=Ra.call(arguments),d=a.shift(),e=A&&A[d]?A[d]:"",e&&a&&a.length)for(b=0,c=a.length;c>b;b++)e=e.replace("%s",a[b]);return e},T=function(a){return 8===l&&a.loops>1&&a.stream&&(n("as2loop"),a.stream=!1),a},U=function(a,b){return a&&!a.usePolicyFile&&(a.onid3||a.usePeakData||a.useWaveformData||a.useEQData)&&(qa._wD((b||"")+O("policy")),a.usePolicyFile=!0),a},V=function(a){ab&&console.warn!==b?console.warn(a):qa._wD(a)},i=function(){return!1},L=function(a){var b;for(b in a)a.hasOwnProperty(b)&&"function"==typeof a[b]&&(a[b]=i);b=null},M=function(a){a===b&&(a=!1),(Ea||a)&&qa.disable(a)},N=function(a){var b,c=null;if(a)if(a.match(/\.swf(\?.*)?$/i)){if(c=a.substr(a.toLowerCase().lastIndexOf(".swf?")+4))return a}else a.lastIndexOf("/")!==a.length-1&&(a+="/");return b=(a&&-1!==a.lastIndexOf("/")?a.substr(0,a.lastIndexOf("/")+1):"./")+qa.movieURL,qa.noSWFCache&&(b+="?ts="+(new Date).getTime()),b},y=function(){l=parseInt(qa.flashVersion,10),8!==l&&9!==l&&(qa._wD(O("badFV",l,Ia)),qa.flashVersion=l=Ia);var a=qa.debugMode||qa.debugFlash?"_debug.swf":".swf";qa.useHTML5Audio&&!qa.html5Only&&qa.audioFormats.mp4.required&&9>l&&(qa._wD(O("needfl9")),qa.flashVersion=l=9),qa.version=qa.versionNumber+(qa.html5Only?" (HTML5-only mode)":9===l?" (AS3/Flash 9)":" (AS2/Flash 8)"),l>8?(qa.defaultOptions=p(qa.defaultOptions,qa.flash9Options),qa.features.buffering=!0,qa.defaultOptions=p(qa.defaultOptions,qa.movieStarOptions),qa.filePatterns.flash9=new RegExp("\\.(mp3|"+lb.join("|")+")(\\?.*)?$","i"),qa.features.movieStar=!0):qa.features.movieStar=!1,qa.filePattern=qa.filePatterns[8!==l?"flash9":"flash8"],qa.movieURL=(8===l?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",a),qa.features.peakData=qa.features.waveformData=qa.features.eqData=l>8},J=function(a,b){return sa?void sa._setPolling(a,b):!1},K=function(){if(qa.debugURLParam.test(xa)&&(qa.debugMode=!0),h(qa.debugID))return!1;var a,b,c,d,e;if(qa.debugMode&&!h(qa.debugID)&&(!ab||!qa.useConsole||!qa.consoleOnly)){a=ya.createElement("div"),a.id=qa.debugID+"-toggle",d={position:"fixed",bottom:"0px",right:"0px",width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001},a.appendChild(ya.createTextNode("-")),a.onclick=S,a.title="Toggle SM2 debug console",wa.match(/msie 6/i)&&(a.style.position="absolute",a.style.cursor="hand");for(e in d)d.hasOwnProperty(e)&&(a.style[e]=d[e]);if(b=ya.createElement("div"),b.id=qa.debugID,b.style.display=qa.debugMode?"block":"none",qa.debugMode&&!h(a.id)){try{c=G(),c.appendChild(a)}catch(f){throw new Error(O("domError")+" \n"+f.toString())}c.appendChild(b)}}c=null},W=this.getSoundById,n=function(a,b){return a?qa._wD(O(a),b):""},S=function(){var a=h(qa.debugID),b=h(qa.debugID+"-toggle");return a?(Aa?(b.innerHTML="+",a.style.display="none"):(b.innerHTML="-",a.style.display="block"),void(Aa=!Aa)):!1},m=function(c,d,e){if(a.sm2Debugger!==b)try{sm2Debugger.handleEvent(c,d,e)}catch(f){return!1}return!0},Q=function(){var a=[];return qa.debugMode&&a.push(R.sm2Debug),qa.debugFlash&&a.push(R.flashDebug),qa.useHighPerformance&&a.push(R.highPerf),a.join(" ")},P=function(){var a=O("fbHandler"),b=qa.getMoviePercent(),c=R,d={type:"FLASHBLOCK"};return qa.html5Only?!1:void(qa.ok()?(qa.didFlashBlock&&qa._wD(a+": Unblocked"),qa.oMC&&(qa.oMC.className=[Q(),c.swfDefault,c.swfLoaded+(qa.didFlashBlock?" "+c.swfUnblocked:"")].join(" "))):(Qa&&(qa.oMC.className=Q()+" "+c.swfDefault+" "+(null===b?c.swfTimedout:c.swfError),qa._wD(a+": "+O("fbTimeout")+(b?" ("+O("fbLoaded")+")":""))),qa.didFlashBlock=!0,t({type:"ontimeout",ignoreInit:!0,error:d}),I(d)))},s=function(a,c,d){za[a]===b&&(za[a]=[]),za[a].push({method:c,scope:d||null,fired:!1})},t=function(a){if(a||(a={type:qa.ok()?"onready":"ontimeout"}),!Da&&a&&!a.ignoreInit)return!1;if("ontimeout"===a.type&&(qa.ok()||Ea&&!a.ignoreInit))return!1;var b,c,d={success:a&&a.ignoreInit?qa.ok():!Ea},e=a&&a.type?za[a.type]||[]:[],f=[],g=[d],h=Qa&&!qa.ok();for(a.error&&(g[0].error=a.error),b=0,c=e.length;c>b;b++)e[b].fired!==!0&&f.push(e[b]);if(f.length)for(b=0,c=f.length;c>b;b++)f[b].scope?f[b].method.apply(f[b].scope,g):f[b].method.apply(this,g),h||(f[b].fired=!0);return!0},u=function(){a.setTimeout(function(){qa.useFlashBlock&&P(),t(),"function"==typeof qa.onload&&(n("onload",1),qa.onload.apply(a),n("onloadOK",1)),qa.waitForWindowLoad&&ha.add(a,"load",u)},1)},ka=function(){if(ja!==b)return ja;var c,d,e,f=!1,g=navigator,h=g.plugins,i=a.ActiveXObject;if(h&&h.length)d="application/x-shockwave-flash",e=g.mimeTypes,e&&e[d]&&e[d].enabledPlugin&&e[d].enabledPlugin.description&&(f=!0);else if(i!==b&&!wa.match(/MSAppHost/i)){try{c=new i("ShockwaveFlash.ShockwaveFlash")}catch(j){c=null}f=!!c,c=null}return ja=f,f},aa=function(){var a,b,c=qa.audioFormats,d=Ua&&!!wa.match(/os (1|2|3_0|3_1)\s/i);if(d?(qa.hasHTML5=!1,qa.html5Only=!0,qa.oMC&&(qa.oMC.style.display="none")):qa.useHTML5Audio&&(qa.html5&&qa.html5.canPlayType||(qa._wD("SoundManager: No HTML5 Audio() support detected."),qa.hasHTML5=!1),_a&&qa._wD(ua+"Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - "+(ja?"will use flash fallback for MP3/MP4, if available":" would use flash fallback for MP3/MP4, but none detected."),1)),qa.useHTML5Audio&&qa.hasHTML5){_=!0;for(b in c)c.hasOwnProperty(b)&&c[b].required&&(qa.html5.canPlayType(c[b].type)?qa.preferFlash&&(qa.flash[b]||qa.flash[c[b].type])&&(a=!0):(_=!1,a=!0))}return qa.ignoreFlash&&(a=!1,_=!0),qa.html5Only=qa.hasHTML5&&qa.useHTML5Audio&&!a,!qa.html5Only},$=function(a){var b,c,d,e=0;if(a instanceof Array){for(b=0,c=a.length;c>b;b++)if(a[b]instanceof Object){if(qa.canPlayMIME(a[b].type)){e=b;break}}else if(qa.canPlayURL(a[b])){e=b;break}a[e].url&&(a[e]=a[e].url),d=a[e]}else d=a;return d},X=function(a){a._hasTimer||(a._hasTimer=!0,!$a&&qa.html5PollingInterval&&(null===Oa&&0===Na&&(Oa=setInterval(Z,qa.html5PollingInterval)),Na++))},Y=function(a){a._hasTimer&&(a._hasTimer=!1,!$a&&qa.html5PollingInterval&&Na--)},Z=function(){var a;if(null!==Oa&&!Na)return clearInterval(Oa),Oa=null,!1;for(a=qa.soundIDs.length-1;a>=0;a--)qa.sounds[qa.soundIDs[a]].isHTML5&&qa.sounds[qa.soundIDs[a]]._hasTimer&&qa.sounds[qa.soundIDs[a]]._onTimer()},I=function(c){c=c!==b?c:{},"function"==typeof qa.onerror&&qa.onerror.apply(a,[{type:c.type!==b?c.type:null}]),c.fatal!==b&&c.fatal&&qa.disable()},la=function(){if(!_a||!ka())return!1;var a,b,c=qa.audioFormats;for(b in c)if(c.hasOwnProperty(b)&&("mp3"===b||"mp4"===b)&&(qa._wD(ta+": Using flash fallback for "+b+" format"),qa.html5[b]=!1,c[b]&&c[b].related))for(a=c[b].related.length-1;a>=0;a--)qa.html5[c[b].related[a]]=!1},this._setSandboxType=function(a){var c=qa.sandbox;c.type=a,c.description=c.types[c.types[a]!==b?a:"unknown"],"localWithFile"===c.type?(c.noRemote=!0,c.noLocal=!1,n("secNote",2)):"localWithNetwork"===c.type?(c.noRemote=!1,c.noLocal=!0):"localTrusted"===c.type&&(c.noRemote=!1,c.noLocal=!1)},this._externalInterfaceOK=function(a){if(qa.swfLoaded)return!1;var b;return m("swf",!0),m("flashtojs",!0),qa.swfLoaded=!0,cb=!1,_a&&la(),a&&a.replace(/\+dev/i,"")===qa.versionNumber.replace(/\+dev/i,"")?void setTimeout(k,Wa?100:1):(b=ta+': Fatal: JavaScript file build "'+qa.versionNumber+'" does not match Flash SWF build "'+a+'" at '+qa.url+". Ensure both are up-to-date.",setTimeout(function(){throw new Error(b)},0),!1)},H=function(a,c){function d(){var a,b=[],c=[],d=" + ";a="SoundManager "+qa.version+(!qa.html5Only&&qa.useHTML5Audio?qa.hasHTML5?" + HTML5 audio":", no HTML5 audio support":""),qa.html5Only?qa.html5PollingInterval&&b.push("html5PollingInterval ("+qa.html5PollingInterval+"ms)"):(qa.preferFlash&&b.push("preferFlash"),qa.useHighPerformance&&b.push("useHighPerformance"),qa.flashPollingInterval&&b.push("flashPollingInterval ("+qa.flashPollingInterval+"ms)"),qa.html5PollingInterval&&b.push("html5PollingInterval ("+qa.html5PollingInterval+"ms)"),qa.wmode&&b.push("wmode ("+qa.wmode+")"),qa.debugFlash&&b.push("debugFlash"),qa.useFlashBlock&&b.push("flashBlock")),b.length&&(c=c.concat([b.join(d)])),qa._wD(a+(c.length?d+c.join(", "):""),1),na()}function e(a,b){return'<param name="'+a+'" value="'+b+'" />'}if(Ba&&Ca)return!1;if(qa.html5Only)return y(),d(),qa.oMC=h(qa.movieID),k(),Ba=!0,Ca=!0,!1;var f,g,i,j,l,m,n,o,p=c||qa.url,q=qa.altURL||p,r="JS/Flash audio component (SoundManager 2)",s=G(),t=Q(),u=null,v=ya.getElementsByTagName("html")[0];if(u=v&&v.dir&&v.dir.match(/rtl/i),a=a===b?qa.id:a,y(),qa.url=N(ib?p:q),c=qa.url,qa.wmode=!qa.wmode&&qa.useHighPerformance?"transparent":qa.wmode,null!==qa.wmode&&(wa.match(/msie 8/i)||!Wa&&!qa.useHighPerformance)&&navigator.platform.match(/win32|win64/i)&&(Pa.push(A.spcWmode),qa.wmode=null),f={name:a,id:a,src:c,quality:"high",allowScriptAccess:qa.allowScriptAccess,bgcolor:qa.bgColor,pluginspage:jb+"www.macromedia.com/go/getflashplayer",title:r,type:"application/x-shockwave-flash",wmode:qa.wmode,hasPriority:"true"},qa.debugFlash&&(f.FlashVars="debug=1"),qa.wmode||delete f.wmode,Wa)g=ya.createElement("div"),j=['<object id="'+a+'" data="'+c+'" type="'+f.type+'" title="'+f.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+jb+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">',e("movie",c),e("AllowScriptAccess",qa.allowScriptAccess),e("quality",f.quality),qa.wmode?e("wmode",qa.wmode):"",e("bgcolor",qa.bgColor),e("hasPriority","true"),qa.debugFlash?e("FlashVars",f.FlashVars):"","</object>"].join("");else{g=ya.createElement("embed");for(i in f)f.hasOwnProperty(i)&&g.setAttribute(i,f[i])}if(K(),t=Q(),s=G())if(qa.oMC=h(qa.movieID)||ya.createElement("div"),qa.oMC.id)o=qa.oMC.className,qa.oMC.className=(o?o+" ":R.swfDefault)+(t?" "+t:""),qa.oMC.appendChild(g),Wa&&(l=qa.oMC.appendChild(ya.createElement("div")),l.className=R.swfBox,l.innerHTML=j),Ca=!0;else{if(qa.oMC.id=qa.movieID,qa.oMC.className=R.swfDefault+" "+t,m=null,l=null,qa.useFlashBlock||(qa.useHighPerformance?m={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(m={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},u&&(m.left=Math.abs(parseInt(m.left,10))+"px"))),Xa&&(qa.oMC.style.zIndex=1e4),!qa.debugFlash)for(n in m)m.hasOwnProperty(n)&&(qa.oMC.style[n]=m[n]);try{Wa||qa.oMC.appendChild(g),s.appendChild(qa.oMC),Wa&&(l=qa.oMC.appendChild(ya.createElement("div")),l.className=R.swfBox,l.innerHTML=j),Ca=!0}catch(w){throw new Error(O("domError")+" \n"+w.toString())}}return Ba=!0,d(),!0},B=function(){return qa.html5Only?(H(),!1):sa?!1:qa.url?(sa=qa.getMovie(qa.id),sa||(Ja?(Wa?qa.oMC.innerHTML=Ka:qa.oMC.appendChild(Ja),Ja=null,Ba=!0):H(qa.id,qa.url),sa=qa.getMovie(qa.id)),"function"==typeof qa.oninitmovie&&setTimeout(qa.oninitmovie,1),oa(),!0):(n("noURL"),!1)},v=function(){setTimeout(w,1e3)},x=function(){a.setTimeout(function(){V(ua+"useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false..."),qa.setup({preferFlash:!1}).reboot(),qa.didFlashBlock=!0,qa.beginDelayedInit()},1)},w=function(){var b,c=!1;return qa.url?La?!1:(La=!0,ha.remove(a,"load",v),ja&&cb&&!bb?(n("waitFocus"),!1):(Da||(b=qa.getMoviePercent(),b>0&&100>b&&(c=!0)),void setTimeout(function(){return b=qa.getMoviePercent(),c?(La=!1,qa._wD(O("waitSWF")),a.setTimeout(v,1),!1):(Da||(qa._wD(ta+": No Flash response within expected time. Likely causes: "+(0===b?"SWF load failed, ":"")+"Flash blocked or JS-Flash security error."+(qa.debugFlash?" "+O("checkSWF"):""),2),!ib&&b&&(n("localFail",2),qa.debugFlash||n("tryDebug",2)),0===b&&qa._wD(O("swf404",qa.url),1),m("flashtojs",!1," (Check flash security or flash blockers)")),void(!Da&&db&&(null===b?qa.useFlashBlock||0===qa.flashLoadTimeout?(qa.useFlashBlock&&P(),n("waitForever")):!qa.useFlashBlock&&_?x():(n("waitForever"),t({type:"ontimeout",ignoreInit:!0,error:{type:"INIT_FLASHBLOCK"}})):0===qa.flashLoadTimeout?n("waitForever"):!qa.useFlashBlock&&_?x():M(!0))))},qa.flashLoadTimeout))):!1},z=function(){function b(){ha.remove(a,"focus",z)}return bb||!cb?(b(),!0):(db=!0,bb=!0,n("gotFocus"),La=!1,v(),b(),!0)},oa=function(){Pa.length&&(qa._wD("SoundManager 2: "+Pa.join(" "),1),Pa=[])},na=function(){oa();var a,b=[];if(qa.useHTML5Audio&&qa.hasHTML5){for(a in qa.audioFormats)qa.audioFormats.hasOwnProperty(a)&&b.push(a+" = "+qa.html5[a]+(!qa.html5[a]&&Qa&&qa.flash[a]?" (using flash)":qa.preferFlash&&qa.flash[a]&&Qa?" (preferring flash)":qa.html5[a]?"":" ("+(qa.audioFormats[a].required?"required, ":"")+"and no flash support)"));qa._wD("SoundManager 2 HTML5 support: "+b.join(", "),1)}},o=function(b){if(Da)return!1;if(qa.html5Only)return n("sm2Loaded",1),Da=!0,u(),m("onload",!0),!0;var c,d=qa.useFlashBlock&&qa.flashLoadTimeout&&!qa.getMoviePercent(),e=!0;return d||(Da=!0),c={type:!ja&&Qa?"NO_FLASH":"INIT_TIMEOUT"},qa._wD("SoundManager 2 "+(Ea?"failed to load":"loaded")+" ("+(Ea?"Flash security/load error":"OK")+") "+String.fromCharCode(Ea?10006:10003),Ea?2:1),Ea||b?(qa.useFlashBlock&&qa.oMC&&(qa.oMC.className=Q()+" "+(null===qa.getMoviePercent()?R.swfTimedout:R.swfError)),t({type:"ontimeout",error:c,ignoreInit:!0}),m("onload",!1),I(c),e=!1):m("onload",!0),Ea||(qa.waitForWindowLoad&&!Fa?(n("waitOnload"),ha.add(a,"load",u)):(qa.waitForWindowLoad&&Fa&&n("docLoaded"),u())),e},j=function(){var a,c=qa.setupOptions;for(a in c)c.hasOwnProperty(a)&&(qa[a]===b?qa[a]=c[a]:qa[a]!==c[a]&&(qa.setupOptions[a]=qa[a]))},k=function(){function b(){ha.remove(a,"load",qa.beginDelayedInit)}if(Da)return n("didInit"),!1;if(qa.html5Only)return Da||(b(),qa.enabled=!0,o()),!0;B();try{sa._externalInterfaceTest(!1),J(!0,qa.flashPollingInterval||(qa.useHighPerformance?10:50)),qa.debugMode||sa._disableDebug(),qa.enabled=!0,m("jstoflash",!0),qa.html5Only||ha.add(a,"unload",i)}catch(c){return qa._wD("js/flash exception: "+c.toString()),m("jstoflash",!1),I({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),M(!0),o(),!1}return o(),b(),!0},D=function(){return F?!1:(F=!0,j(),K(),function(){var a="sm2-usehtml5audio=",b="sm2-preferflash=",c=null,d=null,e=xa.toLowerCase();-1!==e.indexOf(a)&&(c="1"===e.charAt(e.indexOf(a)+a.length),ab&&console.log((c?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"),qa.setup({useHTML5Audio:c})),-1!==e.indexOf(b)&&(d="1"===e.charAt(e.indexOf(b)+b.length),ab&&console.log((d?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),qa.setup({preferFlash:d}))}(),!ja&&qa.hasHTML5&&(qa._wD("SoundManager 2: No Flash detected"+(qa.useHTML5Audio?". Trying HTML5-only mode.":", enabling HTML5."),1),qa.setup({useHTML5Audio:!0,preferFlash:!1})),ga(),!ja&&Qa&&(Pa.push(A.needFlash),qa.setup({flashLoadTimeout:1})),ya.removeEventListener&&ya.removeEventListener("DOMContentLoaded",D,!1),B(),!0)},fa=function(){return"complete"===ya.readyState&&(D(),ya.detachEvent("onreadystatechange",fa)),!0},E=function(){Fa=!0,D(),ha.remove(a,"load",E)},C=function(){$a&&((!qa.setupOptions.useHTML5Audio||qa.setupOptions.preferFlash)&&Pa.push(A.mobileUA),qa.setupOptions.useHTML5Audio=!0,qa.setupOptions.preferFlash=!1,(Ua||Va&&!wa.match(/android\s2\.3/i))&&(Pa.push(A.globalHTML5),Ua&&(qa.ignoreFlash=!0),Sa=!0))},C(),ka(),ha.add(a,"focus",z),ha.add(a,"load",v),ha.add(a,"load",E),ya.addEventListener?ya.addEventListener("DOMContentLoaded",D,!1):ya.attachEvent?ya.attachEvent("onreadystatechange",fa):(m("onload",!1),I({type:"NO_DOM2_EVENTS",fatal:!0}))}if(!a||!a.document)throw new Error("SoundManager requires a browser with window and document objects.");var d=null;void 0!==a.SM2_DEFER&&SM2_DEFER||(d=new c),"object"==typeof module&&module&&"object"==typeof module.exports?(a.soundManager=d,module.exports.SoundManager=c,module.exports.soundManager=d):"function"==typeof define&&define.amd?define("SoundManager",[],function(){return{SoundManager:c,soundManager:d}}):(a.SoundManager=c,a.soundManager=d)}(window),window.JST["apps/album/show/tpl/album_with_songs.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="album album--with-songs">\n <div class="region-album-side">\n <div class="region-album-meta"></div>\n </div>\n <div class="region-album-content">\n <div class="region-album-songs"></div>\n </div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/album/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub"><a href="#music/albums?year=')),d(this.year),d(b('">')),d(this.year),d(b("</a></span></h2>\n </div>\n ")),this.rating&&(d(b('\n <div class="region-details-rating">\n ')),d(this.rating),d(b(" <i></i>\n </div>\n "))),d(b('\n</div>\n\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.artist&&(d(b("\n <li><label>")),d(tr("artist")),d(b(':</label> <span><a href="#music/artist/')),d(this.artistid),d(b('">')),d(this.artist),d(b("</a></span></li>\n "))),d(b("\n ")),this.genre.length>0&&(d(b("\n <li><label>")),d(t.ngettext("genre","genres",this.genre.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.style.length&&(d(b("\n <li><label>")),d(t.ngettext("style","styles",this.style.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","style",this.style))),d(b("</span></li>\n "))),d(b("\n ")),this.albumlabel&&(d(b("\n <li><label>")),d(tr("label")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/albums","albumlabel",[this.albumlabel]))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <div class="description">')),d(this.description),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream localplay">')),d(tr("Stream")),d(b('</li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="localadd">')),d(tr("Add to playlist")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.artist),d(b(" ")),d(this.label),d(b('">Google</li>\n <li data-type="soundcloud" data-query="')),d(this.artist),d(b('">SoundCloud</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.artist),d(b(" ")),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/artist/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2>')),d(this.label),d(b('</h2>\n </div>\n</div>\n\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(t.ngettext("genre","genres",this.genre.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/artists","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.style.length&&(d(b("\n <li><label>")),d(t.ngettext("style","styles",this.style.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/artists","style",this.style))),d(b("</span></li>\n "))),d(b("\n ")),this.formed&&(d(b("\n <li><label>")),d(tr("formed")),d(b(":</label> <span>")),d(this.formed),d(b("</span></li>\n "))),d(b("\n ")),this.yearsactive&&this.yearsactive.length>0&&(d(b("\n <li><label>")),d(tr("years active")),d(b(":</label> <span>")),d(this.yearsactive),d(b("</span></li>\n "))),d(b("\n ")),this.born&&(d(b("\n <li><label>")),d(tr("born")),d(b(":</label> <span>")),d(this.born),d(b("</span></li>\n "))),d(b("\n ")),this.died&&(d(b("\n <li><label>")),d(tr("died")),d(b(":</label> <span>")),d(this.died),d(b("</span></li>\n "))),d(b("\n ")),this.disbanded&&(d(b("\n <li><label>")),d(tr("disbanded")),d(b(":</label> <span>")),d(this.disbanded),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <div class="description">')),d(this.description),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream localplay">')),d(tr("Stream")),d(b('</li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="localadd">')),d(tr("Add to playlist")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="soundcloud" data-query="')),d(this.label),d(b('">SoundCloud</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/back_button.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<i class="mdi thumb"></i><div class="title">')),d(t.gettext("Back")),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/file.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="thumb" style="background-image: url(\'')),d(this.thumbnail),d(b('\')"><div class="mdi play"></div></div>\n<div class="title" title="')),d(helpers.global.stripTags(this.label)),d(b('">')),d(b(this.label)),d(b('</div>\n<ul class="actions">\n <li class="menu dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu pull-right"></ul>\n </li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/folder_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="folder-layout">\n <div class="loading-bar"><div class="inner"><div class="loader-small-inline"></div> <span>')),d(tr("Loading folder...")),d(b('</span></div></div>\n <div class="path"></div>\n <ul class="actions">\n <li class="dropdown sort-wrapper">\n <i class="sort-toggle" data-toggle="dropdown" title="')),d(tr("Sort")),d(b('"></i>\n <ul class="sorts dropdown-menu pull-right">\n <li data-sort="none">')),d(tr("default")),d(b('<i></i></li>\n <li data-sort="label">')),d(tr("title")),d(b('<i></i></li>\n <li data-sort="dateadded">')),d(tr("date added")),d(b('<i></i></li>\n <li data-sort="random">')),d(tr("random")),d(b('<i></i></li>\n </ul>\n </li>\n <li class="dropdown context-wrapper">\n <i class="context-toggle" data-toggle="dropdown" title="')),d(tr("Actions")),d(b('"></i>\n <ul class="dropdown-menu pull-right">\n <li class="play">')),d(tr("play files")),d(b('<i></i></li>\n <li class="queue">')),d(tr("queue files")),d(b('<i></i></li>\n </ul>\n </li>\n </ul>\n\n\n <div class="folder-container">\n <div class="files">\n </div>\n <div class="folders-pane">\n <div class="back"></div>\n <div class="folders">\n <div class="intro">\n <h3><span class="mdi-navigation-arrow-back text-dim"></span> ')),d(tr("Browse files and add-ons")),d(b("</h3>\n <p>")),d(tr("This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.")),d(b("</p>\n </div>\n </div>\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/path.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">')),d(this.label),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/source.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="source source-')),d(this.media),d(b('">\n ')),d(this.label),d(b("\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/browser/list/tpl/source_set.jst"]=function(a){ +var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.label),d(b('</h3>\n<ul class="sources"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/cast/list/tpl/cast.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a href="#')),d(this.origin),d(b("?cast=")),d(this.name),d(b('" title="')),d(this.name),d(b(" (")),d(this.role),d(b(')">\n <div class="thumb">\n <img src="')),d(this.thumbnail),d(b('" />\n </div>\n <div class="meta">\n <strong>')),d(this.name),d(b('</strong>\n <span title="')),d(this.role),d(b('">')),d(this.role),d(b('</span>\n </div>\n</a>\n<ul class="actions">\n <li class="imdb" title="IMDb search ')),d(this.name),d(b('"></li>\n <li class="google" title="Google search ')),d(this.name),d(b('"></li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/category/list/tpl/item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a href="#')),d(this.url),d(b('">\n <span>')),d(this.title),d(b("</span>\n</a>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/epg/list/tpl/channel.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.channel),d(b('</h3>\n<ul class="items">\n <li class="play">')),d(tr("Play")),d(b('</li>\n <li class="record">')),d(tr("Record")),d(b("</li>\n</ul>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/epg/list/tpl/programme.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">\n <strong>')),d(this.label),d(b('</strong>\n</div>\n<div class="date">\n ')),d(this.start.toString("h:mmtt").toLowerCase()),d(b(" - ")),d(this.end.toString("h:mmtt").toLowerCase()),d(b(" (")),d(this.runtime),d(b("min)<br />\n ")),d(this.start.toString("dddd, dS MMM")),d(b('\n</div>\n<div class="plot">')),d(this.plot),d(b('</div>\n<div class="entity-progress">\n <div class="current-progress" style="width: ')),d(this.progresspercentage),d(b('%" title="')),d(Math.round(this.progresspercentage)),d(b("% ")),d(tr("complete")),d(b('"></div>\n</div>\n<ul class="actions">\n ')),this.isactive?(d(b('\n <li class="play" title="')),d(tr("Play")),d(b('"></li>\n <li class="record" title="')),d(tr("Record")),d(b('"></li>\n '))):(d(b("\n ")),this.wasactive||(d(b('\n <li class="toggle-timer" title="')),d(tr("Toggle timer")),d(b('"></li>\n '))),d(b("\n "))),d(b("\n</ul>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/external/youtube/tpl/youtube.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<img src="')),d(this.thumbnail),d(b('" class="thumb" />\n<h3>')),d(this.title),d(b("</h3>\n")),d(this.addonEnabled?b('\n <span class="play flat-btn action">Play in Kodi</span>\n <span class="localplay flat-btn action">Play in browser</span>\n'):b('\n <span class="play flat-btn action">Play in browser</span>\n')),d(b("\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filter_options.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="options-search-wrapper">\n <input class="options-search" value="" />\n</div>\n<div class="deselect-all">')),d(t.gettext("Deselect all")),d(b('</div>\n<ul class="selection-list"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filters_bar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<span class="filters-active-all">')),d(this.filters),d(b('</span><i class="remove"></i>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/filters_ui.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="filters-container">\n\n <div class="filters-current filter-pane">\n <div class="nav-section"></div>\n\n <h3 class="open-filters">')),d(t.gettext("Filters")),d(b('<i></i></h3>\n <div class="filters-active"></div>\n\n <h3>')),d(t.gettext("Sort")),d(b('</h3>\n <div class="list sort-options"></div>\n </div>\n\n <div class="filters-page filter-pane">\n <h3 class="close-filters">')),d(t.gettext("Select a filter")),d(b('</h3>\n <div class="list filters-list"></div>\n </div>\n\n <div class="filters-options filter-pane">\n <h3 class="close-options">')),d(t.gettext("Select an option")),d(b('</h3>\n <div class="list filter-options-list"></div>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/filter/show/tpl/list_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b(this.title))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/help/overview/tpl/overview.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h1>")),d(tr("About Chorus")),d(b("</h1>\n<h2>")),d(tr("Status report")),d(b('</h2>\n<div class="help--overview--report">\n <ul>\n <li class="report-chorus-version"><strong>Chorus ')),d(tr("version")),d(b('</strong><span></span></li>\n <li class="report-kodi-version"><strong>Kodi ')),d(tr("version")),d(b('</strong><span></span></li>\n <li class="report-websockets"><strong>')),d(tr("Remote control")),d(b('</strong><span></span></li>\n <li class="report-local-audio"><strong>')),d(tr("Local audio")),d(b('</strong><span></span></li>\n </ul>\n</div>\n<div class="help--overview--header"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/input/remote/tpl/remote_control.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="remote-background" class="close-remote"></div>\n<div class="remote kodi-remote">\n <div class="toggle-visibility"></div>\n <div class="playing-area">\n\n </div>\n <div class="main-controls">\n <div class="direction">\n <div class="pad">\n <div class="ibut mdi-hardware-keyboard-arrow-left left input-button" data-type="Left"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-up up input-button" data-type="Up"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-down down input-button" data-type="Down"></div>\n <div class="ibut mdi-hardware-keyboard-arrow-right right input-button" data-type="Right"></div>\n <div class="ibut mdi-image-brightness-1 ok input-button" data-type="Select"></div>\n </div>\n </div>\n <div class="buttons">\n <div class="ibut mdi-action-settings-power power-button"></div>\n <div class="ibut mdi-navigation-more-vert input-button" data-type="ContextMenu"></div>\n <div class="ibut mdi-action-info info-button" data-type="Info"></div>\n </div>\n </div>\n <div class="secondary-controls">\n <div class="ibut mdi-hardware-keyboard-return input-button" data-type="Back"></div>\n <div class="ibut mdi-av-stop player-button" data-type="Stop"></div>\n <div class="ibut mdi-maps-store-mall-directory input-button" data-type="Home"></div>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/input/remote/tpl/system.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;for(d(b('<ul class="system-menu__options options">\n ')),f=this.actions,c=0,e=f.length;e>c;c++)a=f[c],d(b('\n <li data-action="')),d(a.id),d(b('">')),d(a.title),d(b("</li>\n "));d(b("\n</ul>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_browser_landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-browser--landing page">\n <h2>')),d(t.gettext("Kodi API browser")),d(b('</h2>\n <h4><a href="#lab">')),d(t.gettext("Chorus lab")),d(b('</a></h4>\n <div class="api-browser--content">\n <p>')),d(t.gettext("This is a tool to test out the api. Select a method then execute it with parameters.")),d(b('</p>\n <br />\n <div class="alert alert-dismissable alert-warning">\n <button type="button" class="close" data-dismiss="alert">×</button>\n <h4>')),d(t.gettext("Warning")),d(b("</h4>\n <p>")),d(t.gettext("You could potentially damage your system with this and there are no sanity checks. Use at own risk.")),d(b("<br /></p>\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-method--item">\n <h4 class="method">')),d(this.method),d(b('</h4>\n <p class="description">')),d(this.description),d(b("</p>\n</div>\n\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="api-methods--list">\n <p class="search-box"><input type="text" id="api-search" class="api-methods--search" /></p>\n <ul class="items"></ul>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/apiBrowser/tpl/api_method_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('\n<div class="api-method--info page">\n <h2 class="method"><a href="http://kodi.wiki/view/JSON-RPC_API/v6#')),d(this.method),d(b('" target="_blank">')),d(this.method),d(b('</a></h2>\n <p class="description">')),d(this.description),d(b("</p>\n\n</div>\n\n")),"method"===this.type&&(d(b('\n <div class="api-method--execute">\n <h3>Execute <strong>')),d(this.method),d(b('</strong> with these params:</h3>\n <textarea class="api-method--params" placeholder=\'Eg. ["arg", "foo", true]\'></textarea>\n <p class="description">Parameters get parsed by\n <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" target="_blank">JSON.parse</a>.\n Check the console for response objects, you will get an \'unexpected token\' error if parsing failed.\n Params should be an array \'[]\' matching below \'Method params\'. Only use double quotes for strings/keys.\n </p>\n <p class="description">\n Pass params as array Eg. [true] or [255, ["born", "formed", "thumbnail"]] or [] or [255]. Brackets required.<br />\n Pass params as object Eg. {songid: 255} or {songid: 255, fields: ["born", "formed", "thumbnail"]}. Braces required.<br />\n </p>\n <p><button class="btn btn-primary" id="send-command">Send Command</button></p>\n\n </div>\n'))),d(b('\n\n<div class="api-method--result" id="api-result"></div>\n\n<h3>')),"method"===this.type&&d(b("Method ")),d(b('Params</h3>\n<div class="api-method--params"></div>\n\n')),"method"===this.type&&d(b('\n <hr />\n <h3>Method Returns</h3>\n <div class="api-method--return"></div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/iconBrowser/tpl/icon_browser_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h3>Material Icons</h3>\n<ul id="icons-material"></ul>\n\n<h3>Custom Icons</h3>\n<ul id="icons-custom"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/lab/lab/tpl/lab_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a class="lab-item" href="#')),d(this.path),d(b('">\n <h4>')),d(this.title),d(b("</h4>\n <p>")),d(this.description),d(b("</p>\n</a>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/landing/show/tpl/landing_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<a id="landing-hero"></a>\n<div class="landing-sections">\n <div id="landing-section-1"></div>\n <div id="landing-section-2"></div>\n <div id="landing-section-3"></div>\n <div id="landing-section-4"></div>\n <div id="landing-section-5"></div>\n <div id="landing-section-6"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/loading/show/tpl/loading_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="loading-page">\n <div class="spinner-double-section-far"></div>\n <h2>')),d(t.gettext("Just a sec...")),d(b("</h2>\n</div>\n\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<span class="item">')),d(b(this.title)),d(b("</span>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="local-playlist-header">\n <h2></h2>\n <div class="dropdown">\n <i data-toggle="dropdown"></i>\n <ul class="dropdown-menu">\n <li class="play">')),d(tr("Play in Kodi")),d(b('</li>\n <li class="localplay">')),d(tr("Play in browser")),d(b('</li>\n <li class="export">')),d(tr("Export list")),d(b('</li>\n <div class="divider"></div>\n <li class="rename">')),d(tr("Rename playlist")),d(b('</li>\n <li class="clear">')),d(tr("Clear playlist")),d(b('</li>\n <li class="delete">')),d(tr("Delete playlist")),d(b('</li>\n </ul>\n </div>\n</div>\n<div class="item-container">\n <div class="empty-content">')),d(t.gettext("Empty playlist, you should probably add something to it?")),d(b("</div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h3></h3>\n<ul class="lists options"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/localPlaylist/list/tpl/playlist_sidebar_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="current-lists"></div>\n<div class="new-list">')),d(tr("New playlist")),d(b("</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/content.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="section-content">\n <h2>')),d(t.gettext("Synopsis")),d(b("</h2>\n ")),this.mediaTrailer&&"youtube"===this.mediaTrailer.source&&(d(b('\n <div class="trailer ')),d(this.mediaTrailer.source),d(b('">\n <img src="')),d(b(this.mediaTrailer.img)),d(b('" />\n </div>\n '))),d(b("\n <p>")),d(this.plot),d(b('</p>\n <ul class="inline-links">\n <li>')),d(b(helpers.url.imdbUrl(this.imdbnumber,"View on IMDb"))),d(b("</li>\n </ul>\n</div>\n\n")),this.cast.length>0&&(d(b('\n <div class="section-content">\n <h2>')),d(t.gettext("Full cast")),d(b('</h2>\n <div class="region-cast"></div>\n </div>\n'))),d(b('\n\n<div class="region-more-1"></div>\n<div class="region-more-2"></div>\n<div class="region-more-3"></div>\n<div class="region-more-4"></div>\n<div class="region-more-5"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;if(d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub"><a href="#movies?year=')),d(this.year),d(b('">')),d(this.year),d(b('</a></span></h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n\n<div class="region-details-meta-below">\n\n <div class="region-details-subtext">\n <div class="runtime">\n ')),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b('\n </div>\n </div>\n\n <div class="tagline">')),d(this.plotoutline),d(b('</div>\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(t.gettext("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.director.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Director","Directors",this.director.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","director",this.director))),d(b("</span></li>\n "))),d(b("\n ")),this.writer.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Writer","Writers",this.writer.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","writer",this.writer))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(t.gettext("Cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(t.gettext("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("movies","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <ul class="streams">\n ')),this.streamdetails.video.length>0&&(d(b("\n <li><label>")),d(t.gettext("Video")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.video,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.audio.length>0&&(d(b("\n <li><label>")),d(t.gettext("Audio")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.audio,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.subtitle.length>0&&""!==this.streamdetails.subtitle[0].label){for(d(b("\n <li><label>")),d(t.ngettext("Subtitle","Subtitles",this.streamdetails.subtitle.length)),d(b(':</label>\n <span class="dropdown"><span data-toggle="dropdown">')),d(_.pluck(this.streamdetails.subtitle,"label").join(", ")),d(b('</span>\n <ul class="dropdown-menu">\n ')),e=this.streamdetails.subtitle,a=0,c=e.length;c>a;a++)f=e[a],d(b("\n <li>")),d(f.label),d(b("</li>\n "));d(b("\n </ul>\n </span>\n </li>\n "))}d(b('\n </ul>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(t.gettext("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream stream">')),d(t.gettext("Stream")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(t.gettext("set")),d(b(' <span class="action-watched">')),d(t.gettext("watched")),d(b('</span><span class="action-unwatched">')),d(t.gettext("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="download">')),d(tr("Download")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.label),d(b('">IMDb</li>\n <li data-type="tmdb" data-query="')),d(this.label),d(b('">TVDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="refresh">')),d(tr("Refresh")),d(b('</li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/movie/show/tpl/set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="section-content">\n <div class="set-collection">\n <h2 class="set-name"></h2>\n <div class="collection-items"></div>\n </div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/musicvideo/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b("</span></h2>\n </div>\n ")),this.rating&&(d(b('\n <div class="region-details-rating">\n ')),d(this.rating),d(b(" <i></i>\n </div>\n "))),d(b('\n</div>\n\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.artist&&(d(b("\n <li><label>")),d(tr("artist")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/videos","artist",[this.artist]))),d(b("</span></li>\n "))),d(b("\n ")),this.album&&(d(b("\n <li><label>")),d(tr("album")),d(b(':</label> <span><a href="#music/videos?album=')),d(this.album),d(b('">')),d(this.album),d(b("</a></span></li>\n "))),d(b("\n ")),this.genre.length>0&&(d(b("\n <li><label>")),d(t.ngettext("genre","genres",this.genre.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/videos","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.director.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Director","Directors",this.director.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/videos","director",this.director))),d(b("</span></li>\n "))),d(b("\n ")),this.studio.length>0&&(d(b("\n <li><label>")), +d(t.ngettext("Studio","Studios",this.studio.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("music/videos","studio",this.studio))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <div class="description">')),d(this.plot),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream localplay">')),d(tr("Stream")),d(b('</li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="download">')),d(tr("Download")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.title))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.title),d(b(" ")),d(this.artist),d(b('">Google</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.title),d(b(" ")),d(this.artist),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/navMain.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f,g,h,i,j;for(d(b('<div id="nav-header"></div>\n<nav>\n <ul>\n ')),i=this.items,c=0,g=i.length;g>c;c++)if(e=i[c],"undefined"!==e.path&&0===e.parent){if(d(b('\n <li class="')),d(e["class"]),d(b('">\n <a href="#')),d(e.path),d(b('">\n <i class="')),d(e.icon),d(b('"></i>\n <span>')),d(e.title),d(b("</span>\n </a>\n\n ")),0!==e.children.length){for(d(b("\n <ul>\n ")),j=e.children,f=0,h=j.length;h>f;f++)a=j[f],"undefined"!==a.path&&(d(b('\n <li><a href="#')),d(a.path),d(b('">')),d(a.title),d(b("</a></li>\n ")));d(b("\n </ul>\n "))}d(b("\n </li>\n "))}d(b("\n </ul>\n</nav>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/nav_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b(this.link))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/navMain/show/tpl/nav_sub.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<h3>")),d(this.title),d(b('</h3>\n<ul class="items"></ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/player/show/tpl/player.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="player">\n\n <div class="controls-primary">\n <div class="controls-primary-buttons">\n <div class="control control-prev"></div>\n <div class="control control-play"></div>\n <div class="control control-next"></div>\n </div>\n </div>\n\n <div class="controls-secondary">\n <div class="volume slider-bar"></div>\n <div class="controls-secondary-buttons">\n <div class="control control-mute"></div>\n <div class="control control-repeat"></div>\n <div class="control control-shuffle"></div>\n <div class="control control-menu"></div>\n </div>\n </div>\n\n <div class="now-playing">\n <div class="playing-thumb thumb">\n <div class="mdi remote-toggle"></div>\n </div>\n <div class="playing-info">\n <div class="playing-progress slider-bar"></div>\n <div class="playing-time">\n <div class="playing-time-current">0</div>\n <div class="playing-time-duration">0:00</div>\n </div>\n <div class="playing-meta">\n <div class="playing-title">')),d(t.gettext("Nothing playing")),d(b('</div>\n <div class="playing-subtitle"></div>\n </div>\n </div>\n </div>\n\n</div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/list/tpl/playlist_bar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="playlist-header">\n <ul class="player-toggle">\n <li class="kodi">')),d(t.gettext("Kodi")),d(b('</li>\n <li class="local">')),d(t.gettext("Local")),d(b('</li>\n </ul>\n <div class="playlist-menu dropdown">\n <i data-toggle="dropdown" class="menu-toggle"></i>\n <ul class="dropdown-menu pull-right">\n <li class="dropdown-header">')),d(t.gettext("Current playlist")),d(b('</li>\n <li><a href="#" class="clear-playlist">')),d(t.gettext("Clear playlist")),d(b('</a></li>\n <li><a href="#" class="refresh-playlist">')),d(t.gettext("Refresh playlist")),d(b('</a></li>\n <li class="dropdown-header">')),d(t.gettext("Kodi")),d(b('</li>\n <li><a href="#" class="party-mode">')),d(t.gettext("Party mode")),d(b(' <i class="mdi-navigation-check"></i></a></li>\n <li><a href="#" class="save-playlist">')),d(t.gettext("Save Kodi playlist")),d(b('</a></li>\n </li>\n </ul>\n </div>\n</div>\n<div class="playlists-wrapper">\n <div class="kodi-playlists">\n <ul class="media-toggle">\n <li class="audio">')),d(t.gettext("Audio")),d(b('</li>\n <li class="video">')),d(t.gettext("Video")),d(b('</li>\n </ul>\n <div class="kodi-playlist"></div>\n </div>\n <div class="local-playlists">\n <div class="local-playlist"></div>\n </div>\n</div>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/list/tpl/playlist_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="item-inner item-')),d(this.type),d(b('">\n <div class="artwork">\n <div class="thumb" title="')),d(this.label),d(b('" style="background-image: url(\'')),d(this.thumbnail),d(b('\')">\n <div class="mdi play"></div>\n ')),this.canThumbsUp&&d(b('\n <div class="mdi thumbs"></div>\n ')),d(b('\n </div>\n </div>\n <div class="meta">\n <div class="title"><a href="#')),d(this.url),d(b('" title="')),d(this.label),d(b('">')),d(this.label),d(b("</a></div>\n ")),null!=this.subtitle&&(d(b('\n <div class="subtitle">')),d(b(this.subtitle)),d(b("</div>\n "))),d(b('\n </div>\n <div class="remove"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/m3u/tpl/list.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;for(d(b("#EXTCPlayListM3U::M3U\n")),f=this.items,a=0,e=f.length;e>a;a++)c=f[a],d(b("#EXTINF:")),d(c.duration),d(b(",")),d(c.artist.join("/")),d(b(" - ")),d(c.label),d(b("\n")),d(c.file),d(b("\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/playlist/show/tpl/landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="playlist-page playlist-page__empty set-page">\n <h3>')),d(t.gettext("Now playing - Playlists")),d(b("</h3>\n <p>")),d(t.gettext("Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right")),d(b("</p>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/pvr/recordingList/tpl/recording.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="title">\n <strong>')),d(this.label),d(b("</strong> <span>- ")),d(this.channel),d(b('</span>\n</div>\n<div class="date">\n ')),d(this.start.toString("h:mmtt").toLowerCase()),d(b(" -\n ")),"1970"!==this.end.toString("yyyy")?(d(b("\n ")),d(this.end.toString("h:mmtt").toLowerCase()),d(b("\n (")),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b(")\n "))):(d(b("\n ")),d(tr("Now")),d(b("\n "))),d(b("\n\n <br />")),d(this.start.toString("dddd, dS MMM")),d(b('\n</div>\n<div class="plot">')),d(this.plot),d(b('</div>\n<div class="entity-progress">\n <div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div>\n</div>\n<ul class="actions">\n <li class="play"></li>\n</ul>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/list/tpl/search_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="search-inner">\n <div class="entity-set entity-set-movie"></div>\n <div class="entity-set entity-set-tvshow"></div>\n <div class="entity-set entity-set-artist"></div>\n <div class="entity-set entity-set-album"></div>\n <div class="entity-set entity-set-song"></div>\n <div class="entity-set entity-set-musicvideo"></div>\n <div class="entity-set entity-set-loading"></div>\n <div class="entity-set entity-set-addons"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/list/tpl/search_sidebar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="sidebar-section sidebar-section-media">\n <h3>Local media</h3>\n <ul class="search-media-links"></ul>\n</div>\n\n<div class="sidebar-section sidebar-section-addon">\n <h3>Addons</h3>\n <ul class="search-addon-links"></ul>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/search/show/tpl/landing.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="search-page search-page__empty set-page">\n <h3>')),d(t.gettext("Enter your search above")),d(b("</h3>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/settings/show/tpl/settings_sidebar.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="settings-sidebar">\n <div class="settings-sidebar--section local-nav nav-sub"></div>\n <div class="settings-sidebar--section kodi-nav"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/shell/show/tpl/homepage.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="homepage"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/shell/show/tpl/shell.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div id="shell">\n\n <a id="logo" href="#"></a>\n\n <div id="nav-bar"></div>\n\n <div id="header">\n\n <h1 id="page-title">\n <span class="context"></span>\n <span class="title"></span>\n </h1>\n\n <ul class="mobile-menu">\n <li><a href="#remote" class="mobile-menu--link__remote remote-toggle"><i></i></a></li>\n <li><a href="#search" class="mobile-menu--link__search"><i></i></a></li>\n <li><a href="#playlist" class="mobile-menu--link__playlist"><i></i></a></li>\n </ul>\n\n <div id="selected-region">\n <div class="selected-text">\n <span id="selected-count"></span>\n </div>\n <i data-toggle="dropdown" class="menu-toggle"></i>\n <ul class="dropdown-menu pull-right">\n <li class="selected-play">')),d(tr("Play in Kodi")),d(b('</li>\n <li class="selected-add">')),d(tr("Queue in Kodi")),d(b('</li>\n <li class="selected-localadd">')),d(tr("Add to playlist")),d(b('</li>\n </ul>\n </div>\n\n <div id="search-region">\n <input id="search" title="Search">\n <span id="do-search"></span>\n </div>\n\n </div>\n\n <div id="main">\n\n <div id="sidebar-one"></div>\n\n <div id="content">')),d(tr("Loading things...")),d(b('</div>\n\n </div>\n\n <div id="sidebar-two">\n <div class="playlist-toggle-open"></div>\n <div id="playlist-summary"></div>\n <div id="playlist-bar"></div>\n </div>\n\n <div id="remote"></div>\n\n <div id="player-wrapper">\n <footer id="player-kodi"></footer>\n <footer id="player-local"></footer>\n </div>\n\n <div class="player-menu-wrapper">\n <ul class="player-menu">\n <li class="video-scan">')),d(t.gettext("Scan video library")),d(b('</li>\n <li class="audio-scan">')),d(t.gettext("Scan audio library")),d(b('</li>\n <li class="send-input">')),d(t.gettext("Send text to Kodi")),d(b('</li>\n <li class="goto-lab">')),d(t.gettext("The lab")),d(b('</li>\n <li class="about">')),d(t.gettext("About Chorus")),d(b('</li>\n </ul>\n </div>\n\n</div>\n\n<div id="fanart"></div>\n<div id="fanart-overlay"></div>\n\n<div id="snackbar-container"></div>\n\n<div class="modal fade" id="modal-window">\n <div class="modal-dialog">\n <div class="modal-content">\n <div class="modal-header">\n <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>\n <h4 class="modal-title"></h4>\n </div>\n <div class="modal-body"></div>\n <div class="modal-footer"></div>\n </div>\n </div>\n</div>\n\n<div id="disconnected">\n <div class="message">\n <i class="mdi-file-cloud-off"></i>\n <h2>')),d(tr("Lost connection to Kodi")),d(b('</h2>\n <p class="try-connect"><button class="reconnect btn btn-primary">')),d(tr("Attempt to reconnect")),d(b('</button></p>\n <p class="load-connect"><span class="loader-small-inline"></span><br />')),d(tr("Attempting reconnect")),d(b('</p>\n </div>\n</div>\n\n<div id="offscreen"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/song/list/tpl/song.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<td class="cell-first">\n <div class="thumb" style="background-image: url(\'')),d(this.thumbnail),d(b('\')">\n </div>\n <div class="track">')),d(this.track),d(b('</div>\n <div class="mdi play"></div>\n</td>\n<td class="cell-label song-title"><span class="crop">')),d(this.label),d(b('</span></td>\n<td class="cell-label song-album"><a class="crop" href="#music/album/')),d(this.albumid),d(b('">')),d(this.album),d(b('</a></td>\n<td class="cell-label song-artist"><a class="crop" href="#music/artist/')),d(this.artistid),d(b('">')),d(this.artist),d(b('</a></td>\n<td class="cell-last">\n <li class="thumbed-up"></li>\n <div class="duration">')),d(this.displayDuration),d(b('</div>\n <ul class="actions">\n <li class="mdi thumbs"></li>\n <li class="mdi add"></li>\n <li class="menu dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu pull-right"></ul>\n </li>\n </ul>\n</td>\n<td class="cell-remove song-remove">\n <i class="mdi mdi-navigation-close"></i>\n</td>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/thumbs/list/tpl/thumbs_layout.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="thumbs-inner">\n <div class="entity-set entity-set-movie"></div>\n <div class="entity-set entity-set-tvshow"></div>\n <div class="entity-set entity-set-episode"></div>\n <div class="entity-set entity-set-artist"></div>\n <div class="entity-set entity-set-album"></div>\n <div class="entity-set entity-set-song"></div>\n <div class="entity-set entity-set-musicvideo"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/thumbs/list/tpl/thumbs_set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<h2 class="set-header"></h2>\n<div class="set-results"></div>\n<div class="more"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/episode/tpl/content.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('\n<div class="section-content">\n <h2>')),d(t.gettext("Synopsis")),d(b("</h2>\n <p>")),d(this.plot),d(b("</p>\n</div>\n\n")),this.cast.length>0&&(d(b('\n <div class="section-content">\n <h2>')),d(tr("Full cast")),d(b('</h2>\n <div class="region-cast"></div>\n </div>\n'))),d(b('\n\n<div class="section-content section-full-width">\n <h2>')),d(tr("Season")),d(b(" ")),d(this.season),d(b('</h2>\n <div class="region-season"></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/episode/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e,f;if(d(b('<div class="region-details-top">\n ')),null!=this.showtitle&&d(b("\n\n ")),d(b('\n <div class="region-details-title">\n <h2>\n <span class="title">')),d(this.label),d(b('</span>\n <span class="sub show-title"><a href="#')),d(this.url.split("/",2).join("/")),d(b('">')),d(this.showtitle),d(b('</a></span>\n <span class="sub">S')),d(this.season),d(b(" E")),d(this.episode),d(b('</span>\n </h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <div class="region-details-subtext">\n\n ')),this.runtime>0&&(d(b('\n <div class="runtime">\n ')),d(helpers.global.formatTime(helpers.global.secToTime(this.runtime))),d(b("\n </div>\n "))),d(b('\n\n </div>\n\n <ul class="meta">\n <li><label>')),d(t.gettext("Season")),d(b(':</label> <span><a href="#tvshow/')),d(this.tvshowid),d(b("/")),d(this.season),d(b('">')),d(t.gettext("Season")),d(b(" ")),d(this.season),d(b("</a></span></li>\n ")),this.firstaired&&(d(b("\n <li><label>")),d(t.gettext("First aired")),d(b(":</label> <span>")),d(this.firstaired),d(b(" </span></li>\n "))),d(b("\n ")),this.director.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Director","Directors",this.director.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","director",this.director))),d(b("</span></li>\n "))),d(b("\n ")),this.writer.length>0&&(d(b("\n <li><label>")),d(t.ngettext("Writer","Writers",this.writer.length)),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","writer",this.writer))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(t.gettext("Cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b('\n </ul>\n\n <ul class="streams">\n ')),this.streamdetails.video.length>0&&(d(b("\n <li><label>")),d(t.gettext("Video")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.video,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.audio.length>0&&(d(b("\n <li><label>")),d(t.gettext("Audio")),d(b(":</label> <span>")),d(_.pluck(this.streamdetails.audio,"label").join(", ")),d(b("</span></li>\n "))),d(b("\n ")),this.streamdetails.subtitle.length>0&&""!==this.streamdetails.subtitle[0].label){for(d(b("\n <li><label>")),d(t.ngettext("Subtitle","Subtitles",this.streamdetails.subtitle.length)),d(b(':</label>\n <span class="dropdown"><span data-toggle="dropdown">')),d(_.first(_.pluck(this.streamdetails.subtitle,"label"))),d(b('</span>\n <ul class="dropdown-menu">\n ')),e=this.streamdetails.subtitle,a=0,c=e.length;c>a;a++)f=e[a],d(b("\n <li>")),d(f.label),d(b("</li>\n "));d(b("\n </ul>\n </span>\n </li>\n "))}d(b('\n </ul>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-stream stream">')),d(tr("Stream")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(t.gettext("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="download">')),d(tr("Download")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.showtitle))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.showtitle),d(b(" ")),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.showtitle),d(b('">IMDb</li>\n <li data-type="tvdb" data-query="')),d(this.showtitle),d(b('">TVDb</li>\n <li data-type="tmdb" data-query="')),d(this.showtitle),d(b('">TMDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.showtitle),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="refresh">')),d(tr("Refresh")),d(b('</li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/season/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2>\n <span class="title">')),d(tr("Season")),d(b(" ")),d(this.season),d(b('</span>\n <span class="sub"><a href="#tvshow/')),d(this.tvshowid),d(b('">')),d(this.label),d(b('</a></span>\n </h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(tr("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(tr("cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.studio.length>0&&(d(b("\n <li><label>")),d(tr("studio")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","studio",this.studio))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(tr("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b("\n <li><label>")),d(tr("episodes")),d(b(':</label> <span><span class="episode-total">')),d(this.episode),d(b("</span> ")),d(tr("total")),d(b(' (<span class="episode-unwatched">')),d(this.unwatched),d(b("</span> ")),d(tr("unwatched")),d(b(')</span></li>\n </ul>\n\n <div class="description">')),d(this.plot),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(tr("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b("</span>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""); +},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["apps/tvshow/show/tpl/details_meta.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="region-details-top">\n <div class="region-details-title">\n <h2><span class="title">')),d(this.label),d(b('</span> <span class="sub">')),d(this.year),d(b('</span></h2>\n </div>\n <div class="region-details-rating">\n ')),d(this.rating),d(b(' <i></i>\n </div>\n</div>\n<div class="region-details-meta-below">\n\n <ul class="meta">\n ')),this.genre.length>0&&(d(b("\n <li><label>")),d(tr("genre")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","genre",this.genre))),d(b("</span></li>\n "))),d(b("\n ")),this.cast.length>0&&(d(b("\n <li><label>")),d(tr("cast")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","cast",_.pluck(this.cast,"name")))),d(b("</span></li>\n "))),d(b("\n ")),this.studio.length>0&&(d(b("\n <li><label>")),d(tr("studio")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","studio",this.studio))),d(b("</span></li>\n "))),d(b("\n ")),this.mpaa&&(d(b("\n <li><label>")),d(tr("rated")),d(b(":</label> <span>")),d(b(helpers.url.filterLinks("tvshows","mpaa",[this.mpaa]))),d(b("</span></li>\n "))),d(b("\n <li><label>")),d(tr("episodes")),d(b(':</label> <span><span class="episode-total">')),d(this.episode),d(b("</span> ")),d(tr("total")),d(b(' (<span class="episode-unwatched">')),d(this.unwatched),d(b("</span> ")),d(tr("unwatched")),d(b(')</span></li>\n </ul>\n\n <div class="description">')),d(this.plot),d(b('</div>\n\n <ul class="inline-links">\n <li class="btn-flat-play play">')),d(tr("Play")),d(b('</li>\n <li class="btn-flat-add add">')),d(tr("Queue")),d(b('</li>\n <li class="btn-flat-watched watched">\n ')),d(tr("set")),d(b(' <span class="action-watched">')),d(tr("watched")),d(b('</span><span class="action-unwatched">')),d(tr("unwatched")),d(b('</span>\n </li>\n <li class="more-actions dropdown">\n <span class="btn-flat-more" data-toggle="dropdown" aria-expanded="true">')),d(tr("more")),d(b('</span>\n <ul class="dropdown-menu pull-right">\n <li class="dropdown-submenu internal-search">')),d(tr("Chorus Search")),d(b('\n <ul class="dropdown-menu">\n ')),d(b(helpers.entities.getAddonSearchMenuItems(this.label))),d(b('\n </ul>\n </li>\n <li class="dropdown-submenu external-search">')),d(tr("External Search")),d(b('\n <ul class="dropdown-menu">\n <li data-type="google" data-query="')),d(this.label),d(b('">Google</li>\n <li data-type="imdb" data-query="')),d(this.label),d(b('">IMDb</li>\n <li data-type="tvdb" data-query="')),d(this.label),d(b('">TVDb</li>\n <li data-type="tmdb" data-query="')),d(this.label),d(b('">TMDb</li>\n </ul>\n </li>\n <li class="youtube-search" data-query="')),d(this.label),d(b('">')),d(tr("YouTube Search")),d(b('</li>\n <li class="divider"></li>\n <li class="dropdown-submenu">')),d(tr("Refresh")),d(b('\n <ul class="dropdown-menu">\n <li class="refresh">')),d(tr("Show only")),d(b('</li>\n <li class="refresh-episodes">')),d(tr("Show and episodes")),d(b('</li>\n </ul>\n </li>\n <li class="edit">')),d(tr("Edit")),d(b("</li>\n </ul>\n </li>\n </ul>\n\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="form-inner">\n <div class="form-content-region"></div>\n <footer>\n <ul class="inline-list">\n <li>\n <button type="submit" data-form-button="submit" class="btn btn-primary form-save">Save</button>\n </li>\n <li class="response">\n\n </li>\n </ul>\n </footer>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){this.title&&(d(b('\n <label class="control-label">')),d(b(this.title)),d(b("</label>\n"))),d(b("\n\n")),"markup"===this.type?(d(b("\n ")),d(b(this.element)),d(b("\n"))):(d(b('\n <div class="element">\n ')),"checkbox"!==this.type?(d(b("\n ")),d(b(this.element)),d(b("\n "))):(d(b('\n <div class="togglebutton">\n <label>')),d(b(this.element)),d(b("</label>\n </div>\n "))),d(b("\n ")),this.description&&(d(b('\n <div class="help-block description">')),d(b(this.description)),d(b("</div>\n "))),d(b("\n </div>\n"))),d(b("\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item_group.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){this.title&&(d(b('\n <h3 class="group-title">')),this.icon&&(d(b('<i class="')),d(b(this.icon)),d(b('"></i> '))),d(b(this.title)),d(b("</h3>\n"))),d(b('\n<div class="form-items"></div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["components/form/tpl/form_item_imageselect.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="form-imageselect">\n <ul class="form-imageselect__tabs">\n <li data-pane="select" class="active">')),d(tr("Selector")),d(b('</li>\n <li data-pane="url">')),d(tr("URL")),d(b('</li>\n </ul>\n <div class="form-imageselect__panes">\n <div class="pane active" rel="select">\n <ul class="form-imageselect__thumbs">\n ')),this.image&&(d(b('\n <li data-original="')),d(this.image.original),d(b('" class="selected" style="background-image: url(\'')),d(this.image.thumb),d(b("')\"></li>\n "))),d(b('\n </ul>\n <div class="form-imageselect__loader"><div class="loader-small-inline"></div> <span>')),d(tr("Searching for more images")),d(b('</span></div>\n </div>\n <div class="pane" rel="url">\n ')),this.title&&(d(b('\n <label class="control-label">')),d(b(this.title)),d(b("</label>\n "))),d(b('\n <div class="form-imageselect__url">\n ')),d(b(this.element)),d(b("\n </div>\n ")),this.description&&(d(b('\n <div class="help-block description">')),d(b(this.description)),d(b("</div>\n "))),d(b("\n </div>\n </div>\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/card/tpl/card.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){var a,c,e;if(d(b('<div class="card-')),d(this.type),d(b('">\n <div class="artwork">\n <a href="#')),d(this.url),d(b('" class="thumb" title="')),d(helpers.global.stripTags(this.label)),d(b('" style="background-image: url(\'')),d(this.thumbnail),d(b('\')"></a>\n <div class="mdi play" title="')),d(tr("Play")),d(b('"></div>\n ')),("channeltv"===this.type||"channelradio"===this.type)&&d(b('\n <div class="mdi record"></div>\n ')),d(b('\n </div>\n <div class="meta">\n <div class="title"><a href="#')),d(this.url),d(b('" title="')),d(helpers.global.stripTags(this.label)),d(b('">')),d(b(this.label)),d(b("</a></div>\n ")),null!=this.subtitle&&(d(b('\n <div class="subtitle">')),d(b(this.subtitle)),d(b("</div>\n "))),d(b("\n </div>\n ")),this.actions){d(b('\n <ul class="actions">\n ')),c=this.actions;for(a in c)e=c[a],d(b('<li class="mdi ')),d(a),d(b('" title="')),d(e),d(b('"></li>'));d(b("\n </ul>\n "))}d(b("\n ")),this.menu&&d(b('\n <div class="dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu"></ul>\n </div>\n ')),d(b("\n ")),this.progress=null!=this.progress?this.progress:0,d(b('\n <div class="entity-progress"><div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div></div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/card/tpl/card_placeholder.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b("<i></i>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/empty/tpl/empty_page.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="empty--page">\n ')),this.title&&(d(b('\n <h2 class="empty--page-title">')),d(title),d(b("</h2>\n "))),d(b("\n\n ")),this.content&&(d(b('\n <div class="empty--page-content">')),d(this.content),d(b("</div>\n "))),d(b("\n</div>"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/empty/tpl/empty_results.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="empty-result">\n <h2>')),d(b(t.sprintf(tr("No %1$s found"),'<span class="empty-key">'+tr("results")+"</span>"))),d(b('</h2>\n <div class="empty-actions">\n <div class="back-link"></div>\n </div>\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_details_header.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container details-header">\n\n <div class="region-details-side"></div>\n\n <div class="region-details-meta-wrapper"><div class="region-details-meta">\n\n <div class="region-details-title"><span class="title"></span> <span class="sub"></span></div>\n\n <div class="region-details-meta-below">\n <div class="region-details-subtext"></div>\n <div class="description"></div>\n </div>\n\n </div></div>\n\n ')),this.fanart&&(d(b('\n <div class="region-details-fanart" style="background-image: url(\'')),d(this.fanart),d(b('\')"><div class="gradient"></div></div>\n '))),d(b("\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_with_header.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container with-header">\n\n <header class="region-header"></header>\n\n <div class="region-content-wrapper">\n <div class="entity-progress"><div class="current-progress" style="width: ')),d(this.progress),d(b('%" title="')),d(this.progress),d(b("% ")),d(t.gettext("complete")),d(b('"></div></div>\n <section class="region-content"></section>\n </div>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/layouts/tpl/layout_with_sidebar_first.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="layout-container with-sidebar-first">\n\n <div class="region-first-toggle"></div>\n <section class="region-first">\n <div class="region-first-primary"></div>\n <div class="region-first-secondary"></div>\n </section>\n\n <section class="region-content-wrapper">\n <div class="region-content-top"></div>\n <div class="region-content"></div>\n </section>\n\n</div>'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/set/tpl/set.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<div class="set">\n ')),this.title&&(d(b('\n <div class="set__header">\n <h2 class="set__title">')),d(this.title),d(b('</h2>\n <div class="set__actions">\n ')),this.menu&&d(b('\n <div class="dropdown">\n <i data-toggle="dropdown" class="mdi"></i>\n <ul class="dropdown-menu pull-right"></ul>\n </div>\n ')),d(b("\n </div>\n </div>\n "))),d(b('\n <div class="set__items">\n <')),d(this.childViewTag),d(b(' class="set__collection ')),d(this.childViewClass),d(b('"></')),d(this.childViewTag),d(b(">\n </div>\n ")),this.more&&(d(b('\n <div class="set__more">')),d(b(this.more)),d(b("</div>\n "))),d(b("\n</div>\n"))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())},window.JST["views/song/tpl/song_placeholder.jst"]=function(a){var b=function(a){"undefined"==typeof a&&null==a&&(a="");var b=new String(a);return b.ecoSafe=!0,b};return function(){var a=[],c=this,d=function(b){"undefined"!=typeof b&&null!=b&&a.push(b.ecoSafe?b:c.escape(b))};return function(){d(b('<td colspan="6"><i></i></td>\n'))}.call(this),a.join("")}.call(function(){var c,d={escape:function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},safe:b};for(c in a)d[c]=a[c];return d}())};;var tr, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, @@ -30,6 +30,7 @@ this.config = { socketsHost: location.hostname, socketsPort: 9090, ajaxTimeout: 5000, + connected: true, hashKey: 'kodi', defaultPlayer: 'auto', ignoreArticle: true, @@ -46,7 +47,8 @@ this.config = { keyboardControl: 'kodi', disableThumbs: false, showDeviceName: false, - refreshIgnoreNFO: true + refreshIgnoreNFO: true, + largeBreakpoint: 910 } }; @@ -217,6 +219,46 @@ config.preStartGet = function(id, defaultData) { /* + Connection helpers. For live connecting and disconnecting from Kodi. + */ + +helpers.connection = {}; + +helpers.connection.reconnect = function(success) { + return helpers.connection.ping((function() { + config.setLocal('connected', true); + Kodi.execute('state:ws:init'); + return success(); + }), function() { + return Kodi.execute('shell:disconnect'); + }); +}; + +helpers.connection.disconnect = function() { + return config.setLocal('connected', false); +}; + +helpers.connection.ping = function(success, fail) { + var d; + d = new Date(); + return $.ajax({ + url: helpers.url.baseKodiUrl("Ping"), + timeout: 3000, + contentType: 'application/json', + type: 'POST', + data: JSON.stringify({ + jsonrpc: '2.0', + method: 'JSONRPC.Ping', + params: {}, + id: d.getTime() + }), + success: success, + error: fail + }); +}; + + +/* Entities mixins, all the common things we do/need on almost every collection example of usage: @@ -1330,7 +1372,8 @@ helpers.url.map = { channeltv: 'pvr/tv/:id', channelradio: 'pvr/radio/:id', file: 'browser/file/:id', - playlist: 'playlist/:id' + playlist: 'playlist/:id', + musicvideo: 'music/video/:id' }; helpers.url.baseKodiUrl = function(query) { @@ -1499,8 +1542,6 @@ helpers.url.isSecureProtocol = function() { return secure; }; -Cocktail.patch(Backbone); - (function(Backbone) { var methods, _sync; _sync = Backbone.sync; @@ -1977,6 +2018,294 @@ this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) }); }); +this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) { + Entities.ExternalEntity = (function(_super) { + __extends(ExternalEntity, _super); + + function ExternalEntity() { + return ExternalEntity.__super__.constructor.apply(this, arguments); + } + + ExternalEntity.prototype.defaults = { + id: '', + title: '', + desc: '', + thumbnail: '', + url: '', + type: '', + provider: '' + }; + + return ExternalEntity; + + })(Entities.Model); + return Entities.ExternalCollection = (function(_super) { + __extends(ExternalCollection, _super); + + function ExternalCollection() { + return ExternalCollection.__super__.constructor.apply(this, arguments); + } + + ExternalCollection.prototype.model = Entities.ExternalEntity; + + return ExternalCollection; + + })(Entities.Collection); +}); + +this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) { + var API; + API = { + apiKey: 'ed4b784f97227358b31ca4dd966a04f1', + baseURL: 'http://webservice.fanart.tv/v3/', + maxImageCount: 15, + artistFieldTranslate: { + artistbackground: 'fanart', + artistthumb: 'thumbnail' + }, + call: function(path, params, callback) { + var defaultParams, req, url; + defaultParams = { + api_key: this.apiKey + }; + params = _.extend(defaultParams, params); + url = this.baseURL + path + helpers.url.buildParams(params); + req = $.getJSON(url, function(resp) { + return callback(resp); + }); + return req.fail(function(err) { + return callback({ + status: 'error' + }); + }); + }, + parseImageUrls: function(artType, collection) { + var artTypes, field, i, item, items, row, type, _ref; + if (collection.status && collection.status === 'error') { + return []; + } + items = []; + artTypes = this[artType + 'FieldTranslate']; + for (type in artTypes) { + field = artTypes[type]; + if (collection[type] != null) { + collection[type] = collection[type].slice(0, this.maxImageCount); + _ref = collection[type]; + for (i in _ref) { + item = _ref[i]; + row = item; + row.thumbnail = this.getThumbnailUrl(item.url); + row.provider = 'fanarttv'; + row.type = field; + items.push(row); + } + } + } + return items; + }, + getThumbnailUrl: (function(_this) { + return function(url) { + return url.replace('assets.fanart.tv/', 'fanart.tv/detailpreview/'); + }; + })(this), + images: function(type, id, callback) { + return this.call(type + '/' + id, {}, (function(_this) { + return function(resp) { + return callback(_this.parseImageUrls('artist', resp)); + }; + })(this)); + }, + getMusicArtCollection: function(name, callback) { + var cache, cacheKey; + cacheKey = 'fanarttv:' + encodeURIComponent(name); + cache = config.getLocal(cacheKey, []); + if (cache.length > 0) { + return API.createCollection(cache, callback); + } else { + return App.execute("musicbrainz:artist:entity", name, function(model) { + if (model.get('id')) { + return API.images('music', model.get('id'), function(results) { + return API.createCollection(results, callback); + }); + } else { + return API.createCollection([], callback); + } + }); + } + }, + createCollection: function(items, callback) { + return callback(new Entities.ExternalCollection(items)); + } + }; + return App.commands.setHandler("fanarttv:artist:image:entities", function(name, callback) { + return API.getMusicArtCollection(name, callback); + }); +}); + +this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) { + var API; + API = { + baseURL: 'http://musicbrainz.org/ws/2/', + maxCount: 1, + call: function(path, params, callback) { + var url; + url = this.baseURL + path + helpers.url.buildParams(params) + '&fmt=json'; + return $.getJSON(url, function(resp) { + return callback(resp); + }); + }, + findArtist: function(key, id, callback) { + return this.call('artist/', { + query: key + ':' + id + }, function(resp) { + var collection; + collection = new Entities.ExternalCollection(API.parseArtist(resp)); + return callback(collection); + }); + }, + parseArtist: function(resp) { + var items; + items = []; + if (resp.artists && resp.artists.length) { + items = resp.artists; + items = _.map(items, function(item) { + item.artistType = item.type; + item.title = item.name; + item.type = 'artist'; + item.provider = 'musicbrainz'; + return item; + }); + } + return items; + } + }; + return App.commands.setHandler("musicbrainz:artist:entity", function(name, callback) { + return API.findArtist('artist', name, function(collection) { + return callback(collection.first()); + }); + }); +}); + +this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) { + var API; + API = { + apiKey: 'f7f51775877e0bb6703520952b3c7840', + baseURL: 'https://api.themoviedb.org/3/', + baseImageURL: 'https://image.tmdb.org/t/p/', + defaultLang: 'en', + maxImageCount: 15, + thumbSize: { + backdrops: 'w300', + posters: 'w185' + }, + fieldTranslate: { + backdrops: 'fanart', + posters: 'thumbnail' + }, + call: function(path, params, callback) { + var defaultParams, url; + defaultParams = { + api_key: this.apiKey + }; + params = _.extend(defaultParams, params); + url = this.baseURL + path + helpers.url.buildParams(params) + '&callback=?'; + return $.getJSON(url, function(resp) { + return callback(resp); + }); + }, + getImageURL: function(path, size) { + if (size == null) { + size = 'original'; + } + return this.baseImageURL + size + path; + }, + parseImages: function(collection) { + var field, i, item, items, type, _ref, _ref1; + items = []; + _ref = API.fieldTranslate; + for (type in _ref) { + field = _ref[type]; + collection[type] = collection[type].slice(0, this.maxImageCount); + _ref1 = collection[type]; + for (i in _ref1) { + item = _ref1[i]; + item.id = item.file_path; + item.url = this.getImageURL(item.file_path, 'original'); + item.thumbnail = this.getImageURL(item.file_path, this.thumbSize[type]); + item.type = field; + item.provider = 'moviedb'; + items.push(item); + } + } + return items; + }, + find: function(id, source, callback) { + if (source == null) { + source = 'imdb_id'; + } + return this.call('find/' + id, { + external_source: source + }, callback); + }, + images: function(type, tmdbId, callback) { + return this.call(type + '/' + tmdbId + '/images', { + include_image_language: this.defaultLang + ',null' + }, (function(_this) { + return function(resp) { + return callback(_this.parseImages(resp)); + }; + })(this)); + }, + getCollection: function(options, callback) { + var cache, cacheKey, opts; + opts = _.extend({ + lookupType: 'imdb_id', + lookupId: '', + type: 'movie' + }, options); + cacheKey = 'moviedb:' + JSON.stringify(opts); + cache = config.getLocal(cacheKey, []); + if (cache.length > 0) { + return API.createCollection(cache, callback); + } else { + return API.find(opts.lookupId, opts.lookupType, function(resp) { + var item, resKey; + resKey = opts.type + '_results'; + if (resp[resKey] && resp[resKey].length > 0) { + item = _.first(resp[resKey]); + return API.images(opts.type, item.id, function(resp) { + config.setLocal(cacheKey, resp); + return API.createCollection(resp, callback); + }); + } else { + return API.createCollection([], callback); + } + }); + } + }, + createCollection: function(items, callback) { + return callback(new Entities.ExternalCollection(items)); + } + }; + App.commands.setHandler("themoviedb:movie:image:entities", function(lookupId, callback) { + var options; + options = { + lookupId: lookupId + }; + return API.getCollection(options, callback); + }); + return App.commands.setHandler("themoviedb:tv:image:entities", function(lookupId, callback) { + var lookupType, options; + lookupType = lookupId.lastIndexOf('tt', 0) === 0 ? 'imdb_id' : 'tvdb_id'; + options = { + lookupId: lookupId, + lookupType: lookupType, + type: 'tv' + }; + return API.getCollection(options, callback); + }); +}); + /* Youtube collection @@ -1987,74 +2316,71 @@ this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) API = { apiKey: 'AIzaSyBxvaR6mCnUWN8cv2TiPRmuEh0FykBTAH0', searchUrl: 'https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&videoDefinition=any&videoEmbeddable=true&order=relevance&safeSearch=none', + maxResults: 5, + kodiUrl: 'plugin://plugin.video.youtube/?action=play_video&videoid=', + ytURL: 'https://youtu.be/', getSearchUrl: function() { return this.searchUrl + '&key=' + this.apiKey; }, parseItems: function(response) { - var i, item, items, resp, _ref; + var enabled, i, item, items, resp, _ref; items = []; + enabled = App.request("addon:isEnabled", { + addonid: 'plugin.video.youtube' + }) ? true : false; _ref = response.items; for (i in _ref) { item = _ref[i]; resp = { id: item.id.videoId, title: item.snippet.title, + label: item.snippet.title, desc: item.snippet.description, - thumbnail: item.snippet.thumbnails["default"].url + thumbnail: item.snippet.thumbnails.medium.url, + url: API.ytURL + item.id.videoId, + addonEnabled: enabled }; items.push(resp); } return items; } }; - Entities.youtubeItem = (function(_super) { - __extends(youtubeItem, _super); - - function youtubeItem() { - return youtubeItem.__super__.constructor.apply(this, arguments); - } - - youtubeItem.prototype.defaults = { - id: '', - title: '', - desc: '', - thumbnail: '' - }; - - return youtubeItem; - - })(Entities.Model); - Entities.youtubeCollection = (function(_super) { - __extends(youtubeCollection, _super); + Entities.YouTubeCollection = (function(_super) { + __extends(YouTubeCollection, _super); - function youtubeCollection() { - return youtubeCollection.__super__.constructor.apply(this, arguments); + function YouTubeCollection() { + return YouTubeCollection.__super__.constructor.apply(this, arguments); } - youtubeCollection.prototype.model = Entities.youtubeItem; + YouTubeCollection.prototype.model = Entities.ExternalEntity; - youtubeCollection.prototype.url = API.getSearchUrl(); + YouTubeCollection.prototype.url = API.getSearchUrl(); - youtubeCollection.prototype.sync = function(method, collection, options) { + YouTubeCollection.prototype.sync = function(method, collection, options) { options.dataType = "jsonp"; options.timeout = 5000; return Backbone.sync(method, collection, options); }; - youtubeCollection.prototype.parse = function(resp) { + YouTubeCollection.prototype.parse = function(resp) { return API.parseItems(resp); }; - return youtubeCollection; + return YouTubeCollection; - })(Entities.Collection); - return App.commands.setHandler("youtube:search:entities", function(query, callback) { - var yt; - yt = new Entities.youtubeCollection(); + })(Entities.ExternalCollection); + App.commands.setHandler("youtube:search:entities", function(query, options, callback) { + var data, yt; + if (options == null) { + options = {}; + } + yt = new Entities.YouTubeCollection(); + data = _.extend({ + q: query, + maxResults: API.maxResults + }, options); return yt.fetch({ - data: { - q: query - }, + data: data, success: function(collection) { return callback(collection); }, @@ -2063,6 +2389,18 @@ this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) } }); }); + return App.commands.setHandler("youtube:trailer:entities", function(title, callback) { + return App.execute("youtube:search:entities", title + ' trailer', {}, function(collection) { + collection.map(function(item) { + item.set({ + type: 'trailer', + url: API.kodiUrl + item.id + }); + return item; + }); + return callback(collection); + }); + }); }); this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) { @@ -2855,7 +3193,7 @@ this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionett fields: { minimal: [], small: ['thumbnail', 'mood', 'genre', 'style'], - full: ['fanart', 'born', 'formed', 'description', 'died', 'disbanded', 'yearsactive', 'instrument'] + full: ['fanart', 'born', 'formed', 'description', 'died', 'disbanded', 'yearsactive', 'instrument', 'musicbrainzartistid'] }, getArtist: function(id, options) { var artist; @@ -2926,7 +3264,7 @@ this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionett ArtistCollection.prototype.args = function() { return this.getArgs({ albumartistsonly: config.getLocal('albumArtistsOnly', true), - properties: this.argFields(helpers.entities.getFields(API.fields, 'full')), + properties: this.argFields(helpers.entities.getFields(API.fields, 'small')), limits: this.argLimit(), sort: this.argSort('title', 'ascending'), filter: this.argFilter() @@ -3157,8 +3495,8 @@ this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionett API = { fields: { minimal: ['title'], - small: ['thumbnail', 'playcount', 'lastplayed', 'dateadded', 'episode', 'season', 'rating', 'file', 'cast', 'showtitle', 'tvshowid', 'uniqueid', 'resume'], - full: ['fanart', 'plot', 'firstaired', 'director', 'writer', 'runtime', 'streamdetails'] + small: ['thumbnail', 'playcount', 'lastplayed', 'dateadded', 'episode', 'season', 'rating', 'file', 'cast', 'showtitle', 'tvshowid', 'uniqueid', 'resume', 'firstaired'], + full: ['fanart', 'plot', 'director', 'writer', 'runtime', 'streamdetails'] }, getEntity: function(id, options) { var entity; @@ -3961,6 +4299,135 @@ this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionett }); this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionette, $, _) { + var API; + API = { + fields: { + minimal: ['title'], + small: ['thumbnail', 'file', 'genre', 'artist', 'year', 'playcount', 'dateadded', 'streamdetails', 'album', 'resume', 'director', 'rating'], + full: ['fanart', 'studio', 'plot', 'track', 'tag'] + }, + getVideo: function(id, options) { + var artist; + artist = new App.KodiEntities.MusicVideo(); + artist.set({ + musicvideoid: parseInt(id), + properties: helpers.entities.getFields(API.fields, 'full') + }); + artist.fetch(options); + return artist; + }, + getVideos: function(options) { + var collection; + collection = new KodiEntities.MusicVideoCollection(); + collection.fetch(helpers.entities.buildOptions(options)); + return collection; + } + }; + + /* + Models and collections. + */ + KodiEntities.MusicVideo = (function(_super) { + __extends(MusicVideo, _super); + + function MusicVideo() { + return MusicVideo.__super__.constructor.apply(this, arguments); + } + + MusicVideo.prototype.defaults = function() { + var fields; + fields = _.extend(this.modelDefaults, { + musicvideoid: 1, + title: '' + }); + return this.parseFieldsToDefaults(helpers.entities.getFields(API.fields, 'full'), fields); + }; + + MusicVideo.prototype.methods = { + read: ['VideoLibrary.GetMusicVideoDetails', 'musicvideoid', 'properties'] + }; + + MusicVideo.prototype.parse = function(resp, xhr) { + var obj; + obj = resp.musicvideodetails != null ? resp.musicvideodetails : resp; + if (resp.musicvideodetails != null) { + obj.fullyloaded = true; + } + return this.parseModel('musicvideo', obj, obj.musicvideoid); + }; + + return MusicVideo; + + })(App.KodiEntities.Model); + KodiEntities.MusicVideoCollection = (function(_super) { + __extends(MusicVideoCollection, _super); + + function MusicVideoCollection() { + return MusicVideoCollection.__super__.constructor.apply(this, arguments); + } + + MusicVideoCollection.prototype.model = KodiEntities.MusicVideo; + + MusicVideoCollection.prototype.methods = { + read: ['VideoLibrary.GetMusicVideos', 'properties', 'limits', 'sort', 'filter'] + }; + + MusicVideoCollection.prototype.args = function() { + return this.getArgs({ + properties: this.argFields(helpers.entities.getFields(API.fields, 'full')), + limits: this.argLimit(), + sort: this.argSort('title', 'ascending'), + filter: this.argFilter() + }); + }; + + MusicVideoCollection.prototype.parse = function(resp, xhr) { + return this.getResult(resp, 'musicvideos'); + }; + + return MusicVideoCollection; + + })(App.KodiEntities.Collection); + KodiEntities.MusicVideoCustomCollection = (function(_super) { + __extends(MusicVideoCustomCollection, _super); + + function MusicVideoCustomCollection() { + return MusicVideoCustomCollection.__super__.constructor.apply(this, arguments); + } + + MusicVideoCustomCollection.prototype.model = KodiEntities.MusicVideo; + + return MusicVideoCustomCollection; + + })(App.KodiEntities.Collection); + + /* + Request Handlers. + */ + App.reqres.setHandler("musicvideo:entity", function(id, options) { + if (options == null) { + options = {}; + } + return API.getVideo(id, options); + }); + App.reqres.setHandler("musicvideo:entities", function(options) { + if (options == null) { + options = {}; + } + return API.getVideos(options); + }); + App.reqres.setHandler("musicvideo:fields", function(type) { + if (type == null) { + type = 'full'; + } + return helpers.entities.getFields(API.fields, type); + }); + return App.reqres.setHandler("musicvideo:build:collection", function(items) { + return new KodiEntities.MusicVideoCustomCollection(items); + }); +}); + +this.Kodi.module("KodiEntities", function(KodiEntities, App, Backbone, Marionette, $, _) { /* API Helpers @@ -5557,6 +6024,14 @@ this.Kodi.module("Entities", function(Entities, App, Backbone, Marionette, $, _) parent: 1 }); nav.push({ + id: 8, + title: tr("Videos"), + path: 'music/videos', + icon: '', + classes: '', + parent: 1 + }); + nav.push({ id: 11, title: tr("Movies"), path: 'movies/recent', @@ -6121,21 +6596,6 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { return ItemView.__super__.constructor.apply(this, arguments); } - ItemView.prototype.menuPopulate = function() { - var key, menu, val, _ref; - menu = ''; - if (this.model.get('menu')) { - _ref = this.model.get('menu'); - for (key in _ref) { - val = _ref[key]; - menu += this.themeTag('li', { - "class": key - }, val); - } - return this.$el.find('.dropdown-menu').html(menu); - } - }; - ItemView.prototype.onShow = function() { return this.menuBlur(); }; @@ -6226,9 +6686,13 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { external: false, className: '' }); - attrs = !options.external ? { - href: "#" + url - } : void 0; + attrs = {}; + if (options.external) { + attrs.target = '_blank'; + attrs.href = url; + } else { + attrs.href = '#' + url; + } if (options.className !== '') { attrs["class"] = options.className; } @@ -6263,6 +6727,34 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { helpers.debug.msg('formatText error: ' + res.errorQueue.join(', '), 'warning', res); } return res.html; + }, + populateMenu: function(type) { + var baseSelector, key, menu, selector, val, _ref; + if (type == null) { + type = ''; + } + menu = ''; + baseSelector = 'dropdown-menu'; + if (this.model.get('menu')) { + _ref = this.model.get('menu'); + for (key in _ref) { + val = _ref[key]; + if (key.lastIndexOf('divider', 0) === 0) { + key = 'divider'; + } + menu += this.themeTag('li', { + "class": key + }, val); + } + selector = type !== '' ? type + ' .' + baseSelector : baseSelector; + return this.$el.find('.' + selector).html(menu); + } + }, + populateModelMenu: function() { + return this.populateMenu(); + }, + populateSetMenu: function() { + return this.populateMenu('set__actions'); } }); }); @@ -6383,7 +6875,7 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { CardView.prototype.tagName = "li"; CardView.prototype.events = { - "click .dropdown > i": "populateMenu", + "click .dropdown > i": "populateModelMenu", "click .thumbs": "toggleThumbs", "click": "toggleSelect" }; @@ -6392,24 +6884,6 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { 'change': 'modelChange' }; - CardView.prototype.populateMenu = function() { - var key, menu, val, _ref; - menu = ''; - if (this.model.get('menu')) { - _ref = this.model.get('menu'); - for (key in _ref) { - val = _ref[key]; - if (key.lastIndexOf('divider', 0) === 0) { - key = 'divider'; - } - menu += this.themeTag('li', { - "class": key - }, val); - } - return this.$el.find('.dropdown-menu').html(menu); - } - }; - CardView.prototype.toggleThumbs = function() { App.request("thumbsup:toggle:entity", this.model); return this.$el.toggleClass('thumbs-up'); @@ -6436,6 +6910,10 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { }); }; + CardView.prototype.makeLinksExternal = function() { + return $('.title, .thumb', this.$el).attr('href', this.model.get('url')).attr('target', '_blank'); + }; + CardView.prototype.modelChange = function() { if (_.isFunction(this.setMeta)) { this.setMeta(); @@ -6658,6 +7136,113 @@ this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { }); this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { + var API; + API = { + createModel: function(options) { + var defaultMenu, model; + if (options == null) { + options = {}; + } + defaultMenu = { + selectall: tr('Toggle select all') + }; + model = _.extend({ + childViewTag: 'div', + ChildViewClass: '' + }, options); + if (!options.noMenuDefault) { + model.menu = _.isObject(options.menu) ? _.extend(defaultMenu, options.menu) : defaultMenu; + } + return new Backbone.Model(model); + }, + toggleSelectAll: function($el) { + var $ctx; + $ctx = $('.set__collection', $el); + return $('.card, .song', $ctx).toggleClass('selected').each(function(i, d) { + var $d, op; + $d = $(d); + op = $(d).hasClass('selected') ? 'add' : 'remove'; + return App.execute("selected:update:items", op, $d.data('model').toJSON()); + }); + } + }; + Views.SetCompositeView = (function(_super) { + __extends(SetCompositeView, _super); + + function SetCompositeView() { + return SetCompositeView.__super__.constructor.apply(this, arguments); + } + + SetCompositeView.prototype.template = 'views/set/set'; + + SetCompositeView.prototype.childView = App.Views.CardView; + + SetCompositeView.prototype.tagName = 'div'; + + SetCompositeView.prototype.className = "set__wrapper"; + + SetCompositeView.prototype.childViewContainer = ".set__collection"; + + SetCompositeView.prototype.events = { + "click .dropdown > i": "populateSetMenu", + "click .selectall": "toggleSelectAll" + }; + + SetCompositeView.prototype.initialize = function() { + return this.createModel(); + }; + + SetCompositeView.prototype.createModel = function() { + return this.model = API.createModel(this.options); + }; + + SetCompositeView.prototype.toggleSelectAll = function() { + return API.toggleSelectAll(this.$el); + }; + + return SetCompositeView; + + })(App.Views.CompositeView); + return Views.SetLayoutView = (function(_super) { + __extends(SetLayoutView, _super); + + function SetLayoutView() { + return SetLayoutView.__super__.constructor.apply(this, arguments); + } + + SetLayoutView.prototype.template = 'views/set/set'; + + SetLayoutView.prototype.tagName = 'div'; + + SetLayoutView.prototype.className = "set__wrapper"; + + SetLayoutView.prototype.regions = { + regionCollection: ".set__collection" + }; + + SetLayoutView.prototype.events = { + "click .dropdown > i": "populateSetMenu", + "click .selectall": "toggleSelectAll" + }; + + SetLayoutView.prototype.initialize = function() { + return this.createModel(); + }; + + SetLayoutView.prototype.createModel = function() { + return this.model = API.createModel(this.options); + }; + + SetLayoutView.prototype.toggleSelectAll = function() { + return API.toggleSelectAll(this.$el); + }; + + return SetLayoutView; + + })(App.Views.LayoutView); +}); + +this.Kodi.module("Views", function(Views, App, Backbone, Marionette, $, _) { return Views.SongViewPlaceholder = (function(_super) { __extends(SongViewPlaceholder, _super); @@ -7164,14 +7749,14 @@ this.Kodi.module("Components.Form", function(Form, App, Backbone, Marionette, $, return _.defer(function() { if (metadataHandler && metadataLookup && item[metadataLookup]) { $wrapper.addClass('images-loading'); - return App.execute(metadataHandler, item[metadataLookup], function(resp) { + return App.execute(metadataHandler, item[metadataLookup], function(collection) { var image, _i, _len, _ref; - if (resp) { - _ref = resp[field]; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - image = _ref[_i]; - $thumbs.append($('<li data-original="' + image.original + '"><img src="' + image.thumb + '" /></li>')); - } + _ref = collection.where({ + type: field + }); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + image = _ref[_i]; + $('<li>').data('original', image.get('url')).css('background-image', 'url(' + image.get('thumbnail') + ')').attr('title', image.get('title')).appendTo($thumbs); } return $wrapper.removeClass('images-loading'); }); @@ -8271,16 +8856,18 @@ this.Kodi.module("ArtistApp.Edit", function(Edit, App, Backbone, Marionette, $, }, { id: 'formed', title: tr('Formed'), - type: 'textfield' + type: 'textfield', + attributes: { + "class": 'half-width' + } }, { id: 'disbanded', title: tr('Disbanded'), - type: 'textfield' - }, { - id: 'yearsactive', - title: tr('Years Active'), type: 'textfield', - format: 'array.string' + attributes: { + "class": 'half-width' + }, + suffix: '<div class="clearfix"></div>' }, { id: 'born', title: tr('Born'), @@ -8296,6 +8883,11 @@ this.Kodi.module("ArtistApp.Edit", function(Edit, App, Backbone, Marionette, $, "class": 'half-width' }, suffix: '<div class="clearfix"></div>' + }, { + id: 'yearsactive', + title: tr('Years Active'), + type: 'textfield', + format: 'array.string' } ] }, { @@ -9661,11 +10253,12 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, return this.ajaxOptions = options; }; - Base.prototype.multipleCommands = function(commands, callback) { + Base.prototype.multipleCommands = function(commands, callback, fail) { var obj; obj = $.jsonrpc(commands, this.ajaxOptions); obj.fail((function(_this) { return function(error) { + _this.doCallback(fail, error); return _this.onError(commands, error); }; })(this)); @@ -9681,7 +10274,7 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, return obj; }; - Base.prototype.singleCommand = function(command, params, callback) { + Base.prototype.singleCommand = function(command, params, callback, fail) { var obj; command = { method: command, @@ -9690,7 +10283,7 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, if ((params != null) && (params.length > 0 || _.isObject(params))) { command.params = params; } - obj = this.multipleCommands([command], callback); + obj = this.multipleCommands([command], callback, fail); return obj; }; @@ -9787,11 +10380,15 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, return namespace + '.' + command; }; - Commander.prototype.sendCommand = function(command, params, callback) { - return this.singleCommand(this.getCommand(command), params, (function(_this) { + Commander.prototype.sendCommand = function(command, params, callback, fail) { + return this.singleCommand(this.getCommand(command), params, ((function(_this) { return function(resp) { return _this.doCallback(callback, resp); }; + })(this)), (function(_this) { + return function(err) { + return _this.doCallback(fail, err); + }; })(this)); }; @@ -9850,14 +10447,16 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, })(this)); }; - Player.prototype.sendCommand = function(command, params, callback) { + Player.prototype.sendCommand = function(command, params, callback, fail) { if (params == null) { params = []; } return this.getParams(params, (function(_this) { return function(playerParams) { - return _this.singleCommand(_this.getCommand(command), playerParams, function(resp) { + return _this.singleCommand(_this.getCommand(command), playerParams, (function(resp) { return _this.doCallback(callback, resp); + }), function(err) { + return _this.doCallback(fail, err); }); }; })(this)); @@ -10576,6 +11175,63 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, }); this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, _) { + return Api.System = (function(_super) { + __extends(System, _super); + + function System() { + return System.__super__.constructor.apply(this, arguments); + } + + System.prototype.commandNameSpace = 'System'; + + System.prototype.getProperties = function(callback) { + var properties; + properties = ["canshutdown", "cansuspend", "canhibernate", "canreboot"]; + return this.singleCommand(this.getCommand('GetProperties'), [properties], (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + + System.prototype.hibernate = function(callback) { + return this.singleCommand(this.getCommand('Hibernate'), [], (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + + System.prototype.reboot = function(callback) { + return this.singleCommand(this.getCommand('Reboot'), [], (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + + System.prototype.shutdown = function(callback) { + return this.singleCommand(this.getCommand('Shutdown'), [], (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + + System.prototype.suspend = function(callback) { + return this.singleCommand(this.getCommand('Shutdown'), [], (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + + return System; + + })(Api.Commander); +}); + +this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, _) { return Api.VideoLibrary = (function(_super) { __extends(VideoLibrary, _super); @@ -10633,6 +11289,22 @@ this.Kodi.module("CommandApp.Kodi", function(Api, App, Backbone, Marionette, $, })(this)); }; + VideoLibrary.prototype.setMusicVideoDetails = function(id, fields, callback) { + var params; + if (fields == null) { + fields = {}; + } + params = { + musicvideoid: id + }; + params = _.extend(params, fields); + return this.singleCommand(this.getCommand('SetMusicVideoDetails'), params, (function(_this) { + return function(resp) { + return _this.doCallback(callback, resp); + }; + })(this)); + }; + VideoLibrary.prototype.scan = function(callback) { return this.singleCommand(this.getCommand('Scan'), (function(_this) { return function(resp) { @@ -11558,159 +12230,51 @@ this.Kodi.module("EPGApp.List", function(List, App, Backbone, Marionette, $, _) this.Kodi.module("ExternalApp", function(ExternalApp, App, Backbone, Marionette, $, _) {}); -this.Kodi.module("ExternalApp.TheMovieDB", function(Provider, App, Backbone, Marionette, $, _) { +this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marionette, $, _) { var API; API = { - getController: function() { - return new Provider.Controller(); - } - }; - Provider.Controller = (function(_super) { - __extends(Controller, _super); - - function Controller() { - return Controller.__super__.constructor.apply(this, arguments); - } - - Controller.prototype.apiKey = 'f7f51775877e0bb6703520952b3c7840'; - - Controller.prototype.baseURL = 'https://api.themoviedb.org/3/'; - - Controller.prototype.baseImageURL = 'https://image.tmdb.org/t/p/'; - - Controller.prototype.defaultLang = 'en'; - - Controller.prototype.maxImageCount = 15; - - Controller.prototype.thumbSize = { - backdrops: 'w300', - posters: 'w185' - }; - - Controller.prototype.fieldTranslate = { - backdrops: 'fanart', - posters: 'thumbnail' - }; - - Controller.prototype.call = function(path, params, callback) { - var defaultParams, url; - defaultParams = { - api_key: this.apiKey - }; - params = _.extend(defaultParams, params); - url = this.baseURL + path + helpers.url.buildParams(params) + '&callback=?'; - return $.getJSON(url, function(resp) { - return callback(resp); - }); - }; - - Controller.prototype.getImageURL = function(path, size) { - if (size == null) { - size = 'original'; - } - return this.baseImageURL + size + path; - }; - - Controller.prototype.addImageUrls = function(collection) { - var field, i, item, ret, row, type, types, _i, _len, _ref; - ret = {}; - types = ['backdrops', 'posters']; - for (_i = 0, _len = types.length; _i < _len; _i++) { - type = types[_i]; - field = this.fieldTranslate[type]; - ret[field] = []; - collection[type] = collection[type].slice(0, this.maxImageCount); - _ref = collection[type]; - for (i in _ref) { - item = _ref[i]; - row = item; - row.original = this.getImageURL(item.file_path, 'original'); - row.thumb = this.getImageURL(item.file_path, this.thumbSize[type]); - ret[field].push(row); - } - } - return ret; - }; - - Controller.prototype.find = function(id, source, callback) { - if (source == null) { - source = 'imdb_id'; - } - return this.call('find/' + id, { - external_source: source - }, callback); - }; - - Controller.prototype.images = function(type, tmdbId, callback) { - return this.call(type + '/' + tmdbId + '/images', { - include_image_language: this.defaultLang + ',null' - }, (function(_this) { - return function(resp) { - return callback(_this.addImageUrls(resp)); - }; - })(this)); - }; - - return Controller; - - })(App.Controllers.Base); - App.commands.setHandler("themoviedb:movie:images", function(imdbId, callback) { - var controller; - controller = API.getController(); - return controller.find(imdbId, 'imdb_id', function(resp) { - var item; - if (resp.movie_results && resp.movie_results.length > 0) { - item = _.first(resp.movie_results); - return controller.images('movie', item.id, callback); - } else { - return callback(false); + getSearchView: function(query, viewName, title, options, callback) { + if (title == null) { + title = ''; } - }); - }); - return App.commands.setHandler("themoviedb:tv:images", function(id, callback) { - var controller, idType; - controller = API.getController(); - idType = id.lastIndexOf('tt', 0) === 0 ? 'imdb_id' : 'tvdb_id'; - return controller.find(id, idType, function(resp) { - var item; - if (resp.tv_results && resp.tv_results.length > 0) { - item = _.first(resp.tv_results); - return controller.images('tv', item.id, callback); - } else { - return callback(false); + if (options == null) { + options = {}; } - }); - }); -}); - -this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marionette, $, _) { - var API; - API = { - getSearchView: function(query, callback) { - return App.execute("youtube:search:entities", query, function(collection) { + return App.execute("youtube:search:entities", query, options, function(collection) { var view; - view = new Youtube.List({ - collection: collection + view = new Youtube[viewName]({ + collection: collection, + title: title }); - App.listenTo(view, 'childview:youtube:kodiplay', function(parent, item) { - var playlist; - playlist = App.request("command:kodi:controller", 'video', 'PlayList'); - return playlist.play('file', 'plugin://plugin.video.youtube/play/?video_id=' + item.model.get('id')); + App.listenTo(view, 'childview:youtube:play', function(parent, item) { + if (item.model.get('addonEnabled')) { + return API.playKodi(item.model.get('id')); + } else { + return API.playLocal(item.model.get('id')); + } }); App.listenTo(view, 'childview:youtube:localplay', function(parent, item) { - var localPlayer; - localPlayer = "videoPlayer.html?yt=" + item.model.get('id'); - return helpers.global.localVideoPopup(localPlayer, 530); + return API.playLocal(item.model.get('id')); }); return callback(view); }); + }, + playLocal: function(id) { + var localPlayer; + localPlayer = "videoPlayer.html?yt=" + id; + return helpers.global.localVideoPopup(localPlayer, 530); + }, + playKodi: function(id) { + var playlist; + playlist = App.request("command:kodi:controller", 'video', 'PlayList'); + return playlist.play('file', 'plugin://plugin.video.youtube/play/?video_id=' + id); } }; App.commands.setHandler("youtube:search:view", function(query, callback) { - return API.getSearchView(query, callback); + return API.getSearchView(query, 'List', '', {}, callback); }); - return App.commands.setHandler("youtube:search:popup", function(query) { - return API.getSearchView(query, function(view) { + App.commands.setHandler("youtube:search:popup", function(query) { + return API.getSearchView(query, 'List', '', {}, function(view) { var $footer; $footer = $('<a>', { "class": 'btn btn-primary', @@ -11721,6 +12285,12 @@ this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marione return App.execute("ui:modal:show", query, view.render().$el, $footer); }); }); + return App.commands.setHandler("youtube:list:view", function(query, title, options, callback) { + if (options == null) { + options = {}; + } + return API.getSearchView(query, 'CardList', title, options, callback); + }); }); this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marionette, $, _) { @@ -11736,8 +12306,8 @@ this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marione Item.prototype.tagName = 'li'; Item.prototype.triggers = { - 'click .play-kodi': 'youtube:kodiplay', - 'click .play-local': 'youtube:localplay' + 'click .play': 'youtube:play', + 'click .localplay': 'youtube:localplay' }; Item.prototype.events = { @@ -11751,7 +12321,7 @@ this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marione return Item; })(App.Views.ItemView); - return Youtube.List = (function(_super) { + Youtube.List = (function(_super) { __extends(List, _super); function List() { @@ -11767,6 +12337,60 @@ this.Kodi.module("ExternalApp.Youtube", function(Youtube, App, Backbone, Marione return List; })(App.Views.CollectionView); + Youtube.Card = (function(_super) { + __extends(Card, _super); + + function Card() { + return Card.__super__.constructor.apply(this, arguments); + } + + Card.prototype.triggers = { + 'click .play': 'youtube:play', + 'click .localplay': 'youtube:localplay' + }; + + Card.prototype.initialize = function() { + return this.getMeta(); + }; + + Card.prototype.getMeta = function() { + if (this.model) { + this.model.set({ + subtitle: this.themeLink('YouTube', this.model.get('url'), { + external: true + }) + }); + if (this.model.get('addonEnabled')) { + return this.model.set({ + menu: { + localplay: 'Local play' + } + }); + } + } + }; + + Card.prototype.onRender = function() { + return this.makeLinksExternal(); + }; + + return Card; + + })(App.Views.CardView); + return Youtube.CardList = (function(_super) { + __extends(CardList, _super); + + function CardList() { + return CardList.__super__.constructor.apply(this, arguments); + } + + CardList.prototype.childView = Youtube.Card; + + CardList.prototype.className = "section-content card-grid--musicvideo"; + + return CardList; + + })(App.Views.SetCompositeView); }); this.Kodi.module("FilterApp", function(FilterApp, App, Backbone, Marionette, $, _) { @@ -11814,6 +12438,11 @@ this.Kodi.module("FilterApp", function(FilterApp, App, Backbone, Marionette, $, type: 'other', key: 'random', defaultOrder: 'asc' + }, { + alias: 'album', + type: 'string', + key: 'album', + defaultOrder: 'asc' } ], filterFields: [ @@ -11906,6 +12535,18 @@ this.Kodi.module("FilterApp", function(FilterApp, App, Backbone, Marionette, $, key: 'thumbsUp', sortOrder: 'asc', filterCallback: 'thumbsup' + }, { + alias: 'album', + type: 'string', + key: 'album', + sortOrder: 'asc', + filterCallback: 'multiple' + }, { + alias: 'artist', + type: 'array', + key: 'artist', + sortOrder: 'asc', + filterCallback: 'multiple' } ], getFilterFields: function(type) { @@ -13103,10 +13744,17 @@ this.Kodi.module("Images", function(Images, App, Backbone, Marionette, $, _) { default: path = API.getDefaultThumbnail(); } + } else if (type === 'trailer') { + path = API.getTrailerUrl(rawPath); } else { path = API.parseRawPath(rawPath); } return path; + }, + getTrailerUrl: function(rawpath) { + var trailer; + trailer = helpers.url.parseTrailerUrl(rawpath); + return trailer.img; } }; App.commands.setHandler("images:fanart:set", function(path, region) { @@ -13250,10 +13898,12 @@ this.Kodi.module("InputApp", function(InputApp, App, Backbone, Marionette, $, _) return this.doInput("Select"); case 67: return this.doInput("ContextMenu"); - case 107 || 187: + case 107: + case 187: vol = stateObj.getState('volume') + 5; return this.appController().setVolume((vol > 100 ? 100 : Math.ceil(vol))); - case 109 || 189: + case 109: + case 189: vol = stateObj.getState('volume') - 5; return this.appController().setVolume((vol < 0 ? 0 : Math.ceil(vol))); case 32: @@ -13342,11 +13992,11 @@ this.Kodi.module("InputApp.Remote", function(Remote, App, Backbone, Marionette, return App.execute("input:send", 'Info'); } }); - this.listenTo(view, "remote:power", function() { - var appController; - appController = App.request("command:kodi:controller", 'auto', 'Application'); - return appController.quit(); - }); + this.listenTo(view, "remote:power", (function(_this) { + return function() { + return _this.getShutdownMenu(); + }; + })(this)); App.regionRemote.show(view); return App.vent.on("state:changed", function(state) { var fanart, playingItem, stateObj; @@ -13359,13 +14009,68 @@ this.Kodi.module("InputApp.Remote", function(Remote, App, Backbone, Marionette, }); }; + Controller.prototype.getShutdownMenu = function() { + var system; + system = App.request("command:kodi:controller", 'auto', 'System'); + return system.getProperties(function(props) { + var $content, action, actions, model, optionalActions, prop, view, _i, _len; + actions = []; + optionalActions = ['shutdown', 'reboot', 'suspend', 'hibernate']; + actions.push({ + id: 'quit', + title: 'Quit Kodi' + }); + for (_i = 0, _len = optionalActions.length; _i < _len; _i++) { + action = optionalActions[_i]; + prop = 'can' + action; + if (props[prop]) { + actions.push({ + id: action, + title: action + }); + } + } + model = new Backbone.Model({ + id: 1, + actions: actions + }); + view = new Remote.System({ + model: model + }); + $content = view.render().$el; + App.execute("ui:modal:show", tr('Shutdown menu'), $content, '', false, 'system'); + return App.listenTo(view, 'system:action', (function(_this) { + return function(action) { + switch (action) { + case 'quit': + App.request("command:kodi:controller", 'auto', 'Application').quit(); + break; + case 'shutdown': + system.shutdown(); + break; + case 'reboot': + system.reboot(); + break; + case 'suspend': + system.suspend(); + break; + case 'hibernate': + system.hibernate(); + break; + } + return App.execute("ui:modal:close"); + }; + })(this)); + }); + }; + return Controller; })(App.Controllers.Base); }); this.Kodi.module("InputApp.Remote", function(Remote, App, Backbone, Marionette, $, _) { - return Remote.Control = (function(_super) { + Remote.Control = (function(_super) { __extends(Control, _super); function Control() { @@ -13415,6 +14120,30 @@ this.Kodi.module("InputApp.Remote", function(Remote, App, Backbone, Marionette, return Control; })(App.Views.ItemView); + return Remote.System = (function(_super) { + __extends(System, _super); + + function System() { + return System.__super__.constructor.apply(this, arguments); + } + + System.prototype.template = 'apps/input/remote/system'; + + System.prototype.className = 'system-menu'; + + System.prototype.events = { + 'click li': 'doAction' + }; + + System.prototype.doAction = function(e) { + var action; + action = $(e.target).data('action'); + return this.trigger('system:action', action); + }; + + return System; + + })(App.Views.ItemView); }); this.Kodi.module("InputApp.Resume", function(Resume, App, Backbone, Marionette, $, _) { @@ -13954,7 +14683,8 @@ this.Kodi.module("LandingApp", function(LandingApp, App, Backbone, Marionette, $ 'field': 'inprogress', 'value': '' }, - moreLink: 'tvshows?sort=dateadded&order=desc&inprogress=in progress' + moreLink: 'tvshows?sort=dateadded&order=desc&inprogress=in progress', + preventSelect: true }, { title: 'Recently added', entity: 'episode', @@ -14131,10 +14861,17 @@ this.Kodi.module("LandingApp.Show", function(Show, App, Backbone, Marionette, $, }); App.listenTo(setView, "show", (function(_this) { return function() { - return setView.regionResult.show(view); + return setView.regionCollection.show(view); }; })(this)); - return this.content["regionSection" + section.idx].show(setView); + App.listenTo(setView, 'landing:set:more', function(viewItem) { + return App.navigate(viewItem.model.get('section').moreLink, { + trigger: true + }); + }); + if (this.content["regionSection" + section.idx]) { + return this.content["regionSection" + section.idx].show(setView); + } }; Controller.prototype.addFilterValue = function(section) { @@ -14183,7 +14920,7 @@ this.Kodi.module("LandingApp.Show", function(Show, App, Backbone, Marionette, $, return Layout; })(App.Views.LayoutWithSidebarFirstView); - Show.Page = (function(_super) { + return Show.Page = (function(_super) { __extends(Page, _super); function Page() { @@ -14204,43 +14941,44 @@ this.Kodi.module("LandingApp.Show", function(Show, App, Backbone, Marionette, $, regionSection6: '#landing-section-6' }; - return Page; + Show.ListSet = (function(_super1) { + __extends(ListSet, _super1); - })(App.Views.LayoutView); - return Show.ListSet = (function(_super) { - __extends(ListSet, _super); + function ListSet() { + return ListSet.__super__.constructor.apply(this, arguments); + } - function ListSet() { - this.onRender = __bind(this.onRender, this); - return ListSet.__super__.constructor.apply(this, arguments); - } + ListSet.prototype.className = 'landing-set'; - ListSet.prototype.template = 'apps/landing/show/landing_set'; + ListSet.prototype.triggers = { + 'click .more': 'landing:set:more' + }; - ListSet.prototype.className = "landing-set"; + ListSet.prototype.initialize = function() { + this.setOptions(); + return this.createModel(); + }; - ListSet.prototype.onRender = function() { - var $header; - if (this.options) { - $header = $('h3.set-header', this.$el); + ListSet.prototype.setOptions = function() { + this.options.menu = {}; if (this.options.filter !== false && this.options.section.title) { - $header.html(t.sprintf(tr(this.options.section.title), this.options.filter)); + this.options.title = t.sprintf(tr(this.options.section.title), this.options.filter); } else if (this.options.section.title) { - $header.html(tr(this.options.section.title)); + this.options.title = tr(this.options.section.title); } - if (this.options.filter !== false && this.options.section.moreLink) { - return $header.append(this.themeLink(tr('more'), this.options.section.moreLink + this.options.filter)); - } else if (this.options.section.moreLink) { - return $header.append(this.themeLink(tr('more'), this.options.section.moreLink)); + if (this.options.section.moreLink) { + this.options.menu.more = tr('More like this'); } - } - }; + if (this.options.section.preventSelect) { + return this.options.noMenuDefault = true; + } + }; - ListSet.prototype.regions = { - regionResult: '.set-results' - }; + return ListSet; - return ListSet; + })(App.Views.SetLayoutView); + + return Page; })(App.Views.LayoutView); }); @@ -14919,13 +15657,19 @@ this.Kodi.module("MovieApp.Edit", function(Edit, App, Backbone, Marionette, $, _ } ] }, { - title: 'Other media', - id: 'media', + title: 'Trailer', + id: 'trailers', children: [ { id: 'trailer', - title: tr('Trailer'), - type: 'textfield' + title: tr('URL'), + type: 'imageselect', + attributes: { + "class": 'fanart-size' + }, + description: t.sprintf(tr('This should be the play path for the trailer. Eg. %1$s'), 'plugin://plugin.video.youtube/?action=play_video&videoid=[YOUTUBE_ID]'), + metadataImageHandler: 'youtube:trailer:entities', + metadataLookupField: 'title' } ] }, { @@ -14938,7 +15682,7 @@ this.Kodi.module("MovieApp.Edit", function(Edit, App, Backbone, Marionette, $, _ type: 'imageselect', valueProperty: 'thumbnailOriginal', description: tr('Add an image via an external URL'), - metadataImageHandler: 'themoviedb:movie:images', + metadataImageHandler: 'themoviedb:movie:image:entities', metadataLookupField: 'imdbnumber' } ] @@ -14952,7 +15696,7 @@ this.Kodi.module("MovieApp.Edit", function(Edit, App, Backbone, Marionette, $, _ type: 'imageselect', valueProperty: 'fanartOriginal', description: tr('Add an image via an external URL'), - metadataImageHandler: 'themoviedb:movie:images', + metadataImageHandler: 'themoviedb:movie:image:entities', metadataLookupField: 'imdbnumber' } ] @@ -15626,6 +16370,594 @@ this.Kodi.module("MovieApp.Show", function(Show, App, Backbone, Marionette, $, _ })(App.Views.LayoutView); }); +this.Kodi.module("MusicVideoApp.Edit", function(Edit, App, Backbone, Marionette, $, _) { + return Edit.Controller = (function(_super) { + __extends(Controller, _super); + + function Controller() { + return Controller.__super__.constructor.apply(this, arguments); + } + + Controller.prototype.initialize = function() { + var form, options; + this.model = this.getOption('model'); + options = { + title: '<span>' + tr('Edit') + '</span>' + this.model.get('title'), + form: this.getStructure(), + formState: this.model.attributes, + config: { + attributes: { + "class": 'edit-form' + }, + editForm: true, + tabs: true, + callback: (function(_this) { + return function(data, formView) { + return _this.saveCallback(data, formView); + }; + })(this) + } + }; + return form = App.request("form:popup:wrapper", options); + }; + + Controller.prototype.getStructure = function() { + return [ + { + title: 'General', + id: 'general', + children: [ + { + id: 'title', + title: tr('Title'), + type: 'textfield' + }, { + id: 'artist', + title: tr('Artist'), + type: 'textfield', + format: 'array.string' + }, { + id: 'album', + title: tr('Album'), + type: 'textfield' + }, { + id: 'plot', + title: tr('Plot'), + type: 'textarea' + }, { + id: 'studio', + title: tr('Studio'), + type: 'textfield', + format: 'array.string' + }, { + id: 'year', + title: tr('Year'), + type: 'number', + format: 'integer', + attributes: { + "class": 'half-width', + step: 1, + min: 0, + max: 9999 + } + }, { + id: 'rating', + title: tr('Rating'), + type: 'number', + format: 'float', + attributes: { + "class": 'half-width', + step: 0.1, + min: 0, + max: 10 + }, + suffix: '<div class="clearfix"></div>' + } + ] + }, { + title: 'Tags', + id: 'tags', + children: [ + { + id: 'director', + title: tr('Directors'), + type: 'textfield', + format: 'array.string' + }, { + id: 'genre', + title: tr('Genres'), + type: 'textfield', + format: 'array.string' + }, { + id: 'tag', + title: tr('Tags'), + type: 'textfield', + format: 'array.string' + } + ] + }, { + title: 'Poster', + id: 'poster', + children: [ + { + id: 'thumbnail', + title: tr('URL'), + type: 'imageselect', + valueProperty: 'thumbnailOriginal', + description: tr('Add an image via an external URL'), + attributes: { + "class": 'fanart-size' + }, + metadataImageHandler: 'fanarttv:artist:image:entities', + metadataLookupField: 'artist' + } + ] + }, { + title: 'Background', + id: 'background', + children: [ + { + id: 'fanart', + title: tr('URL'), + type: 'imageselect', + valueProperty: 'fanartOriginal', + description: tr('Add an image via an external URL'), + metadataImageHandler: 'fanarttv:artist:image:entities', + metadataLookupField: 'artist' + } + ] + }, { + title: 'Information', + id: 'info', + children: [ + { + id: 'file', + title: tr('File path'), + type: 'textarea', + attributes: { + disabled: 'disabled', + cols: 5 + }, + format: 'prevent.submit' + } + ] + } + ]; + }; + + Controller.prototype.saveCallback = function(data, formView) { + var controller; + controller = App.request("command:kodi:controller", 'audio', 'VideoLibrary'); + return controller.setMusicVideoDetails(this.model.get('id'), data, (function(_this) { + return function() { + Kodi.vent.trigger('entity:kodi:update', _this.model.get('uid')); + return Kodi.execute("notification:show", t.sprintf(tr("Updated %1$s details"), 'album')); + }; + })(this)); + }; + + return Controller; + + })(App.Controllers.Base); +}); + +this.Kodi.module("MusicVideoApp.List", function(List, App, Backbone, Marionette, $, _) { + var API; + API = { + bindTriggers: function(view) { + App.listenTo(view, 'childview:musicvideo:play', function(parent, viewItem) { + return App.execute('musicvideo:action', 'play', viewItem); + }); + App.listenTo(view, 'childview:musicvideo:add', function(parent, viewItem) { + return App.execute('musicvideo:action', 'add', viewItem); + }); + App.listenTo(view, 'childview:musicvideo:localplay', function(parent, viewItem) { + return App.execute('musicvideo:action', 'localplay', viewItem); + }); + App.listenTo(view, 'childview:musicvideo:download', function(parent, viewItem) { + return App.execute('musicvideo:action', 'download', viewItem); + }); + App.listenTo(view, 'childview:musicvideo:edit', function(parent, viewItem) { + return App.execute('musicvideo:edit', viewItem.model); + }); + return view; + }, + getVideoList: function(collection) { + var view; + view = new List.Videos({ + collection: collection + }); + API.bindTriggers(view); + return view; + } + }; + List.Controller = (function(_super) { + __extends(Controller, _super); + + function Controller() { + return Controller.__super__.constructor.apply(this, arguments); + } + + Controller.prototype.initialize = function() { + var collection; + collection = App.request("musicvideo:entities"); + return App.execute("when:entity:fetched", collection, (function(_this) { + return function() { + collection.availableFilters = _this.getAvailableFilters(); + collection.sectionId = 'music'; + App.request('filter:init', _this.getAvailableFilters()); + _this.layout = _this.getLayoutView(collection); + _this.listenTo(_this.layout, "show", function() { + _this.renderList(collection); + return _this.getFiltersView(collection); + }); + return App.regionContent.show(_this.layout); + }; + })(this)); + }; + + Controller.prototype.getLayoutView = function(collection) { + return new List.ListLayout({ + collection: collection + }); + }; + + Controller.prototype.getAvailableFilters = function() { + return { + sort: ['label', 'year', 'artist', 'album'], + filter: ['studio', 'director', 'artist', 'album', 'year'] + }; + }; + + Controller.prototype.getFiltersView = function(collection) { + var filters; + filters = App.request('filter:show', collection); + this.layout.regionSidebarFirst.show(filters); + return this.listenTo(filters, "filter:changed", (function(_this) { + return function() { + return _this.renderList(collection); + }; + })(this)); + }; + + Controller.prototype.renderList = function(collection) { + var filteredCollection, view; + App.execute("loading:show:view", this.layout.regionContent); + filteredCollection = App.request('filter:apply:entities', collection); + view = API.getVideoList(filteredCollection); + return this.layout.regionContent.show(view); + }; + + return Controller; + + })(App.Controllers.Base); + return App.reqres.setHandler("musicvideo:list:view", function(collection) { + return API.getVideoList(collection); + }); +}); + +this.Kodi.module("MusicVideoApp.List", function(List, App, Backbone, Marionette, $, _) { + List.ListLayout = (function(_super) { + __extends(ListLayout, _super); + + function ListLayout() { + return ListLayout.__super__.constructor.apply(this, arguments); + } + + ListLayout.prototype.className = "musicvideo-list with-filters"; + + return ListLayout; + + })(App.Views.LayoutWithSidebarFirstView); + List.Teaser = (function(_super) { + __extends(Teaser, _super); + + function Teaser() { + return Teaser.__super__.constructor.apply(this, arguments); + } + + Teaser.prototype.triggers = { + "click .play": "musicvideo:play", + "click .add": "musicvideo:add", + 'click .stream': 'musicvideo:localplay', + 'click .download': 'musicvideo:download', + 'click .edit': 'musicvideo:edit', + 'click .refresh': 'musicvideo:refresh' + }; + + Teaser.prototype.initialize = function() { + Teaser.__super__.initialize.apply(this, arguments); + if (this.model != null) { + this.setMeta(); + return this.model.set(App.request('musicvideo:action:items')); + } + }; + + Teaser.prototype.setMeta = function() { + var artist, artistLink; + if (this.model) { + artist = this.model.get('artist') !== '' ? this.model.get('artist') : ' '; + artistLink = this.themeLink(artist, 'search/artist/' + artist); + return this.model.set({ + subtitle: artistLink + }); + } + }; + + return Teaser; + + })(App.Views.CardView); + List.Empty = (function(_super) { + __extends(Empty, _super); + + function Empty() { + return Empty.__super__.constructor.apply(this, arguments); + } + + Empty.prototype.tagName = "li"; + + Empty.prototype.className = "musicvideo-empty-result"; + + return Empty; + + })(App.Views.EmptyViewResults); + return List.Videos = (function(_super) { + __extends(Videos, _super); + + function Videos() { + return Videos.__super__.constructor.apply(this, arguments); + } + + Videos.prototype.childView = List.Teaser; + + Videos.prototype.emptyView = List.Empty; + + Videos.prototype.tagName = "ul"; + + Videos.prototype.className = "card-grid--musicvideo"; + + return Videos; + + })(App.Views.VirtualListView); +}); + +this.Kodi.module("MusicVideoApp", function(MusicVideoApp, App, Backbone, Marionette, $, _) { + var API; + MusicVideoApp.Router = (function(_super) { + __extends(Router, _super); + + function Router() { + return Router.__super__.constructor.apply(this, arguments); + } + + Router.prototype.appRoutes = { + "music/videos": "list", + "music/video/:id": "view" + }; + + return Router; + + })(App.Router.Base); + API = { + list: function() { + return new MusicVideoApp.List.Controller(); + }, + view: function(id) { + return new MusicVideoApp.Show.Controller({ + id: id + }); + }, + action: function(op, view) { + var files, model, playlist, videoLib; + model = view.model; + playlist = App.request("command:kodi:controller", 'video', 'PlayList'); + files = App.request("command:kodi:controller", 'video', 'Files'); + videoLib = App.request("command:kodi:controller", 'video', 'VideoLibrary'); + switch (op) { + case 'play': + return App.execute("input:resume", model, 'musicvideoid'); + case 'add': + return playlist.add('musicvideoid', model.get('musicvideoid')); + case 'localplay': + return files.videoStream(model.get('file'), model.get('fanart')); + case 'download': + return files.downloadFile(model.get('file')); + case 'refresh': + return helpers.entities.refreshEntity(model, videoLib, 'refreshMusicVideo'); + } + } + }; + App.on("before:start", function() { + return new MusicVideoApp.Router({ + controller: API + }); + }); + App.commands.setHandler('musicvideo:action', function(op, model) { + return API.action(op, model); + }); + App.reqres.setHandler('musicvideo:action:items', function() { + return { + actions: { + thumbs: tr('Thumbs up') + }, + menu: { + 'add': tr('Queue in Kodi'), + 'divider-1': '', + 'download': tr('Download'), + 'stream': tr('Play in browser'), + 'divider-2': '', + 'edit': tr('Edit') + } + }; + }); + return App.commands.setHandler('musicvideo:edit', function(model) { + var loadedModel; + loadedModel = App.request("musicvideo:entity", model.get('id')); + return App.execute("when:entity:fetched", loadedModel, (function(_this) { + return function() { + return new MusicVideoApp.Edit.Controller({ + model: loadedModel + }); + }; + })(this)); + }); +}); + +this.Kodi.module("MusicVideoApp.Show", function(Show, App, Backbone, Marionette, $, _) { + var API; + API = { + bindTriggers: function(view) { + App.listenTo(view, 'musicvideo:play', function(viewItem) { + return App.execute('musicvideo:action', 'play', viewItem); + }); + App.listenTo(view, 'musicvideo:add', function(viewItem) { + return App.execute('musicvideo:action', 'add', viewItem); + }); + App.listenTo(view, 'musicvideo:localplay', function(viewItem) { + return App.execute('musicvideo:action', 'localplay', viewItem); + }); + App.listenTo(view, 'musicvideo:download', function(viewItem) { + return App.execute('musicvideo:action', 'download', viewItem); + }); + App.listenTo(view, 'musicvideo:edit', function(viewItem) { + return App.execute('musicvideo:edit', viewItem.model); + }); + return view; + } + }; + return Show.Controller = (function(_super) { + __extends(Controller, _super); + + function Controller() { + return Controller.__super__.constructor.apply(this, arguments); + } + + Controller.prototype.initialize = function(options) { + var id, musicvideo; + id = parseInt(options.id); + musicvideo = App.request("musicvideo:entity", id); + return App.execute("when:entity:fetched", musicvideo, (function(_this) { + return function() { + _this.layout = _this.getLayoutView(musicvideo); + _this.listenTo(_this.layout, "show", function() { + _this.getDetailsLayoutView(musicvideo); + return _this.getRelatedVideos(musicvideo); + }); + return App.regionContent.show(_this.layout); + }; + })(this)); + }; + + Controller.prototype.getLayoutView = function(musicvideo) { + return new Show.PageLayout({ + model: musicvideo + }); + }; + + Controller.prototype.getDetailsLayoutView = function(musicvideo) { + var headerLayout; + headerLayout = new Show.HeaderLayout({ + model: musicvideo + }); + this.listenTo(headerLayout, "show", (function(_this) { + return function() { + var detail, teaser; + teaser = new Show.DetailTeaser({ + model: musicvideo + }); + API.bindTriggers(teaser); + detail = new Show.Details({ + model: musicvideo + }); + _this.listenTo(detail, "show", function() { + return API.bindTriggers(detail); + }); + headerLayout.regionSide.show(teaser); + return headerLayout.regionMeta.show(detail); + }; + })(this)); + return this.layout.regionHeader.show(headerLayout); + }; + + Controller.prototype.getRelatedVideos = function(musicvideo) { + var opts, title; + title = tr('Related music videos from YouTube'); + opts = { + maxResults: 8 + }; + return App.execute('youtube:list:view', musicvideo.get('title') + ' ' + musicvideo.get('artist'), title, opts, (function(_this) { + return function(view) { + return _this.layout.regionContent.show(view); + }; + })(this)); + }; + + return Controller; + + })(App.Controllers.Base); +}); + +this.Kodi.module("MusicVideoApp.Show", function(Show, App, Backbone, Marionette, $, _) { + Show.PageLayout = (function(_super) { + __extends(PageLayout, _super); + + function PageLayout() { + return PageLayout.__super__.constructor.apply(this, arguments); + } + + PageLayout.prototype.className = 'musicvideo-show detail-container'; + + return PageLayout; + + })(App.Views.LayoutWithHeaderView); + Show.HeaderLayout = (function(_super) { + __extends(HeaderLayout, _super); + + function HeaderLayout() { + return HeaderLayout.__super__.constructor.apply(this, arguments); + } + + HeaderLayout.prototype.className = 'musicvideo-details'; + + return HeaderLayout; + + })(App.Views.LayoutDetailsHeaderView); + Show.Details = (function(_super) { + __extends(Details, _super); + + function Details() { + return Details.__super__.constructor.apply(this, arguments); + } + + Details.prototype.template = 'apps/musicvideo/show/details_meta'; + + Details.prototype.triggers = { + "click .play": "musicvideo:play", + "click .add": "musicvideo:add", + "click .download": "musicvideo:download", + "click .localplay": "musicvideo:localplay", + "click .edit": "musicvideo:edit" + }; + + return Details; + + })(App.Views.DetailsItem); + return Show.DetailTeaser = (function(_super) { + __extends(DetailTeaser, _super); + + function DetailTeaser() { + return DetailTeaser.__super__.constructor.apply(this, arguments); + } + + DetailTeaser.prototype.attributes = function() { + return this.watchedAttributes('card-detail'); + }; + + return DetailTeaser; + + })(App.MusicVideoApp.List.Teaser); +}); + this.Kodi.module("NavMain", function(NavMain, App, Backbone, Marionette, $, _) { var API; API = { @@ -16756,16 +18088,23 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, Controller.prototype.maxItemsCombinedSearch = 21; - Controller.prototype.allEntities = ['movie', 'tvshow', 'artist', 'album', 'song']; + Controller.prototype.allEntities = ['movie', 'tvshow', 'artist', 'album', 'song', 'musicvideo']; Controller.prototype.searchFieldMap = { artist: 'artist', album: 'album', song: 'title', movie: 'title', - tvshow: 'title' + tvshow: 'title', + musicvideo: 'title' }; + Controller.prototype.entityTitles = { + musicvideo: 'music video' + }; + + Controller.prototype.entityPreventSelect = ['tvshow']; + Controller.prototype.initialize = function() { var media; this.pageLayout = this.getPageLayout(); @@ -16773,6 +18112,7 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, this.processed = []; this.processedItems = 0; this.addonSearches = App.request("addon:search:enabled"); + App.execute("selected:clear:items"); media = this.getOption('media'); if (media === 'all') { this.entities = this.allEntities; @@ -16826,7 +18166,7 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, media = _ref[_i]; medias.push({ id: media, - title: media + 's' + title: this.getTitle(media) + 's' }); } opts = { @@ -16886,10 +18226,11 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, entity: entity, more: more, query: query, - title: entity + 's' + title: _this.getTitle(entity) + 's', + noMenuDefault: helpers.global.inArray(entity, _this.entityPreventSelect) }); App.listenTo(setView, "show", function() { - return setView.regionResult.show(view); + return setView.regionCollection.show(view); }); _this.layout["" + entity + "Set"].show(setView); } @@ -16926,7 +18267,8 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, entity: addonSearch.title, title: i === 1 ? addonSearch.title : '', more: false, - query: _this.getOption('query') + query: _this.getOption('query'), + noMenuDefault: true }); App.listenTo(setView, "show", function() { return setView.regionResult.show(filesView); @@ -16941,6 +18283,12 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, return App.request("file:entities", opts); }; + Controller.prototype.getTitle = function(entity) { + var title; + title = this.entityTitles[entity] ? this.entityTitles[entity] : entity; + return title; + }; + Controller.prototype.updateProgress = function(done) { if (done != null) { this.processed.push(done); @@ -16981,7 +18329,7 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, ListLayout.prototype.template = 'apps/search/list/search_layout'; - ListLayout.prototype.className = "search-page set-page"; + ListLayout.prototype.className = "search-page"; ListLayout.prototype.regions = { artistSet: '.entity-set-artist', @@ -16989,6 +18337,7 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, songSet: '.entity-set-song', movieSet: '.entity-set-movie', tvshowSet: '.entity-set-tvshow', + musicvideoSet: '.entity-set-musicvideo', loadingSet: '.entity-set-loading' }; @@ -17000,40 +18349,31 @@ this.Kodi.module("SearchApp.List", function(List, App, Backbone, Marionette, $, return this[addonViewId].show(addonView); }; - return ListLayout; + List.ListSet = (function(_super1) { + __extends(ListSet, _super1); - })(App.Views.LayoutView); - List.ListSet = (function(_super) { - __extends(ListSet, _super); - - function ListSet() { - return ListSet.__super__.constructor.apply(this, arguments); - } + function ListSet() { + return ListSet.__super__.constructor.apply(this, arguments); + } - ListSet.prototype.template = 'apps/search/list/search_set'; + ListSet.prototype.className = "search-set landing-set"; - ListSet.prototype.className = "search-set"; + ListSet.prototype.initialize = function() { + this.setOptions(); + return this.createModel(); + }; - ListSet.prototype.onRender = function() { - var moreLink; - if (this.options && this.options.entity) { - if (this.options.title) { - $('h2.set-header', this.$el).html(t.gettext(this.options.title)); - } else { - $('h2.set-header', this.$el).remove(); - } + ListSet.prototype.setOptions = function() { if (this.options.more && this.options.query) { - moreLink = this.themeLink(t.gettext('Show more'), 'search/' + this.options.entity + '/' + this.options.query); - return $('.more', this.$el).html(moreLink); + return this.options.more = this.themeLink(t.gettext('Show more'), 'search/' + this.options.entity + '/' + this.options.query); } - } - }; + }; - ListSet.prototype.regions = { - regionResult: '.set-results' - }; + return ListSet; - return ListSet; + })(App.Views.SetLayoutView); + + return ListLayout; })(App.Views.LayoutView); return List.Sidebar = (function(_super) { @@ -18136,14 +19476,16 @@ this.Kodi.module("SettingsApp.Show.navMain", function(NavMain, App, Backbone, Ma $(this).closest('.add-another-wrapper').before(formView.render().$el); return self.binds(); }); - $('.form-groups', $ctx).sortable({ - draggable: ".draggable-row", - onEnd: function(e) { - return $('input[id^="form-edit-weight-"]', e.target).each(function(i, d) { - return $(d).attr('value', i); - }); - } - }); + if ($(window).width() > config.getLocal('largeBreakpoint')) { + $('.form-groups', $ctx).sortable({ + draggable: ".draggable-row", + onEnd: function(e) { + return $('input[id^="form-edit-weight-"]', e.target).each(function(i, d) { + return $(d).attr('value', i); + }); + } + }); + } return $('.nav-restore-defaults', $ctx).on("click", (function(_this) { return function(e) { e.preventDefault(); @@ -18298,14 +19640,16 @@ this.Kodi.module("SettingsApp.Show.Search", function(Search, App, Backbone, Mari $ctx = this.layout.regionContent.$el; $('.settings-form').addClass('settings-form-draggable'); this.binds(); - $('.form-groups', $ctx).sortable({ - draggable: ".draggable-row", - onEnd: function(e) { - return $('input[id^="form-edit-weight-"]', e.target).each(function(i, d) { - return $(d).attr('value', i); - }); - } - }); + if ($(window).width() > config.getLocal('largeBreakpoint')) { + $('.form-groups', $ctx).sortable({ + draggable: ".draggable-row", + onEnd: function(e) { + return $('input[id^="form-edit-weight-"]', e.target).each(function(i, d) { + return $(d).attr('value', i); + }); + } + }); + } $('#form-edit-add-another', $ctx).click(function(e) { var blank, formView, row; e.preventDefault(); @@ -18513,6 +19857,11 @@ this.Kodi.module("Shell", function(Shell, App, Backbone, Marionette, $, _) { return _this.alterRegionClasses('toggle', "shell-playlist-closed"); }; })(this)); + App.listenTo(shellLayout, "shell:reconnect", (function(_this) { + return function() { + return App.execute('shell:reconnect'); + }; + })(this)); this.bindListenersContextMenu(shellLayout); return this.bindListenersSelectedMenu(shellLayout); }, @@ -18575,7 +19924,7 @@ this.Kodi.module("Shell", function(Shell, App, Backbone, Marionette, $, _) { }); } }; - return App.addInitializer(function() { + App.addInitializer(function() { return App.commands.setHandler("shell:view:ready", function() { API.renderLayout(); new Shell.Router({ @@ -18587,6 +19936,18 @@ this.Kodi.module("Shell", function(Shell, App, Backbone, Marionette, $, _) { }); }); }); + App.commands.setHandler('shell:reconnect', function() { + API.alterRegionClasses('add', 'reconnecting'); + return helpers.connection.reconnect(function() { + API.alterRegionClasses('remove', 'lost-connection'); + return API.alterRegionClasses('remove', 'reconnecting'); + }); + }); + return App.commands.setHandler('shell:disconnect', function() { + API.alterRegionClasses('add', 'lost-connection'); + API.alterRegionClasses('remove', 'reconnecting'); + return helpers.connection.disconnect(function() {}); + }); }); this.Kodi.module("Shell", function(Shell, App, Backbone, Marionette, $, _) { @@ -18628,7 +19989,8 @@ this.Kodi.module("Shell", function(Shell, App, Backbone, Marionette, $, _) { "click .about": "shell:about", "click .selected-play": "shell:selected:play", "click .selected-add": "shell:selected:add", - "click .selected-localadd": "shell:selected:localadd" + "click .selected-localadd": "shell:selected:localadd", + "click .reconnect": "shell:reconnect" }; Layout.prototype.events = { @@ -18922,7 +20284,7 @@ this.Kodi.module("SongApp.List", function(List, App, Backbone, Marionette, $, _) }; Song.prototype.events = { - "click .dropdown > i": "menuPopulate", + "click .dropdown > i": "populateModelMenu", "click .thumbs": "toggleThumbs", "click": "toggleSelect" }; @@ -19308,7 +20670,12 @@ this.Kodi.module("StateApp.Kodi", function(StateApp, App, Backbone, Marionette, ws.onclose = (function(_this) { return function(resp) { helpers.debug.msg("Websockets Closed", "warning", resp); - return _this.wsActive = false; + _this.wsActive = false; + App.execute("notification:show", tr("Lost websocket connection")); + return setTimeout(function() { + App.execute("notification:show", tr("Attempting websockets reconnect")); + return App.execute('state:ws:init'); + }, 60000); }; })(this); } else { @@ -19462,6 +20829,11 @@ this.Kodi.module("StateApp.Kodi", function(StateApp, App, Backbone, Marionette, break; case 'System.OnQuit': App.execute("notification:show", t.gettext("Kodi has quit")); + App.execute("shell:disconnect"); + break; + case 'System.OnWake': + case 'System.OnRestart': + App.execute("shell:reconnect"); break; } }; @@ -19509,11 +20881,15 @@ this.Kodi.module("StateApp.Kodi", function(StateApp, App, Backbone, Marionette, }; Polling.prototype.update = function() { + if (config.getLocal('connected', true) === false) { + return; + } if (App.kodiPolling.failures < App.kodiPolling.maxFailures) { App.kodiPolling.updateState(); return App.kodiPolling.timeout = setTimeout(App.kodiPolling.ping, App.kodiPolling.currentInterval); } else { - return App.execute("notification:show", t.gettext("Unable to communicate with Kodi in a long time. I think it's dead Jim!")); + App.execute("notification:show", t.gettext("Unable to communicate with Kodi in a long time. I think it's dead Jim!")); + return App.execute("shell:disconnect"); } }; @@ -19728,6 +21104,9 @@ this.Kodi.module("StateApp", function(StateApp, App, Backbone, Marionette, $, _) stateObj = App.kodiState.getPlayer() === 'kodi' ? App.kodiState : App.localState; return stateObj; }); + App.commands.setHandler('state:ws:init', function() { + return App.kodiSockets = new StateApp.Kodi.Notifications(); + }); return App.vent.trigger("state:changed"); } }; @@ -19744,10 +21123,14 @@ this.Kodi.module("ThumbsApp.List", function(List, App, Backbone, Marionette, $, return Controller.__super__.constructor.apply(this, arguments); } + Controller.prototype.entityTitles = { + musicvideo: 'music video' + }; + Controller.prototype.initialize = function() { var entities; this.layout = this.getLayout(); - entities = ['song', 'artist', 'album', 'tvshow', 'movie', 'episode']; + entities = ['song', 'artist', 'album', 'tvshow', 'movie', 'episode', 'musicvideo']; this.listenTo(this.layout, "show", (function(_this) { return function() { var entity, _i, _len, _results; @@ -19774,7 +21157,7 @@ this.Kodi.module("ThumbsApp.List", function(List, App, Backbone, Marionette, $, if (loaded.length > 0) { view = App.request("" + entity + ":list:view", loaded, true); setView = new List.ListSet({ - entity: entity + entity: this.getTitle(entity) }); App.listenTo(setView, "show", (function(_this) { return function() { @@ -19785,6 +21168,12 @@ this.Kodi.module("ThumbsApp.List", function(List, App, Backbone, Marionette, $, } }; + Controller.prototype.getTitle = function(entity) { + var title; + title = this.entityTitles[entity] ? this.entityTitles[entity] : entity; + return title; + }; + return Controller; })(App.Controllers.Base); @@ -19808,7 +21197,8 @@ this.Kodi.module("ThumbsApp.List", function(List, App, Backbone, Marionette, $, songSet: '.entity-set-song', movieSet: '.entity-set-movie', tvshowSet: '.entity-set-tvshow', - episodeSet: '.entity-set-episode' + episodeSet: '.entity-set-episode', + musicvideoSet: '.entity-set-musicvideo' }; return ListLayout; @@ -20111,7 +21501,7 @@ this.Kodi.module("TVShowApp.EditShow", function(Edit, App, Backbone, Marionette, type: 'imageselect', valueProperty: 'thumbnailOriginal', description: tr('Add an image via an external URL'), - metadataImageHandler: 'themoviedb:tv:images', + metadataImageHandler: 'themoviedb:tv:image:entities', metadataLookupField: 'imdbnumber' } ] @@ -20125,7 +21515,7 @@ this.Kodi.module("TVShowApp.EditShow", function(Edit, App, Backbone, Marionette, type: 'imageselect', valueProperty: 'fanartOriginal', description: tr('Add an image via an external URL'), - metadataImageHandler: 'themoviedb:tv:images', + metadataImageHandler: 'themoviedb:tv:image:entities', metadataLookupField: 'imdbnumber' } ] @@ -20328,7 +21718,7 @@ this.Kodi.module("TVShowApp.Episode", function(Episode, App, Backbone, Marionett }; EpisodeTeaser.prototype.setMeta = function() { - var epNum, epNumFull, showLink; + var epNum, epNumFull, showLink, subTitleTip; epNum = this.themeTag('span', { "class": 'ep-num' }, this.model.get('season') + 'x' + this.model.get('episode') + ' '); @@ -20338,9 +21728,12 @@ this.Kodi.module("TVShowApp.Episode", function(Episode, App, Backbone, Marionett showLink = this.themeLink(this.model.get('showtitle') + ' ', 'tvshow/' + this.model.get('tvshowid'), { className: 'show-name' }); + subTitleTip = this.model.get('firstaired') ? { + title: tr('First aired') + ': ' + this.model.get('firstaired') + } : {}; return this.model.set({ label: epNum + this.model.get('title'), - subtitle: showLink + epNumFull + subtitle: this.themeTag('div', subTitleTip, showLink + epNumFull) }); }; @@ -21483,17 +22876,26 @@ this.Kodi.module("UiApp", function(UiApp, App, Backbone, Marionette, $, _) { API.confirmButtons(function() { return callback(true); }); - return API.openModal(title, msg, true); + return API.openModal(title, msg, true, 'confirm'); }); - App.commands.setHandler("ui:modal:show", function(title, msg, footer) { + App.commands.setHandler("ui:modal:show", function(title, msg, footer, closeButton, style) { if (msg == null) { msg = ''; } if (footer == null) { footer = ''; } + if (closeButton == null) { + closeButton = false; + } + if (style == null) { + style = ''; + } API.getModalButtonContainer().html(footer); - return API.openModal(title, msg, open); + if (closeButton) { + API.getModalButtonContainer().prepend(API.closeModalButton()); + } + return API.openModal(title, msg, true, style); }); App.commands.setHandler("ui:modal:form:show", function(title, msg, style) { if (msg == null) { diff --git a/addons/webinterface.default/lang/_strings/en.json b/addons/webinterface.default/lang/_strings/en.json index 0f668e9b81..31a620aece 100644 --- a/addons/webinterface.default/lang/_strings/en.json +++ b/addons/webinterface.default/lang/_strings/en.json @@ -1 +1 @@ -{"domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural_forms":"nplurals=2; plural=(n != 1);","lang":"en"},"Nothing playing":["Nothing playing"],"Deselect all":["Deselect all"],"Filters":["Filters"],"Sort":["Sort"],"Select a filter":["Select a filter"],"Select an option":["Select an option"],"filter":["filter"],"Add filter":["Add filter"],"Which player to start with":["Which player to start with"],"Ignore terms such as 'The' and 'A' when sorting lists":["Ignore terms such as 'The' and 'A' when sorting lists"],"When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries":["When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries"],"is the default":["is the default"],"The hostname used for websockets connection. Set to 'auto' to use the current hostname.":["The hostname used for websockets connection. Set to 'auto' to use the current hostname."],"How often do I poll for updates from Kodi (Only applies when websockets inactive)":["How often do I poll for updates from Kodi (Only applies when websockets inactive)"],"Enable support for reverse proxy.":["Enable support for reverse proxy."],"Web settings saved.":["Web settings saved."],"Just a sec...":["Just a sec..."],"Unable to communicate with Kodi in a long time. I think it's dead Jim!":["Unable to communicate with Kodi in a long time. I think it's dead Jim!"],"Video library scan started":["Video library scan started"],"Video library scan complete":["Video library scan complete"],"Audio library scan started":["Audio library scan started"],"Audio library scan complete":["Audio library scan complete"],"Kodi has quit":["Kodi has quit"],"Sections":["Sections"],"Back":["Back"],"Loading folder...":["Loading folder..."],"Show more":["Show more"],"to Kodi":["to Kodi"],"Playlist refreshed":["Playlist refreshed"],"Kodi":["Kodi"],"Local":["Local"],"Playlists":["Playlists"],"Existing playlists":["Existing playlists"],"Empty playlist, you should probably add something to it?":["Empty playlist, you should probably add something to it?"],"Create a new list":["Create a new list"],"Add to playlist":["Add to playlist"],"Added to your playlist":["Added to your playlist"],"Give your playlist a name":["Give your playlist a name"],"Recently added":["Recently added"],"Recently played":["Recently played"],"Season":["Season"],"Episode":["Episode"],"Play":["Play"],"Queue":["Queue"],"View on IMDb":["View on IMDb"],"Stream":["Stream"],"Download":["Download"],"complete":["complete"],"Synopsis":["Synopsis"],"Full cast":["Full cast"],"Websockets closed":["Websockets closed"],"Websockets host":["Websockets host"],"Websockets port":["Websockets port"],"Default player":["Default player"],"Ignore article":["Ignore article"],"Album artists only":["Album artists only"],"Poll interval":["Poll interval"],"Reverse proxy support":["Reverse proxy support"],"Language":["Language"],"Preferred language":["Preferred language"],"Ignore articles (terms such as \"The\" and \"A\") when sorting lists":["Ignore articles (terms such as \"The\" and \"A\") when sorting lists"],"sec":["sec"],"Your browser doesn't support websockets! Get with the times and update your browser.":["Your browser doesn't support websockets! Get with the times and update your browser."],"Failed to connect to websockets":["Failed to connect to websockets, so I am falling back to polling for updates. Which makes things slower and uses more resources. Please ensure you have 'Allow programs on other systems to control Kodi' ENABLED in the Kodi settings (System > Services > Remote control). You may also get this if you are using proxies or accessing via an IP address when localhost will suffice. If websockets normally works, you might just need to refresh your browser."],"Video":["Video"],"Audio":["Audio"],"Cast":["Cast"],"Director":["Director","Directors"],"Writer":["Writer","Writers"],"Subtitle":["Subtitle","Subtitles"],"Result":["Result","Results"],"Loading things...":["Loading things..."],"Scan video library":["Scan video library"],"Scan audio library":["Scan audio library"],"About Chorus":["About Chorus"],"Recent":["Recent"],"Artists":["Artists"],"Albums":["Albums"],"Recent movies":["Recent movies"],"All movies":["All movies"],"Recent episodes":["Recent episodes"],"All TV shows":["All TV shows"],"Web settings":["Web settings"],"Kodi settings":["Kodi settings"],"Now Playing Playlists":["Now Playing Playlists"],"Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right":["Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right"],"Current playlist":["Current playlist"],"Clear playlist":["Clear playlist"],"Refresh playlist":["Refresh playlist"],"Party mode":["Party mode"],"Save Kodi playlist":["Save Kodi playlist"],"Preferred language, need to refresh browser to take effect":["Preferred language, need to refresh browser to take effect"],"Ignore articles (terms such as 'The' and 'A') when sorting lists":["Ignore articles (terms such as 'The' and 'A') when sorting lists"],"Vibrant headers":["Vibrant headers"],"Use colourful headers for media pages":["Use colourful headers for media pages"],"Enable support for reverse proxying.":["Enable support for reverse proxying."],"songs":["songs"],"artists":["artists"],"albums":["albums"],"movies":["movies"],"Searching for":["Searching for"],"and":["and"],"tvshows":["tvshows"],"no media in this folder":["no media in this folder"],"Browse files and add-ons":["Browse files and add-ons"],"This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.":["This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on."],"Send text to Kodi":["Send text to Kodi"],"The lab":["The lab"],"Chorus lab":["Chorus lab"],"Warning":["Warning"],"Experimental code, use at own risk":["Experimental code, use at own risk"],"Kodi API browser":["Kodi API browser"],"This is a tool to test out the API. Select a method then execute it with parameters.":["This is a tool to test out the API. Select a method then execute it with parameters."],"You could potentially damage your system with this and there are no sanity checks. Use at own risk.":["You could potentially damage your system with this and there are no sanity checks. Use at own risk."],"Saved Kodi settings":["Saved Kodi settings"],"General":["General"],"Advanced setting level is recommended for those who know what they are doing.":["Advanced setting level is recommended for those who know what they are doing."],"Kodi settings level":["Kodi settings level"],"Remove":["Remove"],"cast":["cast"],"Add-ons":["Add-ons"],"Web interface":["Web interface"],"Readme":["Readme"],"Changelog":["Changelog"],"Translations":["Translations"],"Help topics":["Help topics"],"Overview":["Overview"],"Lab":["Lab"],"version":["version"],"Remote control":["Remote control"],"Remote control is set up correctly":["Remote control is set up correctly"],"About":["About"],"Local audio":["Local audio"],"Status report":["Status report"],"in":["in"],"Focus playlist on playing":["Focus playlist on playing"],"Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed":["Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed"],"Web Settings saved.":["Web Settings saved."],"Keyboard controls":["Keyboard controls"],"In Chorus, will you keyboard control Kodi, the browser or both":["In Chorus, will your keyboard control Kodi, the browser or both"],"Learn more":["Learn more"],"Resume playback":["Resume playback"],"Resume from":["Resume from"],"Start from the beginning":["Start from the beginning"],"Click here restore defaults":["Click here restore defaults"],"Main Menu Structure":["Main Menu Structure"],"Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items.":["Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items."],"Main Nav":["Main Nav"],"Add a new playlist":["Add a new playlist"],"Keyboard":["Keyboard"],"Music":["Music"],"Digital radio":["Digital radio"],"Movies":["Movies"],"TV shows":["TV shows"],"TV":["TV"],"Browser":["Browser"],"Thumbs up":["Thumbs up"],"Settings":["Settings"],"Help":["Help"],"Disable Thumbs Up":["Disable Thumbs Up"],"Remove the thumbs up button from media. Note: you may also want to remove the menu item from the %1$s":["Remove the thumbs up button from media. Note: you may also want to remove the menu item from the %1$s"],"You need to 'Allow remote control' for Kodi. You can do that":["You need to 'Allow remote control' for Kodi. You can do that"],"here":["here"],"yes":["yes"],"no":["no"],"close":["close"],"ok":["ok"],"Are you sure?":["Are you sure?"],"Set all episodes for this season as":["Set all episodes for this season as"],"Set all episodes for this TV show as":["Set all episodes for this TV show as"],"watched":["watched"],"unwatched":["unwatched"],"genre":["genre"],"studio":["studio"],"rated":["rated"],"episodes":["episodes"],"total":["total"],"set":["set"],"Show device name":["Show device name"],"Show the Kodi device name in the header of Chorus":["Show the Kodi device name in the header of Chorus"],"No results found":["No results found"],"Have you done a library scan?":["Have you done a library scan?"],"Play in browser":["Play in browser"],"Edit":["Edit"],"Add to Kodi":["Add to Kodi"],"Watched":["Watched"],"New playlist":["New playlist"],"Play in Kodi":["Play in Kodi"],"Export list":["Export list"],"Delete playlist":["Delete playlist"],"title":["title"],"year":["year"],"date added":["date added"],"rating":["rating"],"actor":["actor"],"mood":["mood"],"writer":["writer"],"director":["director"],"style":["style"],"items selected":["items selected"],"item selected":["item selected"],"Video library clean started":["Video library clean started"],"Video library clean finished":["Video library clean finished"],"Audio library clean started":["Audio library clean started"],"Audio library clean finished":["Audio library clean finished"],"This is a tool to test out the api. Select a method then execute it with parameters.":["This is a tool to test out the api. Select a method then execute it with parameters."],"Go to season":["Go to season"],"Queue in Kodi":["Queue in Kodi"],"Adding items to the queue":["Adding items to the queue"],"Live TV":["Live TV"],"Recently added albums":["Recently added albums"],"Random albums":["Random albums"],"Recently played albums":["Recently played albums"],"Random movies":["Random movies"],"Continue watching":["Continue watching"],"More from %1$s":["More from %1$s"],"More %1$s movies":["More %1$s movies"],"More movies staring %1$s":["More movies staring %1$s"],"Other movies released in %1$s":["Other movies released in %1$s"],"artist":["artist"],"random":["random"],"label":["label"],"formed":["formed"],"born":["born"],"died":["died"],"disbanded":["disbanded"],"years active":["years active"],"Click for more":["Click for more"],"Loading albums":["Loading albums"],"%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell...":["%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell..."],"all media":["all media"],"YouTube":["YouTube"],"SoundCloud":["SoundCloud"],"GoogleMusic":["GoogleMusic"],"Radio":["Radio"],"MixCloud":["MixCloud"],"First aired":["First aired"],"Updated %1$s details":["Updated %1$s details"],"Title":["Title"],"Plot":["Plot"],"Rating":["Rating"],"Original title":["Original title"],"Directors":["Directors"],"Writers":["Writers"],"File path":["File path"],"Artist":["Artist"],"Description":["Description"],"Label":["Label"],"Year":["Year"],"Genres":["Genres"],"Styles":["Styles"],"Themes":["Themes"],"Moods":["Moods"],"Album artist":["Album artist"],"Album":["Album"],"Track":["Track"],"Disc":["Disc"],"Tagline":["Tagline"],"Studio":["Studio"],"Content rating":["Content rating"],"Premiered":["Premiered"],"IMDb":["IMDb"],"Sort title":["Sort title"],"Country":["Country"],"Set":["Set"],"Tags":["Tags"],"Trailer":["Trailer"],"Formed":["Formed"],"Disbanded":["Disbanded"],"Years Active":["Years Active"],"Born":["Born"],"Died":["Died"],"Instruments":["Instruments"],"more":["more"],"in progress":["in progress"],"URL":["URL"],"Add an image via an external URL":["Add an image via an external URL"],"Searching for more images":["Searching for more images"],"Image Selector":["Image Selector"],"Image URL":["Image URL"],"External Search":["External Search"],"Local media":["Local media"],"Chorus Search":["Chorus Search"],"YouTube Search":["YouTube Search"],"Executed addon":["Executed addon"],"all":["all"],"video":["video"],"audio":["audio"],"image":["image"],"picture":["picture"],"executable":["executable"],"settings":["settings"],"Refresh":["Refresh"],"Confirm refresh":["Refreshing '%1$s' will remove it from the library then re-add it, so the ID may change. I'll attempt to reload this page with the new ID in a few seconds. Click 'YES' to confirm refresh"],"Refresh Ignore NFO":["Refresh Ignore NFO"],"Ignore local NFO files when manually refreshing media.":["Ignore local NFO files when manually refreshing media."],"Show only":["Show only"],"Show and episodes":["Show and episodes"],"Top music":["Top music"],"%1$s Artists":["%1$s Artists"],"%1$s Albums":["%1$s Albums"],"%1$s Songs":["%1$s Songs"],"default":["default"],"Actions":["Actions"],"play files":["play files"],"queue files":["queue files"],"Sent text":["Sent text"],"License":["License"],"Main Menu":["Main Menu"],"Search":["Search"],"Custom Add-on search":["Custom Add-on search"],"Add custom add-on searches":["Chorus search supports searching not only local media but add-on content too. For example, you can use the search to find videos in YouTube or audio in SoundCloud. This page allows you to add custom add-on searches that are not included out of the box. See the %1$s for more information."],"Add-ons help page":["Add-ons help page"],"No %1$s found":["No %1$s found"],"results":["results"],"EPG data":["EPG data"],"PVR":["PVR"],"Recordings":["Recordings"],"Channel recording toggled":["Channel recording toggled"],"TV Channels":["TV Channels"],"Radio Stations":["Radio Stations"],"Record":["Record"],"Toggle timer":["Toggle timer"],"Now":["Now"],"Rename playlist":["Rename playlist"]}}}
\ No newline at end of file +{"domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural_forms":"nplurals=2; plural=(n != 1);","lang":"en"},"Nothing playing":["Nothing playing"],"Deselect all":["Deselect all"],"Filters":["Filters"],"Sort":["Sort"],"Select a filter":["Select a filter"],"Select an option":["Select an option"],"filter":["filter"],"Add filter":["Add filter"],"Which player to start with":["Which player to start with"],"Ignore terms such as 'The' and 'A' when sorting lists":["Ignore terms such as 'The' and 'A' when sorting lists"],"When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries":["When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries"],"is the default":["is the default"],"The hostname used for websockets connection. Set to 'auto' to use the current hostname.":["The hostname used for websockets connection. Set to 'auto' to use the current hostname."],"How often do I poll for updates from Kodi (Only applies when websockets inactive)":["How often do I poll for updates from Kodi (Only applies when websockets inactive)"],"Enable support for reverse proxy.":["Enable support for reverse proxy."],"Web settings saved.":["Web settings saved."],"Just a sec...":["Just a sec..."],"Unable to communicate with Kodi in a long time. I think it's dead Jim!":["Unable to communicate with Kodi in a long time. I think it's dead Jim!"],"Video library scan started":["Video library scan started"],"Video library scan complete":["Video library scan complete"],"Audio library scan started":["Audio library scan started"],"Audio library scan complete":["Audio library scan complete"],"Kodi has quit":["Kodi has quit"],"Sections":["Sections"],"Back":["Back"],"Loading folder...":["Loading folder..."],"Show more":["Show more"],"to Kodi":["to Kodi"],"Playlist refreshed":["Playlist refreshed"],"Kodi":["Kodi"],"Local":["Local"],"Playlists":["Playlists"],"Existing playlists":["Existing playlists"],"Empty playlist, you should probably add something to it?":["Empty playlist, you should probably add something to it?"],"Create a new list":["Create a new list"],"Add to playlist":["Add to playlist"],"Added to your playlist":["Added to your playlist"],"Give your playlist a name":["Give your playlist a name"],"Recently added":["Recently added"],"Recently played":["Recently played"],"Season":["Season"],"Episode":["Episode"],"Play":["Play"],"Queue":["Queue"],"View on IMDb":["View on IMDb"],"Stream":["Stream"],"Download":["Download"],"complete":["complete"],"Synopsis":["Synopsis"],"Full cast":["Full cast"],"Websockets closed":["Websockets closed"],"Websockets host":["Websockets host"],"Websockets port":["Websockets port"],"Default player":["Default player"],"Ignore article":["Ignore article"],"Album artists only":["Album artists only"],"Poll interval":["Poll interval"],"Reverse proxy support":["Reverse proxy support"],"Language":["Language"],"Preferred language":["Preferred language"],"Ignore articles (terms such as \"The\" and \"A\") when sorting lists":["Ignore articles (terms such as \"The\" and \"A\") when sorting lists"],"sec":["sec"],"Your browser doesn't support websockets! Get with the times and update your browser.":["Your browser doesn't support websockets! Get with the times and update your browser."],"Failed to connect to websockets":["Failed to connect to websockets, so I am falling back to polling for updates. Which makes things slower and uses more resources. Please ensure you have 'Allow programs on other systems to control Kodi' ENABLED in the Kodi settings (System > Services > Remote control). You may also get this if you are using proxies or accessing via an IP address when localhost will suffice. If websockets normally works, you might just need to refresh your browser."],"Video":["Video"],"Audio":["Audio"],"Cast":["Cast"],"Director":["Director","Directors"],"Writer":["Writer","Writers"],"Subtitle":["Subtitle","Subtitles"],"Result":["Result","Results"],"Loading things...":["Loading things..."],"Scan video library":["Scan video library"],"Scan audio library":["Scan audio library"],"About Chorus":["About Chorus"],"Recent":["Recent"],"Artists":["Artists"],"Albums":["Albums"],"Recent movies":["Recent movies"],"All movies":["All movies"],"Recent episodes":["Recent episodes"],"All TV shows":["All TV shows"],"Web settings":["Web settings"],"Kodi settings":["Kodi settings"],"Now Playing Playlists":["Now Playing Playlists"],"Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right":["Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right"],"Current playlist":["Current playlist"],"Clear playlist":["Clear playlist"],"Refresh playlist":["Refresh playlist"],"Party mode":["Party mode"],"Save Kodi playlist":["Save Kodi playlist"],"Preferred language, need to refresh browser to take effect":["Preferred language, need to refresh browser to take effect"],"Ignore articles (terms such as 'The' and 'A') when sorting lists":["Ignore articles (terms such as 'The' and 'A') when sorting lists"],"Vibrant headers":["Vibrant headers"],"Use colourful headers for media pages":["Use colourful headers for media pages"],"Enable support for reverse proxying.":["Enable support for reverse proxying."],"songs":["songs"],"artists":["artists"],"albums":["albums"],"movies":["movies"],"Searching for":["Searching for"],"and":["and"],"tvshows":["tvshows"],"no media in this folder":["no media in this folder"],"Browse files and add-ons":["Browse files and add-ons"],"This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.":["This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on."],"Send text to Kodi":["Send text to Kodi"],"The lab":["The lab"],"Chorus lab":["Chorus lab"],"Warning":["Warning"],"Experimental code, use at own risk":["Experimental code, use at own risk"],"Kodi API browser":["Kodi API browser"],"This is a tool to test out the API. Select a method then execute it with parameters.":["This is a tool to test out the API. Select a method then execute it with parameters."],"You could potentially damage your system with this and there are no sanity checks. Use at own risk.":["You could potentially damage your system with this and there are no sanity checks. Use at own risk."],"Saved Kodi settings":["Saved Kodi settings"],"General":["General"],"Advanced setting level is recommended for those who know what they are doing.":["Advanced setting level is recommended for those who know what they are doing."],"Kodi settings level":["Kodi settings level"],"Remove":["Remove"],"cast":["cast"],"Add-ons":["Add-ons"],"Web interface":["Web interface"],"Readme":["Readme"],"Changelog":["Changelog"],"Translations":["Translations"],"Help topics":["Help topics"],"Overview":["Overview"],"Lab":["Lab"],"version":["version"],"Remote control":["Remote control"],"Remote control is set up correctly":["Remote control is set up correctly"],"About":["About"],"Local audio":["Local audio"],"Status report":["Status report"],"in":["in"],"Focus playlist on playing":["Focus playlist on playing"],"Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed":["Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed"],"Web Settings saved.":["Web Settings saved."],"Keyboard controls":["Keyboard controls"],"In Chorus, will you keyboard control Kodi, the browser or both":["In Chorus, will your keyboard control Kodi, the browser or both"],"Learn more":["Learn more"],"Resume playback":["Resume playback"],"Resume from":["Resume from"],"Start from the beginning":["Start from the beginning"],"Click here restore defaults":["Click here restore defaults"],"Main Menu Structure":["Main Menu Structure"],"Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items.":["Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items."],"Main Nav":["Main Nav"],"Add a new playlist":["Add a new playlist"],"Keyboard":["Keyboard"],"Music":["Music"],"Digital radio":["Digital radio"],"Movies":["Movies"],"TV shows":["TV shows"],"TV":["TV"],"Browser":["Browser"],"Thumbs up":["Thumbs up"],"Settings":["Settings"],"Help":["Help"],"Disable Thumbs Up":["Disable Thumbs Up"],"Remove the thumbs up button from media. Note: you may also want to remove the menu item from the %1$s":["Remove the thumbs up button from media. Note: you may also want to remove the menu item from the %1$s"],"You need to 'Allow remote control' for Kodi. You can do that":["You need to 'Allow remote control' for Kodi. You can do that"],"here":["here"],"yes":["yes"],"no":["no"],"close":["close"],"ok":["ok"],"Are you sure?":["Are you sure?"],"Set all episodes for this season as":["Set all episodes for this season as"],"Set all episodes for this TV show as":["Set all episodes for this TV show as"],"watched":["watched"],"unwatched":["unwatched"],"genre":["genre"],"studio":["studio"],"rated":["rated"],"episodes":["episodes"],"total":["total"],"set":["set"],"Show device name":["Show device name"],"Show the Kodi device name in the header of Chorus":["Show the Kodi device name in the header of Chorus"],"No results found":["No results found"],"Have you done a library scan?":["Have you done a library scan?"],"Play in browser":["Play in browser"],"Edit":["Edit"],"Add to Kodi":["Add to Kodi"],"Watched":["Watched"],"New playlist":["New playlist"],"Play in Kodi":["Play in Kodi"],"Export list":["Export list"],"Delete playlist":["Delete playlist"],"title":["title"],"year":["year"],"date added":["date added"],"rating":["rating"],"actor":["actor"],"mood":["mood"],"writer":["writer"],"director":["director"],"style":["style"],"items selected":["items selected"],"item selected":["item selected"],"Video library clean started":["Video library clean started"],"Video library clean finished":["Video library clean finished"],"Audio library clean started":["Audio library clean started"],"Audio library clean finished":["Audio library clean finished"],"This is a tool to test out the api. Select a method then execute it with parameters.":["This is a tool to test out the api. Select a method then execute it with parameters."],"Go to season":["Go to season"],"Queue in Kodi":["Queue in Kodi"],"Adding items to the queue":["Adding items to the queue"],"Live TV":["Live TV"],"Recently added albums":["Recently added albums"],"Random albums":["Random albums"],"Recently played albums":["Recently played albums"],"Random movies":["Random movies"],"Continue watching":["Continue watching"],"More from %1$s":["More from %1$s"],"More %1$s movies":["More %1$s movies"],"More movies staring %1$s":["More movies staring %1$s"],"Other movies released in %1$s":["Other movies released in %1$s"],"artist":["artist"],"random":["random"],"label":["label"],"formed":["formed"],"born":["born"],"died":["died"],"disbanded":["disbanded"],"years active":["years active"],"Click for more":["Click for more"],"Loading albums":["Loading albums"],"%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell...":["%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell..."],"all media":["all media"],"YouTube":["YouTube"],"SoundCloud":["SoundCloud"],"GoogleMusic":["GoogleMusic"],"Radio":["Radio"],"MixCloud":["MixCloud"],"First aired":["First aired"],"Updated %1$s details":["Updated %1$s details"],"Title":["Title"],"Plot":["Plot"],"Rating":["Rating"],"Original title":["Original title"],"Directors":["Directors"],"Writers":["Writers"],"File path":["File path"],"Artist":["Artist"],"Description":["Description"],"Label":["Label"],"Year":["Year"],"Genres":["Genres"],"Styles":["Styles"],"Themes":["Themes"],"Moods":["Moods"],"Album artist":["Album artist"],"Album":["Album"],"Track":["Track"],"Disc":["Disc"],"Tagline":["Tagline"],"Studio":["Studio"],"Content rating":["Content rating"],"Premiered":["Premiered"],"IMDb":["IMDb"],"Sort title":["Sort title"],"Country":["Country"],"Set":["Set"],"Tags":["Tags"],"Trailer":["Trailer"],"Formed":["Formed"],"Disbanded":["Disbanded"],"Years Active":["Years Active"],"Born":["Born"],"Died":["Died"],"Instruments":["Instruments"],"more":["more"],"in progress":["in progress"],"URL":["URL"],"Add an image via an external URL":["Add an image via an external URL"],"Searching for more images":["Searching for more images"],"Selector":["Selector"],"External Search":["External Search"],"Local media":["Local media"],"Chorus Search":["Chorus Search"],"YouTube Search":["YouTube Search"],"Executed addon":["Executed addon"],"all":["all"],"video":["video"],"audio":["audio"],"image":["image"],"picture":["picture"],"executable":["executable"],"settings":["settings"],"Refresh":["Refresh"],"Confirm refresh":["Refreshing '%1$s' will remove it from the library then re-add it, so the ID may change. I'll attempt to reload this page with the new ID in a few seconds. Click 'YES' to confirm refresh"],"Refresh Ignore NFO":["Refresh Ignore NFO"],"Ignore local NFO files when manually refreshing media.":["Ignore local NFO files when manually refreshing media."],"Show only":["Show only"],"Show and episodes":["Show and episodes"],"Top music":["Top music"],"%1$s Artists":["%1$s Artists"],"%1$s Albums":["%1$s Albums"],"%1$s Songs":["%1$s Songs"],"default":["default"],"Actions":["Actions"],"play files":["play files"],"queue files":["queue files"],"Sent text":["Sent text"],"License":["License"],"Main Menu":["Main Menu"],"Search":["Search"],"Custom Add-on search":["Custom Add-on search"],"Add custom add-on searches":["Chorus search supports searching not only local media but add-on content too. For example, you can use the search to find videos in YouTube or audio in SoundCloud. This page allows you to add custom add-on searches that are not included out of the box. See the %1$s for more information."],"Add-ons help page":["Add-ons help page"],"No %1$s found":["No %1$s found"],"results":["results"],"EPG data":["EPG data"],"PVR":["PVR"],"Recordings":["Recordings"],"Channel recording toggled":["Channel recording toggled"],"TV Channels":["TV Channels"],"Radio Stations":["Radio Stations"],"Record":["Record"],"Toggle timer":["Toggle timer"],"Now":["Now"],"Rename playlist":["Rename playlist"],"album":["album"],"Videos":["Videos"],"Lost connection to Kodi":["Lost connection to Kodi"],"Attempt to reconnect":["Attempt to reconnect"],"Attempting reconnect":["Attempting reconnect"],"Top Songs":["Top Songs"],"Top Albums":["Top Albums"],"Toggle select all":["Toggle select all"],"More like this":["More like this"],"music videos":["music videos"],"Related music videos from YouTube":["Related music videos from YouTube"],"Lost websocket connection":["Lost websocket connection"],"Attempting websockets reconnect":["Attempting websockets reconnect"],"This should be the play path for the trailer. Eg. %1$s":["This should be the play path for the trailer. Eg. %1$s"]}}}
\ No newline at end of file diff --git a/addons/webinterface.default/lang/_strings/pl.json b/addons/webinterface.default/lang/_strings/pl.json index f6d40ca5b2..5919a9290a 100644 --- a/addons/webinterface.default/lang/_strings/pl.json +++ b/addons/webinterface.default/lang/_strings/pl.json @@ -1 +1 @@ -{"domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural_forms":"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);","lang":"pl_PL"},"Nothing playing":["Odtwarzanie nieaktywne"],"Deselect all":["Odznacz wszystkie"],"Filters":["Filtry"],"Sort":["Sortowanie"],"Select a filter":["Wybierz filtr"],"Select an option":["Wybierz opcję"],"filter":["filtr"],"Add filter":["Dodaj filtr"],"Which player to start with":["Określa domyślnie używany odtwarzacz mediów"],"Ignore terms such as 'The' and 'A' when sorting lists":["Ignoruj wyrażenia takie, jak 'The' i 'A' podczas sortowania list"],"When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries":["W trakcie przeglądania listy wykonawców, widoczni będą tylko wykonawcy z własnymi albumami lub wszyscy odnalezieni wykonawcy. Ostrzeżenie: dezaktywowanie tej funkcji może mieć negatywny wpływ na wydajność w przypadku dużych bibliotek."],"is the default":["jest domyślny"],"The hostname used for websockets connection. Set to 'auto' to use the current hostname.":["Nazwa serwera używanego do połączenia WebSocket. Ustaw na 'auto', aby używać nazwy lokalnego komputera."],"How often do I poll for updates from Kodi (Only applies when websockets inactive)":["Określa częstotliwość aktualizacji zawartości z Kodi (używane tylko w przypadku nieaktywnego połączenia WebSocket)"],"Enable support for reverse proxy.":["Umożliwia aktywację obsługi reverse proxy."],"Web settings saved.":["Zapisano ustawienia interfejsu webowego."],"Just a sec...":["Proszę czekać..."],"Unable to communicate with Kodi in a long time. I think it's dead Jim!":["Komunikacja z Kodi była niemożliwa przez dłuższy czas. Prawdopodobnie program się zawiesił!"],"Video library scan started":["Rozpoczęto skanowanie biblioteki wideo"],"Video library scan complete":["Zakończono skanowanie biblioteki wideo"],"Audio library scan started":["Rozpoczęto skanowanie biblioteki muzyki"],"Audio library scan complete":["Zakończono skanowanie biblioteki muzyki"],"Kodi has quit":["Proces Kodi został zamknięty"],"Sections":["Sekcje"],"Back":["Powrót"],"Loading folder...":["Wczytywanie folderu..."],"Show more":["Pokaż więcej"],"to Kodi":["do Kodi"],"Playlist refreshed":["Lista odtwarzania została odświeżona"],"Kodi":["Kodi"],"Local":["Przeglądarka"],"Playlists":["Listy odtwarzania"],"Existing playlists":["Istniejące listy odtwarzania"],"Empty playlist, you should probably add something to it?":["Lista odtwarzania jest pusta, powinieneś coś do niej dodać."],"Create a new list":["Utwórz nową listę"],"Add to playlist":["Dodaj do listy"],"Added to your playlist":["Dodano do listy odtwarzania"],"Give your playlist a name":["Nadaj nazwę swojej liście"],"Recently added":["Ostatnio dodane"],"Recently played":["Ostatnio odtwarzane"],"Season":["Sezon"],"Episode":["Odcinek"],"Play":["Odtwarzaj"],"Queue":["Dodaj do kolejki"],"View on IMDb":["Zobacz na IMDb"],"Stream":["Transmituj"],"Download":["Pobierz"],"complete":["zakończone"],"Synopsis":["Streszczenie"],"Full cast":["Pełna obsada"],"Websockets closed":["Połączenie WebSocket zostało zamknięte"],"Websockets host":["Serwer WebSocket"],"Websockets port":["Port WebSocket"],"Default player":["Odtwarzacz domyślny"],"Ignore article":["Ignoruj przedimki"],"Album artists only":["Tylko wykonawcy albumów"],"Poll interval":["Częstotliwość odświeżania zawartości"],"Reverse proxy support":["Obsługa reverse proxy"],"Language":["Język"],"Preferred language":["Język preferowany"],"Ignore articles (terms such as \"The\" and \"A\") when sorting lists":["Ignoruj przedimki (wyrażenia takie, jak \"The\" i \"A\") podczas sortowania list"],"sec":["sek."],"Your browser doesn't support websockets! Get with the times and update your browser.":["Twoja przeglądarka nie obsługuje połączeń WebSocket! Idź z duchem czasu i zaktualizuj swoją przeglądarkę."],"Failed to connect to websockets":["Nieudane połączenie WebSocket, awaryjna aktywacja połączenia bezstanowego z cykliczną aktualizacją zawartości. Połączenie tego typu jest wolniejsze i używa więcej zasobów. Upewnij się, że aktywowałeś opcję 'Zezwalaj zdalnym programom na sterowanie aplikacją' w ustawieniach Kodi (System -> Usługi -> Sterowanie). Innym powodem tego problemu może być korzystanie z serwera proxy lub dostęp za pośrednictwem adresu IP, gdy możliwy jest dostęp przy pomocy nazwy localhost. W przypadku poprawnego działania połączenia WebSocket, wystarczy odświeżyć zawartość przeglądarki."],"Video":["Wideo"],"Audio":["Dźwięk"],"Cast":["Obsada"],"Director":["Reżyser","Reżyserzy","Reżyserzy"],"Writer":["Scenarzysta","Scenarzyści","Scenarzyści"],"Subtitle":["Napisy","Napisy","Napisy"],"Result":["Wynik","Wyniki","Wyników"],"Loading things...":["Wczytywanie zawartości..."],"Scan video library":["Skanowanie biblioteki wideo"],"Scan audio library":["Skanowanie biblioteki muzyki"],"About Chorus":["O Chorusie"],"Recent":["Ostatnio"],"Artists":["Wykonawcy"],"Albums":["Albumy"],"Recent movies":["Najnowsze filmy"],"All movies":["Wszystkie filmy"],"Recent episodes":["Najnowsze odcinki"],"All TV shows":["Wszystkie seriale"],"Web settings":["Ustawienia webowe"],"Kodi settings":["Ustawienia Kodi"],"Now Playing Playlists":["Listy Teraz odtwarzane"],"Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right":["Umożliwia wybór odtwarzacza mediów, pomiędzy Kodi a przeglądarką, przy pomocy zakładek. Możesz zmienić widoczność zakładek przy pomocy strzałki w prawym górnym rogu."],"Current playlist":["Aktualna lista odtwarzania"],"Clear playlist":["Wyczyść listę"],"Refresh playlist":["Odśwież listę"],"Party mode":["Tryb Imprezy"],"Save Kodi playlist":["Zapisz listę odtwarzania Kodi"],"Preferred language, need to refresh browser to take effect":["Zmiana języka preferowanego wymaga odświeżenia zawartości przeglądarki"],"Ignore articles (terms such as 'The' and 'A') when sorting lists":["Ignoruj przedminki (wyrażenia takie, jak: 'The' i 'A') podczas sortowania list"],"Vibrant headers":["Dynamiczne nagłówki"],"Use colourful headers for media pages":["Umożliwia używanie osobnego koloru nagłówka dla każdego typu mediów"],"Enable support for reverse proxying.":["Umożliwia aktywację obsługi reverse proxy."],"songs":["utwory"],"artists":["wykonawcy"],"albums":["albumy"],"movies":["filmy"],"Searching for":["Wyszukiwanie"],"and":["i"],"tvshows":["seriale"],"no media in this folder":["Brak mediów w folderze"],"Browse files and add-ons":["Przeglądaj pliki i dodatki"],"This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.":["Miejsce, w którym możesz przeglądać całą zawartość Kodi, nie tylko to co znajduje się w bibliotece. Przeglądanie w podziale na źródła i dodatki."],"Send text to Kodi":["Wyślij tekst do Kodi"],"The lab":["Laboratorium"],"Chorus lab":["Laboratorium Chorusa"],"Warning":["Ostrzeżenie"],"Experimental code, use at own risk":["Funkcje eksperymentalne, używasz ich na własną odpowiedzialność."],"Kodi API browser":["Przeglądarka API Kodi"],"This is a tool to test out the API. Select a method then execute it with parameters.":["Narzędzie do testowania interfejsu programistycznego Kodi. Wybierz metodę, a następnie wykonaj ją z zadanymi parametrami"],"You could potentially damage your system with this and there are no sanity checks. Use at own risk.":["Istnieje potencjalna szansa na uszkodzenie Twojego systemu, ponieważ nie ma żadnej kontroli poprawności. Używasz na własną odpowiedzialność."],"Saved Kodi settings":["Zapisano zmiany ustawień Kodi"],"General":["Ogólne"],"Advanced setting level is recommended for those who know what they are doing.":["Poziom Zaawansowany jest rekomendowany tylko dla tych, którzy wiedzą co robią."],"Kodi settings level":["Poziom ustawień Kodi"],"Remove":["Usuń"],"cast":["obsada"],"Add-ons":["Dodatki"],"Web interface":["Interfejs webowy"],"Readme":["Dokumentacja"],"Changelog":["Dziennik zmian"],"Translations":["Tłumaczenia"],"Help topics":["Tematy pomocy"],"Overview":["Przegląd"],"Lab":["Laboratorium"],"version":["wersja"],"Remote control":["Sterowanie"],"Remote control is set up correctly":["Zdalne sterowanie zostało poprawnie skonfigurowane"],"About":["O Chorusie"],"Local audio":["Dźwięk"],"Status report":["Raport o stanie"],"in":["w"],"Focus playlist on playing":["Zaznaczaj odtwarzaną pozycję na liście"],"Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed":["Umożliwia automatyczne przewijanie listy do aktualnie odtwarzanej pozycji. Ta operacja jest wykonywana za każdym razem, gdy zmienia się odtwarzana pozycja."],"Web Settings saved.":["Zapisano ustawienia interfejsu webowego."],"Keyboard controls":["Sterowanie klawiaturą"],"In Chorus, will you keyboard control Kodi, the browser or both":["Umożliwia sterowanie przy pomocy klawiatury działaniem Kodi, przeglądarki lub oboma jednocześnie"],"Learn more":["Dowiedz się więcej"],"Resume playback":["Wznów odtwarzanie"],"Resume from":["Wznów od"],"Start from the beginning":["Zacznij od początku"],"Click here restore defaults":["Naciśnij, aby przywrócić domyślne ustawienia"],"Main Menu Structure":["Struktura menu"],"Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items.":["Umożliwia zmianę tytułu, adresu URL i %1$s pozycji menu. Możesz także usunąć pozycje, zmienić ich kolejność lub dodać nowe pozycje."],"Main Nav":["Nawigacja"],"Add a new playlist":["Dodaj nową listę"],"Keyboard":["Klawiatura"],"Music":["Muzyka"],"Digital radio":["Radio"],"Movies":["Filmy"],"TV shows":["Seriale"],"TV":["Telewizja"],"Browser":["Przeglądarka"],"Thumbs up":["Lubię to!"],"Settings":["Ustawienia"],"Help":["Pomoc"],"Disable Thumbs Up":["Dezaktywuj funkcję 'Lubię to!'"],"Remove the thumbs up button from media. Note: you may also want to remove the menu item from the ":["Umożliwia usunięcie przycisku 'Lubię to' z panelu informacji o mediach. Uwaga: Możesz także usunąć pozycję menu z "],"You need to 'Allow remote control' for Kodi. You can do that":["Wymagana aktywacja opcji 'Zezwalaj na zdalne sterowanie Kodi przez HTTP'. Możesz to zrobić"],"here":["tutaj"],"yes":["tak"],"no":["nie"],"close":["zamknij"],"ok":["ok"],"Are you sure?":["Jesteś pewien?"],"Set all episodes for this season as":["Ustaw wszystkie odcinki tego sezonu jako"],"Set all episodes for this TV show as":["Ustaw wszystkie odcinki tego serialu jako"],"watched":["obejrzane"],"unwatched":["nieobejrzane"],"genre":["gatunek"],"studio":["wytwórnia"],"rated":["kategoria"],"episodes":["odcinki"],"total":["razem"],"set":["ustaw"],"Show device name":["Pokazuj nazwę urządzenia"],"Show the Kodi device name in the header of Chorus":["Umożliwia wyświetlanie nazwy urządzenia, na którym uruchomiono Kodi, w nagłówku strony Chorusa."],"No results found":["Brak wyników wyszukiwania"],"Have you done a library scan?":["Czy wykonałeś skanowanie biblioteki?"],"Play in browser":["Odtwarzaj w przeglądarce"],"Edit":["Edytuj"],"Add to Kodi":["Dodaj do Kodi"],"Watched":["Obejrzane"],"New playlist":["Nowa lista"],"Play in Kodi":["Odtwarzaj w Kodi"],"Export list":["Eksportuj listę"],"Delete playlist":["Usuń listę"],"title":["tytuł"],"year":["rok"],"date added":["data dodania"],"rating":["ocena"],"actor":["aktor"],"mood":["nastrój"],"writer":["scenarzysta"],"director":["reżyser"],"style":["styl"],"items selected":["pozycje zaznaczone"],"item selected":["pozycja zaznaczona"],"Video library clean started":["Rozpoczęto czyszczenie biblioteki wideo"],"Video library clean finished":["Zakończono czyszczenie biblioteki wideo"],"Audio library clean started":["Rozpoczęto czyszczenie biblioteki muzyki"],"Audio library clean finished":["Zakończono czyszczenie biblioteki muzyki"],"This is a tool to test out the api. Select a method then execute it with parameters.":["To jest narzędzie do testowania interfejsu programistycznego Kodi. Wybierz metodę, a następnie wykonaj ją z zadanymi parametrami"],"Go to season":["Przejdź do sezonu"],"Queue in Kodi":["Dodaj do kolejki Kodi"],"Adding items to the queue":["Dodawanie pozycji do kolejki"],"Live TV":["Telewizja"],"Recently added albums":["Albumy ostatnio dodane"],"Random albums":["Albumy losowe"],"Recently played albums":["Albumy ostatnio odtwarzane"],"Random movies":["Filmy losowe"],"Continue watching":["Kontynuuj odtwarzanie"],"More from %1$s":["Więcej z %1$s"],"More %1$s movies":["Więcej filmów z %1$s"],"More movies staring %1$s":["Więcej filmów z aktorem %1$s"],"Other movies released in %1$s":["Inne premiery filmów w %1$s"],"artist":["wykonawca"],"random":["losowo"],"label":["wytwórnia"],"formed":["założone"],"born":["urodzony"],"died":["zmarły"],"disbanded":["rozwiązany"],"years active":["lata aktywności"],"Click for more":["Naciśnij po więcej informacji"],"Loading albums":["Wczytywanie albumów"],"%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell...":["%1$d sekund temu okno dialogowe zostało otworzone i ciągle jest otwarte! Aby zapobiec implozji systemu, powinieneś wprowadzić jakiś tekst. Obecnie nie dbamy co to powinno być, więc dlaczego nie być kreatywnym? Czy posiadasz %2$s? Nie powiem..."],"all media":["wszystkie media"],"YouTube":["YouTube"],"SoundCloud":["SoundCloud"],"GoogleMusic":["GoogleMusic"],"Radio":["Radio"],"MixCloud":["MixCloud"],"First aired":["Premiera"],"Updated %1$s details":["Zaktualizowano informacje o %1$s"],"Title":["Tytuł"],"Plot":["Fabuła"],"Rating":["Ocena"],"Original title":["Tytuł oryginalny"],"Directors":["Reżyseria"],"Writers":["Scenariusz"],"File path":["Ścieżka pliku"],"Artist":["Wykonawca"],"Description":["Opis"],"Label":["Wytwórnia"],"Year":["Rok"],"Genres":["Gatunki"],"Styles":["Style"],"Themes":["Motywy"],"Moods":["Nastroje"],"Album artist":["Wykonawca albumu"],"Album":["Album"],"Track":["Utwór"],"Disc":["Dysk"],"Tagline":["Motto"],"Studio":["Wytwórnia"],"Content rating":["Kategoria wiekowa"],"Premiered":["Premiera"],"IMDb":["IMDb"],"Sort title":["Tytuł sortowania"],"Country":["Kraj"],"Set":["Seria"],"Tags":["Znaczniki"],"Trailer":["Zwiastun"],"Formed":["Założony"],"Disbanded":["Rozwiązany"],"Years Active":["Lata aktywności"],"Born":["Urodzony"],"Died":["Zmarły"],"Instruments":["Instrumenty"],"more":["więcej"],"in progress":["W trakcie"],"URL":["Adres URL"],"Add an image via an external URL":["Dodaj obraz za pomocą adresu URL"],"Searching for more images":["Wyszukiwanie dodatkowych obrazów"],"Image Selector":["Wybór obrazu"],"Image URL":["Adres URL obrazu"],"External Search":["Wyszukiwanie w internecie"],"Local media":["Media lokalne"],"Chorus Search":["Wyszukiwanie w Chorusie"],"YouTube Search":["Wyszukiwanie w YouTube"],"Executed addon":["Uruchomiony dodatek"],"all":["wszystkie"],"video":["wideo"],"audio":["muzyka"],"image":["obraz"],"picture":["zdjęcie"],"executable":["program"],"settings":["ustawienia"],"Refresh":["Odśwież"],"Confirm refresh":["Odświeżenie informacji o pozycji '%1$s' spowoduje usunięcie jej z biblioteki, a następnie ponowne jej dodanie, co może zmienić jej identyfikator. Za kilka sekund nastąpi próba przeładowania strony z nowym identyfikatorem. Naciśnij 'TAK', aby potwierdzić odświeżenie"],"Refresh Ignore NFO":["Odświeżaj ignorując pliki NFO"],"Ignore local NFO files when manually refreshing media.":["Umożliwia ignorowanie lokalnych plików NFO podczas manualnego odświeżania informacji o mediach."],"Show only":["Tylko seriale"],"Show and episodes":["Seriale i odcinki"],"Top music":["Najlepsza muzyka"],"%1$s Artists":["%1$s Wykonawcy"],"%1$s Albums":["%1$s Albumy"],"%1$s Songs":["%1$s Utwory"],"default":["domyślne"],"Actions":["Akcje"],"play files":["odtwarzaj pliki"],"queue files":["dodaj pliki do kolejki"],"Sent text":["Wyślij tekst"],"License":["Licencja"],"Main Menu":["Menu startowe"],"Search":["Szukaj"],"Custom Add-on search":["Wyszukiwanie zawartości dodatku"],"Add custom add-on searches":["Mechanizm wyszukiwania Chorusa obsługuje nie tylko lokalne media, ale także zawartość dodatków. Dla przykładu, możesz użyć wyszukiwania, aby znaleźć wideo w YouTube lub muzykę w usłudze SoundCloud. Ta strona umożliwia dodanie niestandardowego wyszukiwania w zawartości dodatku, które domyślnie nie jest dostępne. Zobacz %1$s, aby dowiedzieć się więcej."],"Add-ons help page":["Strona pomocy dodatków"]}}}
\ No newline at end of file +{"domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural_forms":"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);","lang":"pl_PL"},"Nothing playing":["Odtwarzanie nieaktywne"],"Deselect all":["Odznacz wszystkie"],"Filters":["Filtry"],"Sort":["Sortowanie"],"Select a filter":["Wybierz filtr"],"Select an option":["Wybierz opcję"],"filter":["filtr"],"Add filter":["Dodaj filtr"],"Which player to start with":["Określa domyślnie używany odtwarzacz mediów"],"Ignore terms such as 'The' and 'A' when sorting lists":["Ignoruj wyrażenia takie, jak 'The' i 'A' podczas sortowania list"],"When listing artists should we only see artists with albums or all artists found. Warning: turning this off can impact performance with large libraries":["W trakcie przeglądania listy wykonawców, widoczni będą tylko wykonawcy z własnymi albumami lub wszyscy odnalezieni wykonawcy. Ostrzeżenie: dezaktywowanie tej funkcji może mieć negatywny wpływ na wydajność w przypadku dużych bibliotek."],"is the default":["jest domyślny"],"The hostname used for websockets connection. Set to 'auto' to use the current hostname.":["Nazwa serwera używanego do połączenia WebSocket. Ustaw na 'auto', aby używać nazwy lokalnego komputera."],"How often do I poll for updates from Kodi (Only applies when websockets inactive)":["Określa częstotliwość aktualizacji zawartości z Kodi (używane tylko w przypadku nieaktywnego połączenia WebSocket)"],"Enable support for reverse proxy.":["Umożliwia aktywację obsługi reverse proxy."],"Web settings saved.":["Zapisano ustawienia interfejsu webowego."],"Just a sec...":["Proszę czekać..."],"Unable to communicate with Kodi in a long time. I think it's dead Jim!":["Komunikacja z Kodi była niemożliwa przez dłuższy czas. Prawdopodobnie program się zawiesił!"],"Video library scan started":["Rozpoczęto skanowanie biblioteki wideo"],"Video library scan complete":["Zakończono skanowanie biblioteki wideo"],"Audio library scan started":["Rozpoczęto skanowanie biblioteki muzyki"],"Audio library scan complete":["Zakończono skanowanie biblioteki muzyki"],"Kodi has quit":["Proces Kodi został zamknięty"],"Sections":["Sekcje"],"Back":["Powrót"],"Loading folder...":["Wczytywanie folderu..."],"Show more":["Pokaż więcej"],"to Kodi":["do Kodi"],"Playlist refreshed":["Lista odtwarzania została odświeżona"],"Kodi":["Kodi"],"Local":["Przeglądarka"],"Playlists":["Listy odtwarzania"],"Existing playlists":["Istniejące listy odtwarzania"],"Empty playlist, you should probably add something to it?":["Lista odtwarzania jest pusta, powinieneś coś do niej dodać."],"Create a new list":["Utwórz nową listę"],"Add to playlist":["Dodaj do listy"],"Added to your playlist":["Dodano do listy odtwarzania"],"Give your playlist a name":["Nadaj nazwę swojej liście"],"Recently added":["Ostatnio dodane"],"Recently played":["Ostatnio odtwarzane"],"Season":["Sezon"],"Episode":["Odcinek"],"Play":["Odtwarzaj"],"Queue":["Dodaj do kolejki"],"View on IMDb":["Zobacz na IMDb"],"Stream":["Transmituj"],"Download":["Pobierz"],"complete":["zakończone"],"Synopsis":["Streszczenie"],"Full cast":["Pełna obsada"],"Websockets closed":["Połączenie WebSocket zostało zamknięte"],"Websockets host":["Serwer WebSocket"],"Websockets port":["Port WebSocket"],"Default player":["Odtwarzacz domyślny"],"Ignore article":["Ignoruj przedimki"],"Album artists only":["Tylko wykonawcy albumów"],"Poll interval":["Częstotliwość odświeżania zawartości"],"Reverse proxy support":["Obsługa reverse proxy"],"Language":["Język"],"Preferred language":["Język preferowany"],"Ignore articles (terms such as \"The\" and \"A\") when sorting lists":["Ignoruj przedimki (wyrażenia takie, jak \"The\" i \"A\") podczas sortowania list"],"sec":["sek."],"Your browser doesn't support websockets! Get with the times and update your browser.":["Twoja przeglądarka nie obsługuje połączeń WebSocket! Idź z duchem czasu i zaktualizuj swoją przeglądarkę."],"Failed to connect to websockets":["Nieudane połączenie WebSocket, awaryjna aktywacja połączenia bezstanowego z cykliczną aktualizacją zawartości. Połączenie tego typu jest wolniejsze i używa więcej zasobów. Upewnij się, że aktywowałeś opcję 'Zezwalaj zdalnym programom na sterowanie aplikacją' w ustawieniach Kodi (System -> Usługi -> Sterowanie). Innym powodem tego problemu może być korzystanie z serwera proxy lub dostęp za pośrednictwem adresu IP, gdy możliwy jest dostęp przy pomocy nazwy localhost. W przypadku poprawnego działania połączenia WebSocket, wystarczy odświeżyć zawartość przeglądarki."],"Video":["Wideo"],"Audio":["Dźwięk"],"Cast":["Obsada"],"Director":["Reżyser","Reżyserzy","Reżyserzy"],"Writer":["Scenarzysta","Scenarzyści","Scenarzyści"],"Subtitle":["Napisy","Napisy","Napisy"],"Result":["Wynik","Wyniki","Wyników"],"Loading things...":["Wczytywanie zawartości..."],"Scan video library":["Skanowanie biblioteki wideo"],"Scan audio library":["Skanowanie biblioteki muzyki"],"About Chorus":["O Chorusie"],"Recent":["Ostatnio"],"Artists":["Wykonawcy"],"Albums":["Albumy"],"Recent movies":["Najnowsze filmy"],"All movies":["Wszystkie filmy"],"Recent episodes":["Najnowsze odcinki"],"All TV shows":["Wszystkie seriale"],"Web settings":["Ustawienia webowe"],"Kodi settings":["Ustawienia Kodi"],"Now Playing Playlists":["Listy Teraz odtwarzane"],"Switch between Kodi and local playback via the tabs. You can toggle visibility with the arrow in the top right":["Umożliwia wybór odtwarzacza mediów, pomiędzy Kodi a przeglądarką, przy pomocy zakładek. Możesz zmienić widoczność zakładek przy pomocy strzałki w prawym górnym rogu."],"Current playlist":["Aktualna lista odtwarzania"],"Clear playlist":["Wyczyść listę"],"Refresh playlist":["Odśwież listę"],"Party mode":["Tryb Imprezy"],"Save Kodi playlist":["Zapisz listę w Kodi"],"Preferred language, need to refresh browser to take effect":["Zmiana języka preferowanego wymaga odświeżenia zawartości przeglądarki"],"Ignore articles (terms such as 'The' and 'A') when sorting lists":["Ignoruj przedminki (wyrażenia takie, jak: 'The' i 'A') podczas sortowania list"],"Vibrant headers":["Dynamiczne nagłówki"],"Use colourful headers for media pages":["Umożliwia używanie osobnego koloru nagłówka dla każdego typu mediów"],"Enable support for reverse proxying.":["Umożliwia aktywację obsługi reverse proxy."],"songs":["utwory"],"artists":["wykonawcy"],"albums":["albumy"],"movies":["filmy"],"Searching for":["Szukaj"],"and":["i"],"tvshows":["seriale"],"no media in this folder":["Brak mediów w folderze"],"Browse files and add-ons":["Przeglądaj pliki i dodatki"],"This is where you can browse all Kodi content, not just what is in the library. Browse by source or add-on.":["Miejsce, w którym możesz przeglądać całą zawartość Kodi, nie tylko to co znajduje się w bibliotece. Przeglądanie w podziale na źródła i dodatki."],"Send text to Kodi":["Wyślij tekst do Kodi"],"The lab":["Laboratorium"],"Chorus lab":["Laboratorium Chorusa"],"Warning":["Ostrzeżenie"],"Experimental code, use at own risk":["Funkcje eksperymentalne, używasz ich na własną odpowiedzialność."],"Kodi API browser":["Przeglądarka API Kodi"],"This is a tool to test out the API. Select a method then execute it with parameters.":["Narzędzie do testowania interfejsu programistycznego Kodi. Wybierz metodę, a następnie wykonaj ją z zadanymi parametrami"],"You could potentially damage your system with this and there are no sanity checks. Use at own risk.":["Istnieje potencjalna szansa na uszkodzenie Twojego systemu, ponieważ nie ma żadnej kontroli poprawności. Używasz na własną odpowiedzialność."],"Saved Kodi settings":["Zapisano zmiany ustawień Kodi"],"General":["Ogólne"],"Advanced setting level is recommended for those who know what they are doing.":["Poziom Zaawansowany jest rekomendowany tylko dla tych, którzy wiedzą co robią."],"Kodi settings level":["Poziom ustawień Kodi"],"Remove":["Usuń"],"cast":["obsada"],"Add-ons":["Dodatki"],"Web interface":["Interfejs webowy"],"Readme":["Dokumentacja"],"Changelog":["Dziennik zmian"],"Translations":["Tłumaczenia"],"Help topics":["Tematy pomocy"],"Overview":["Przegląd"],"Lab":["Laboratorium"],"version":["wersja"],"Remote control":["Sterowanie"],"Remote control is set up correctly":["Zdalne sterowanie zostało poprawnie skonfigurowane"],"About":["O Chorusie"],"Local audio":["Dźwięk"],"Status report":["Raport o stanie"],"in":["w"],"Focus playlist on playing":["Zaznaczaj odtwarzaną pozycję na liście"],"Automatically scroll the playlist to the current playing item. This happens whenever the playing item is changed":["Umożliwia automatyczne przewijanie listy do aktualnie odtwarzanej pozycji. Ta operacja jest wykonywana za każdym razem, gdy zmienia się odtwarzana pozycja."],"Web Settings saved.":["Zapisano ustawienia interfejsu webowego."],"Keyboard controls":["Sterowanie klawiaturą"],"In Chorus, will you keyboard control Kodi, the browser or both":["Umożliwia sterowanie przy pomocy klawiatury działaniem Kodi, przeglądarki lub oboma jednocześnie"],"Learn more":["Dowiedz się więcej"],"Resume playback":["Wznów odtwarzanie"],"Resume from":["Wznów od"],"Start from the beginning":["Zacznij od początku"],"Click here restore defaults":["Naciśnij, aby przywrócić domyślne ustawienia"],"Main Menu Structure":["Struktura menu"],"Here you can change the title, url and %1$s for menu items. You can also remove, re-order and add new items.":["Umożliwia zmianę tytułu, adresu URL i %1$s pozycji menu. Możesz także usunąć pozycje, zmienić ich kolejność lub dodać nowe pozycje."],"Main Nav":["Nawigacja"],"Add a new playlist":["Dodaj nową listę"],"Keyboard":["Klawiatura"],"Music":["Muzyka"],"Digital radio":["Radio"],"Movies":["Filmy"],"TV shows":["Seriale"],"TV":["Telewizja"],"Browser":["Przeglądarka"],"Thumbs up":["Lubię to!"],"Settings":["Ustawienia"],"Help":["Pomoc"],"Disable Thumbs Up":["Dezaktywuj funkcję 'Lubię to!'"],"Remove the thumbs up button from media. Note: you may also want to remove the menu item from the ":["Umożliwia usunięcie przycisku 'Lubię to' z panelu informacji o mediach. Uwaga: Możesz także usunąć pozycję menu z "],"You need to 'Allow remote control' for Kodi. You can do that":["Wymagana aktywacja opcji 'Zezwalaj na zdalne sterowanie Kodi przez HTTP'. Możesz to zrobić"],"here":["tutaj"],"yes":["tak"],"no":["nie"],"close":["zamknij"],"ok":["ok"],"Are you sure?":["Jesteś pewien?"],"Set all episodes for this season as":["Ustaw wszystkie odcinki tego sezonu jako"],"Set all episodes for this TV show as":["Ustaw wszystkie odcinki tego serialu jako"],"watched":["obejrzane"],"unwatched":["nieobejrzane"],"genre":["gatunek"],"studio":["wytwórnia"],"rated":["kategoria"],"episodes":["odcinki"],"total":["razem"],"set":["ustaw"],"Show device name":["Pokazuj nazwę urządzenia"],"Show the Kodi device name in the header of Chorus":["Umożliwia wyświetlanie nazwy urządzenia, na którym uruchomiono Kodi, w nagłówku strony Chorusa."],"No results found":["Brak wyników wyszukiwania"],"Have you done a library scan?":["Czy wykonałeś skanowanie biblioteki?"],"Play in browser":["Odtwarzaj w przeglądarce"],"Edit":["Edytuj"],"Add to Kodi":["Dodaj do Kodi"],"Watched":["Obejrzane"],"New playlist":["Nowa lista"],"Play in Kodi":["Odtwarzaj w Kodi"],"Export list":["Eksportuj listę"],"Delete playlist":["Usuń listę"],"title":["tytuł"],"year":["rok"],"date added":["data dodania"],"rating":["ocena"],"actor":["aktor"],"mood":["nastrój"],"writer":["scenarzysta"],"director":["reżyser"],"style":["styl"],"items selected":["pozycje zaznaczone"],"item selected":["pozycja zaznaczona"],"Video library clean started":["Rozpoczęto czyszczenie biblioteki wideo"],"Video library clean finished":["Zakończono czyszczenie biblioteki wideo"],"Audio library clean started":["Rozpoczęto czyszczenie biblioteki muzyki"],"Audio library clean finished":["Zakończono czyszczenie biblioteki muzyki"],"This is a tool to test out the api. Select a method then execute it with parameters.":["To jest narzędzie do testowania interfejsu programistycznego Kodi. Wybierz metodę, a następnie wykonaj ją z zadanymi parametrami"],"Go to season":["Przejdź do sezonu"],"Queue in Kodi":["Dodaj do kolejki Kodi"],"Adding items to the queue":["Dodawanie pozycji do kolejki"],"Live TV":["Telewizja"],"Recently added albums":["Albumy ostatnio dodane"],"Random albums":["Albumy losowe"],"Recently played albums":["Albumy ostatnio odtwarzane"],"Random movies":["Filmy losowe"],"Continue watching":["Kontynuuj odtwarzanie"],"More from %1$s":["Więcej z %1$s"],"More %1$s movies":["Więcej filmów z %1$s"],"More movies staring %1$s":["Więcej filmów z aktorem %1$s"],"Other movies released in %1$s":["Inne premiery filmów w %1$s"],"artist":["wykonawca"],"random":["losowo"],"label":["wytwórnia"],"formed":["założone"],"born":["urodzony"],"died":["zmarły"],"disbanded":["rozwiązany"],"years active":["lata aktywności"],"Click for more":["Naciśnij po więcej informacji"],"Loading albums":["Wczytywanie albumów"],"%1$d seconds ago, an input dialog opened in Kodi and it is still open! To prevent a mainframe implosion, you should probably give me some text. I don't really care what it is at this point, why not be creative? Do you have a %2$s? I won't tell...":["%1$d sekund temu okno dialogowe zostało otworzone i ciągle jest otwarte! Aby zapobiec implozji systemu, powinieneś wprowadzić jakiś tekst. Obecnie nie dbamy co to powinno być, więc dlaczego nie być kreatywnym? Czy posiadasz %2$s? Nie powiem..."],"all media":["wszystkie media"],"YouTube":["YouTube"],"SoundCloud":["SoundCloud"],"GoogleMusic":["GoogleMusic"],"Radio":["Radio"],"MixCloud":["MixCloud"],"First aired":["Premiera"],"Updated %1$s details":["Zaktualizowano informacje o %1$s"],"Title":["Tytuł"],"Plot":["Fabuła"],"Rating":["Ocena"],"Original title":["Tytuł oryginalny"],"Directors":["Reżyseria"],"Writers":["Scenariusz"],"File path":["Ścieżka pliku"],"Artist":["Wykonawca"],"Description":["Opis"],"Label":["Wytwórnia"],"Year":["Rok"],"Genres":["Gatunki"],"Styles":["Style"],"Themes":["Motywy"],"Moods":["Nastroje"],"Album artist":["Wykonawca albumu"],"Album":["Album"],"Track":["Utwór"],"Disc":["Dysk"],"Tagline":["Motto"],"Studio":["Wytwórnia"],"Content rating":["Kategoria wiekowa"],"Premiered":["Premiera"],"IMDb":["IMDb"],"Sort title":["Tytuł sortowania"],"Country":["Kraj"],"Set":["Seria"],"Tags":["Znaczniki"],"Trailer":["Zwiastun"],"Formed":["Założony"],"Disbanded":["Rozwiązany"],"Years Active":["Lata aktywności"],"Born":["Urodzony"],"Died":["Zmarły"],"Instruments":["Instrumenty"],"more":["więcej"],"in progress":["W trakcie"],"URL":["Adres URL"],"Add an image via an external URL":["Dodaj obraz za pomocą adresu URL"],"Searching for more images":["Wyszukiwanie dodatkowych obrazów"],"Image Selector":["Wybór obrazu"],"Image URL":["Adres URL obrazu"],"External Search":["Szukaj w Internecie"],"Local media":["Media lokalne"],"Chorus Search":["Szukaj w Chorusie"],"YouTube Search":["Szukaj w YouTube"],"Executed addon":["Uruchomiony dodatek"],"all":["wszystkie"],"video":["wideo"],"audio":["muzyka"],"image":["obraz"],"picture":["zdjęcie"],"executable":["program"],"settings":["ustawienia"],"Refresh":["Odśwież"],"Confirm refresh":["Odświeżenie informacji o pozycji '%1$s' spowoduje usunięcie jej z biblioteki, a następnie ponowne jej dodanie, co może zmienić jej identyfikator. Za kilka sekund nastąpi próba przeładowania strony z nowym identyfikatorem. Naciśnij 'TAK', aby potwierdzić odświeżenie"],"Refresh Ignore NFO":["Odświeżaj ignorując pliki NFO"],"Ignore local NFO files when manually refreshing media.":["Umożliwia ignorowanie lokalnych plików NFO podczas manualnego odświeżania informacji o mediach."],"Show only":["Tylko seriale"],"Show and episodes":["Seriale i odcinki"],"Top music":["Najlepsza muzyka"],"%1$s Artists":["%1$s Wykonawcy"],"%1$s Albums":["%1$s Albumy"],"%1$s Songs":["%1$s Utwory"],"default":["domyślne"],"Actions":["Akcje"],"play files":["odtwarzaj pliki"],"queue files":["dodaj pliki do kolejki"],"Sent text":["Wyślij tekst"],"License":["Licencja"],"Main Menu":["Menu startowe"],"Search":["Wyszukiwanie"],"Custom Add-on search":["Wyszukiwanie zawartości dodatku"],"Add custom add-on searches":["Mechanizm wyszukiwania Chorusa obsługuje nie tylko lokalne media, ale także zawartość dodatków. Dla przykładu, możesz użyć wyszukiwania, aby znaleźć wideo w YouTube lub muzykę w usłudze SoundCloud. Ta strona umożliwia dodanie niestandardowego wyszukiwania w zawartości dodatku, które domyślnie nie jest dostępne. Zobacz %1$s, aby dowiedzieć się więcej."],"Add-ons help page":["Strona pomocy dodatków"],"No %1$s found":["Brak %1$s"],"results":["wyniki"],"EPG data":["danych przewodnika"],"PVR":["Telewizja"],"Recordings":["Nagrania"],"Channel recording toggled":["Zmieniono status nagrywania kanału"],"TV Channels":["Kanały telewizyjne"],"Radio Stations":["Stacje radiowe"],"Record":["Nagraj"],"Toggle timer":["Przełącz zadanie"],"Now":["Teraz"],"Rename playlist":["Przemianuj listę"]}}}
\ No newline at end of file diff --git a/addons/webinterface.default/lang/en/app-changelog.html b/addons/webinterface.default/lang/en/app-changelog.html index 4e676c2059..78b09eafd7 100644 --- a/addons/webinterface.default/lang/en/app-changelog.html +++ b/addons/webinterface.default/lang/en/app-changelog.html @@ -1,3 +1,20 @@ +<h2 id="version-2-4-2">Version 2.4.2</h2> +<ul> +<li>Added trailer selector to movie editor</li> +<li>Added ability to quit, shutdown, reboot, suspend and hibernate when remote power button clicked #28</li> +<li>Attempt to reconnect to websockets after closed connection #15</li> +<li>Added ability to select all items from a set and perform action on items #156</li> +<li>Added tooltip with episode air date to episode teaser #170</li> +<li>Added ChromeCast support to local video player #220</li> +<li>Changed all video player libs to local assets, Minor style and bugfixes #219</li> +<li>Volume can now be controlled via - and = keys for keyboards without numpad #202</li> +<li>Removed cocktail and mixins as not in use #179</li> +<li>Added external videos to music video details page</li> +<li>Added fanarttv and musicbrainz external lookups for musicvideo fanart and thumb</li> +<li>Added support for music videos #217</li> +<li>Added disconnect notice when kodi has quit #10</li> +<li>Updated Polish Translation #216</li> +</ul> <h2 id="version-2-4-1">Version 2.4.1</h2> <ul> <li>Added album to song table #212</li> diff --git a/addons/webinterface.default/lang/pl/app-changelog.html b/addons/webinterface.default/lang/pl/app-changelog.html index 4aa6faa88a..3a1244b2d7 100644 --- a/addons/webinterface.default/lang/pl/app-changelog.html +++ b/addons/webinterface.default/lang/pl/app-changelog.html @@ -1,3 +1,15 @@ +<h2 id="wersja-2-4-1">Wersja 2.4.1</h2> +<ul> +<li>Dodano album do tabeli utworu #212</li> +<li>Naprawiono kilka drobych błędów regresyjnych</li> +<li>Naprawiono błąd wczytywania strony filmu w Kodi dla wersji 16 #207</li> +<li>Dodano możliwość zmiany nazwy list odtwarzania #55</li> +<li>Zaktualizowano sekcję Telewizja, ulepszono interfejs użytkownika i dodano listę nagrań</li> +<li>Naprawiono ściężkę dostępu do sekcji Telewizja #17</li> +<li>Naprawiono błąd wczytywania danych przewodnika #211</li> +<li>Zaktualizowano tłumaczenie na język polski #205 #210</li> +<li>Zmieniono typ licencji Chorusa na GPL-2+ #179 #208</li> +</ul> <h2 id="wersja-2-4-0">Wersja 2.4.0</h2> <ul> <li>Naprawiono rzadki błąd widoczny po opuszczeniu list z dużą ilością pozycji</li> diff --git a/addons/webinterface.default/lang/pl/app-readme.html b/addons/webinterface.default/lang/pl/app-readme.html index 167960c93a..69468c9347 100644 --- a/addons/webinterface.default/lang/pl/app-readme.html +++ b/addons/webinterface.default/lang/pl/app-readme.html @@ -106,9 +106,21 @@ narzędzia znajdują się w przyborniku.</p> </ul> <h2 id="wsparcie">Wsparcie</h2> <p>Jesteś fanem Chorusa? Możesz <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ZCGV976794JHE&lc=AU&item_name=Chorus%20Beer%20Fund&currency_code=AUD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted">zasponsorować</a> Jeremy'iemu piwo, aby okazać swoją wdzięczność. :)</p> -<h2 id="license">License</h2> -<p>Chorus jest udostępniany na licencji Creative Commons Uznanie autorstwa - Na tych samych warunkach 3.0 Stany Zjednoczone. -<a href="https://github.com/xbmc/chorus2/blob/master/src/lang/en/license.md">Naciśnij tutaj, aby dowiedzieć się więcej</a>.</p> +<h2 id="licencja">Licencja</h2> +<p>Ta aplikacja jest darmowym oprogramowaniem; możesz ją dystrybuować +i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU +opublikowanej przez Fundację Wolnego Oprogramowania, w wersji +drugiej lub późniejszej.</p> +<p>Ten program jest dystrybuowany w nadziei, że będzie użyteczny, +aczkolwiek BEZ ŻADNEJ GWARANCJI, nawet bez domyślnej gwarancji +HANDLOWEJ lub PRZYDATNOŚCI DLA OKREŚLONEGO CELU. Zapoznaj się +z treścią Powszechnej Licencji Publicznej GNU, aby dowiedzieć +się więcej.</p> +<p>Powinienieś otrzymać kopię Powszechnej Licencji Publicznej GNU +<a href="https://github.com/xbmc/chorus2/blob/master/LICENSE">razem z programem</a>; +jeśli nie, napisz do Fundacji Wolnego Oprogramowania, Inc, na adres +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</p> +<p><a href="https://github.com/xbmc/chorus2/blob/master/src/lang/en/license.md">Naciśnij tutaj, aby dowiedzieć się więcej</a>.</p> <h2 id="zrzuty-ekranu">Zrzuty ekranu</h2> <h3 id="strona-startowa-teraz-odtwarzane-">Strona startowa (Teraz odtwarzane)</h3> <p><img src="https://raw.githubusercontent.com/xbmc/chorus2/master/dist/screenshots/now-playing.jpg" alt="alt text" title="Strona startowa/Teraz odtwarzane"></p> diff --git a/addons/webinterface.default/lib/jquery/jquery-1.11.0.min.js b/addons/webinterface.default/lib/jquery/jquery-1.11.0.min.js new file mode 100644 index 0000000000..046e93aa15 --- /dev/null +++ b/addons/webinterface.default/lib/jquery/jquery-1.11.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b) +},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/font/VideoJS.eot b/addons/webinterface.default/lib/video-js/font/VideoJS.eot Binary files differnew file mode 100644 index 0000000000..cbdd2a20c0 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/font/VideoJS.eot diff --git a/addons/webinterface.default/lib/video-js/font/VideoJS.svg b/addons/webinterface.default/lib/video-js/font/VideoJS.svg new file mode 100644 index 0000000000..49af73ab8a --- /dev/null +++ b/addons/webinterface.default/lib/video-js/font/VideoJS.svg @@ -0,0 +1,102 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<defs> + <font id="VideoJS" horiz-adv-x="1792"> + <font-face font-family="VideoJS" + units-per-em="1792" ascent="1792" + descent="0" /> + <missing-glyph horiz-adv-x="0" /> + <glyph glyph-name="play" + unicode="" + horiz-adv-x="1792" d=" M597.3333333333334 1418.6666666666665V373.3333333333333L1418.6666666666667 896z" /> + <glyph glyph-name="play-circle" + unicode="" + horiz-adv-x="1792" d=" M746.6666666666667 560L1194.6666666666667 896L746.6666666666667 1232V560zM896 1642.6666666666667C483.4666666666667 1642.6666666666667 149.3333333333334 1308.5333333333333 149.3333333333334 896S483.4666666666667 149.3333333333333 896 149.3333333333333S1642.6666666666667 483.4666666666667 1642.6666666666667 896S1308.5333333333333 1642.6666666666667 896 1642.6666666666667zM896 298.6666666666665C566.72 298.6666666666665 298.6666666666667 566.7199999999998 298.6666666666667 896S566.72 1493.3333333333333 896 1493.3333333333333S1493.3333333333335 1225.28 1493.3333333333335 896S1225.2800000000002 298.6666666666665 896 298.6666666666665z" /> + <glyph glyph-name="pause" + unicode="" + horiz-adv-x="1792" d=" M448 373.3333333333333H746.6666666666667V1418.6666666666665H448V373.3333333333333zM1045.3333333333335 1418.6666666666665V373.3333333333333H1344V1418.6666666666665H1045.3333333333335z" /> + <glyph glyph-name="volume-mute" + unicode="" + horiz-adv-x="1792" d=" M1232 896C1232 1027.7866666666666 1155.8400000000001 1141.6533333333332 1045.3333333333335 1196.5333333333333V1031.52L1228.6399999999999 848.2133333333334C1230.88 863.8933333333334 1232 879.9466666666667 1232 896.0000000000001zM1418.6666666666667 896C1418.6666666666667 825.8133333333333 1403.3600000000001 759.7333333333333 1378.3466666666668 698.8799999999999L1491.466666666667 585.7599999999998C1540 678.72 1568 783.9999999999999 1568 896C1568 1215.5733333333333 1344.3733333333334 1482.88 1045.3333333333335 1550.8266666666666V1396.6399999999999C1261.1200000000001 1332.4266666666667 1418.6666666666667 1132.6933333333332 1418.6666666666667 896zM319.2000000000001 1568L224 1472.8L576.8 1120H224V672H522.6666666666667L896 298.6666666666665V800.8L1213.7066666666667 483.0933333333332C1163.68 444.6399999999999 1107.3066666666666 413.6533333333332 1045.3333333333335 394.9866666666665V240.7999999999998C1148 264.32 1241.7066666666667 311.3599999999997 1320.48 375.9466666666663L1472.8000000000002 224L1568 319.1999999999998L896 991.1999999999998L319.2000000000001 1568zM896 1493.3333333333333L739.9466666666667 1337.28L896 1181.2266666666667V1493.3333333333333z" /> + <glyph glyph-name="volume-low" + unicode="" + horiz-adv-x="1792" d=" M522.6666666666667 1120V672H821.3333333333334L1194.6666666666667 298.6666666666665V1493.3333333333333L821.3333333333334 1120H522.6666666666667z" /> + <glyph glyph-name="volume-mid" + unicode="" + horiz-adv-x="1792" d=" M1381.3333333333335 896C1381.3333333333335 1027.7866666666666 1305.1733333333334 1141.6533333333332 1194.6666666666667 1196.5333333333333V595.0933333333332C1305.1733333333334 650.3466666666666 1381.3333333333335 764.2133333333331 1381.3333333333335 896zM373.3333333333334 1120V672H672L1045.3333333333335 298.6666666666665V1493.3333333333333L672 1120H373.3333333333334z" /> + <glyph glyph-name="volume-high" + unicode="" + horiz-adv-x="1792" d=" M224 1120V672H522.6666666666667L896 298.6666666666665V1493.3333333333333L522.6666666666667 1120H224zM1232 896C1232 1027.7866666666666 1155.8400000000001 1141.6533333333332 1045.3333333333335 1196.5333333333333V595.0933333333332C1155.8400000000001 650.3466666666666 1232 764.2133333333331 1232 896zM1045.3333333333335 1550.8266666666666V1396.6399999999999C1261.1200000000001 1332.4266666666667 1418.6666666666667 1132.6933333333332 1418.6666666666667 896S1261.1200000000001 459.5733333333333 1045.3333333333335 395.3600000000002V241.1733333333332C1344.3733333333334 309.1199999999999 1568 576.0533333333333 1568 896S1344.3733333333334 1482.88 1045.3333333333335 1550.8266666666666z" /> + <glyph glyph-name="fullscreen-enter" + unicode="" + horiz-adv-x="1792" d=" M522.6666666666667 746.6666666666665H373.3333333333334V373.3333333333333H746.6666666666667V522.6666666666665H522.6666666666667V746.6666666666665zM373.3333333333334 1045.3333333333333H522.6666666666667V1269.3333333333333H746.6666666666667V1418.6666666666665H373.3333333333334V1045.3333333333333zM1269.3333333333335 522.6666666666665H1045.3333333333335V373.3333333333333H1418.6666666666667V746.6666666666665H1269.3333333333335V522.6666666666665zM1045.3333333333335 1418.6666666666665V1269.3333333333333H1269.3333333333335V1045.3333333333333H1418.6666666666667V1418.6666666666665H1045.3333333333335z" /> + <glyph glyph-name="fullscreen-exit" + unicode="" + horiz-adv-x="1792" d=" M373.3333333333334 597.3333333333333H597.3333333333334V373.3333333333333H746.6666666666667V746.6666666666665H373.3333333333334V597.3333333333333zM597.3333333333334 1194.6666666666665H373.3333333333334V1045.3333333333333H746.6666666666667V1418.6666666666665H597.3333333333334V1194.6666666666665zM1045.3333333333335 373.3333333333333H1194.6666666666667V597.3333333333333H1418.6666666666667V746.6666666666665H1045.3333333333335V373.3333333333333zM1194.6666666666667 1194.6666666666665V1418.6666666666665H1045.3333333333335V1045.3333333333333H1418.6666666666667V1194.6666666666665H1194.6666666666667z" /> + <glyph glyph-name="square" + unicode="" + horiz-adv-x="1792" d=" M1344 1493.3333333333333H448C365.4933333333334 1493.3333333333333 298.6666666666667 1426.5066666666667 298.6666666666667 1344V448C298.6666666666667 365.4933333333331 365.4933333333334 298.6666666666665 448 298.6666666666665H1344C1426.506666666667 298.6666666666665 1493.3333333333335 365.4933333333331 1493.3333333333335 448V1344C1493.3333333333335 1426.5066666666667 1426.506666666667 1493.3333333333333 1344 1493.3333333333333zM1344 448H448V1344H1344V448z" /> + <glyph glyph-name="spinner" + unicode="" + horiz-adv-x="1792" d=" M701.8666666666668 1008L1057.6533333333334 1624.3733333333334C1005.7600000000002 1635.9466666666667 951.6266666666666 1642.6666666666667 896 1642.6666666666667C716.8000000000001 1642.6666666666667 552.9066666666668 1579.5733333333333 424.1066666666667 1474.2933333333333L697.76 1000.5333333333334L701.8666666666666 1008zM1608.32 1120C1539.6266666666666 1338.4 1373.1200000000001 1512.7466666666667 1160.6933333333332 1593.3866666666668L887.4133333333334 1120H1608.32zM1627.7333333333336 1045.3333333333333H1068.48L1090.1333333333334 1008L1445.92 392C1567.6266666666668 524.9066666666668 1642.6666666666667 701.4933333333333 1642.6666666666667 896C1642.6666666666667 947.1466666666666 1637.44 997.1733333333332 1627.7333333333336 1045.3333333333333zM637.2800000000001 896L346.08 1400C224.3733333333333 1267.0933333333332 149.3333333333334 1090.5066666666667 149.3333333333334 896C149.3333333333334 844.8533333333332 154.56 794.8266666666666 164.2666666666667 746.6666666666665H723.5200000000001L637.2800000000002 896zM183.68 672C252.3733333333334 453.5999999999999 418.88 279.2533333333334 631.3066666666667 198.6133333333332L904.5866666666668 672H183.68zM1025.1733333333334 672L733.9733333333334 167.6266666666666C786.24 156.0533333333333 840.3733333333334 149.3333333333333 896 149.3333333333333C1075.2 149.3333333333333 1239.0933333333332 212.4266666666665 1367.8933333333334 317.7066666666665L1094.24 791.4666666666666L1025.1733333333334 672z" /> + <glyph glyph-name="subtitles" + unicode="" + horiz-adv-x="1792" d=" M1493.3333333333335 1493.3333333333333H298.6666666666667C216.16 1493.3333333333333 149.3333333333334 1426.5066666666667 149.3333333333334 1344V448C149.3333333333334 365.4933333333331 216.16 298.6666666666665 298.6666666666667 298.6666666666665H1493.3333333333335C1575.8400000000001 298.6666666666665 1642.6666666666667 365.4933333333331 1642.6666666666667 448V1344C1642.6666666666667 1426.5066666666667 1575.8400000000001 1493.3333333333333 1493.3333333333335 1493.3333333333333zM298.6666666666667 896H597.3333333333334V746.6666666666665H298.6666666666667V896zM1045.3333333333335 448H298.6666666666667V597.3333333333333H1045.3333333333335V448zM1493.3333333333335 448H1194.6666666666667V597.3333333333333H1493.3333333333335V448zM1493.3333333333335 746.6666666666665H746.6666666666667V896H1493.3333333333335V746.6666666666665z" /> + <glyph glyph-name="captions" + unicode="" + horiz-adv-x="1792" d=" M1418.6666666666667 1493.3333333333333H373.3333333333334C290.8266666666667 1493.3333333333333 224 1426.5066666666667 224 1344V448C224 365.4933333333331 290.8266666666667 298.6666666666665 373.3333333333334 298.6666666666665H1418.6666666666667C1501.1733333333334 298.6666666666665 1568 365.4933333333331 1568 448V1344C1568 1426.5066666666667 1501.1733333333334 1493.3333333333333 1418.6666666666667 1493.3333333333333zM821.3333333333334 970.6666666666666H709.3333333333334V1008H560V783.9999999999999H709.3333333333334V821.3333333333333H821.3333333333334V746.6666666666665C821.3333333333334 705.5999999999999 788.1066666666667 672 746.6666666666667 672H522.6666666666667C481.2266666666667 672 448 705.5999999999999 448 746.6666666666665V1045.3333333333333C448 1086.4 481.2266666666667 1120 522.6666666666667 1120H746.6666666666667C788.1066666666667 1120 821.3333333333334 1086.4 821.3333333333334 1045.3333333333333V970.6666666666666zM1344 970.6666666666666H1232V1008H1082.6666666666667V783.9999999999999H1232V821.3333333333333H1344V746.6666666666665C1344 705.5999999999999 1310.7733333333333 672 1269.3333333333335 672H1045.3333333333335C1003.8933333333334 672 970.6666666666669 705.5999999999999 970.6666666666669 746.6666666666665V1045.3333333333333C970.6666666666669 1086.4 1003.8933333333334 1120 1045.3333333333335 1120H1269.3333333333335C1310.7733333333333 1120 1344 1086.4 1344 1045.3333333333333V970.6666666666666z" /> + <glyph glyph-name="chapters" + unicode="" + horiz-adv-x="1792" d=" M224 821.3333333333333H373.3333333333334V970.6666666666666H224V821.3333333333333zM224 522.6666666666665H373.3333333333334V672H224V522.6666666666665zM224 1120H373.3333333333334V1269.3333333333333H224V1120zM522.6666666666667 821.3333333333333H1568V970.6666666666666H522.6666666666667V821.3333333333333zM522.6666666666667 522.6666666666665H1568V672H522.6666666666667V522.6666666666665zM522.6666666666667 1269.3333333333333V1120H1568V1269.3333333333333H522.6666666666667z" /> + <glyph glyph-name="share" + unicode="" + horiz-adv-x="1792" d=" M1344 590.9866666666665C1287.2533333333333 590.9866666666665 1236.1066666666668 568.9599999999998 1197.2800000000002 533.4933333333331L665.2800000000001 843.7333333333333C669.3866666666667 860.5333333333333 672 878.08 672 896S669.3866666666667 931.4666666666666 665.2800000000001 948.2666666666667L1191.68 1255.52C1231.6266666666668 1218.1866666666665 1285.0133333333335 1195.04 1344 1195.04C1467.5733333333335 1195.04 1568 1295.4666666666665 1568 1419.04S1467.5733333333335 1643.04 1344 1643.04S1120 1542.6133333333332 1120 1419.04C1120 1401.12 1122.6133333333335 1383.5733333333333 1126.72 1366.773333333333L600.3199999999999 1059.5199999999998C560.3733333333333 1096.853333333333 506.9866666666666 1119.9999999999998 448 1119.9999999999998C324.4266666666666 1119.9999999999998 224 1019.5733333333332 224 895.9999999999998S324.4266666666666 671.9999999999998 448 671.9999999999998C506.9866666666666 671.9999999999998 560.3733333333333 695.1466666666665 600.3199999999999 732.4799999999998L1132.32 422.2399999999998C1128.5866666666666 406.5599999999997 1126.3466666666666 390.133333333333 1126.3466666666666 373.3333333333331C1126.3466666666666 253.1199999999997 1223.7866666666669 155.6799999999996 1344 155.6799999999996S1561.6533333333334 253.1199999999997 1561.6533333333334 373.3333333333331S1464.2133333333334 590.9866666666662 1344 590.9866666666662z" /> + <glyph glyph-name="cog" + unicode="" + horiz-adv-x="1792" d=" M1450.7733333333333 823.1999999999999C1453.76 847.0933333333334 1456 871.3599999999999 1456 896S1453.76 944.9066666666666 1450.7733333333333 968.8L1608.6933333333336 1092.3733333333332C1622.8800000000003 1103.5733333333333 1626.986666666667 1123.7333333333331 1617.6533333333336 1140.1599999999999L1468.3200000000004 1398.8799999999999C1458.986666666667 1414.9333333333334 1439.5733333333335 1421.6533333333332 1422.7733333333338 1414.9333333333334L1236.8533333333337 1339.8933333333332C1198.4000000000003 1369.3866666666668 1156.2133333333338 1394.3999999999999 1110.6666666666672 1413.44L1082.6666666666667 1611.3066666666666C1079.3066666666668 1628.8533333333332 1064 1642.6666666666667 1045.3333333333335 1642.6666666666667H746.6666666666667C728 1642.6666666666667 712.6933333333334 1628.8533333333332 709.7066666666668 1611.3066666666666L681.7066666666668 1413.44C636.1600000000002 1394.4 593.9733333333335 1369.76 555.5200000000001 1339.8933333333332L369.6 1414.9333333333334C352.8000000000001 1421.28 333.3866666666667 1414.9333333333334 324.0533333333334 1398.88L174.72 1140.1599999999999C165.3866666666667 1124.1066666666666 169.4933333333334 1103.9466666666667 183.68 1092.3733333333332L341.2266666666667 968.8C338.2400000000001 944.9066666666666 336 920.64 336 896S338.2400000000001 847.0933333333334 341.2266666666667 823.1999999999999L183.68 699.6266666666668C169.4933333333334 688.4266666666667 165.3866666666667 668.2666666666667 174.72 651.8399999999999L324.0533333333334 393.1199999999999C333.3866666666667 377.0666666666666 352.8 370.3466666666666 369.6 377.0666666666666L555.5200000000001 452.1066666666666C593.9733333333334 422.6133333333333 636.16 397.5999999999999 681.7066666666668 378.56L709.7066666666668 180.6933333333334C712.6933333333334 163.1466666666668 728 149.3333333333333 746.6666666666667 149.3333333333333H1045.3333333333335C1064 149.3333333333333 1079.3066666666668 163.1466666666665 1082.2933333333333 180.6933333333334L1110.2933333333333 378.56C1155.84 397.5999999999999 1198.0266666666666 422.24 1236.48 452.1066666666666L1422.3999999999999 377.0666666666666C1439.2 370.7199999999998 1458.6133333333332 377.0666666666666 1467.9466666666665 393.1199999999999L1617.2799999999997 651.8399999999999C1626.6133333333332 667.8933333333332 1622.5066666666664 688.0533333333333 1608.3199999999997 699.6266666666668L1450.773333333333 823.1999999999999zM896 634.6666666666665C751.52 634.6666666666665 634.6666666666667 751.52 634.6666666666667 896S751.52 1157.3333333333333 896 1157.3333333333333S1157.3333333333335 1040.48 1157.3333333333335 896S1040.48 634.6666666666665 896 634.6666666666665z" /> + <glyph glyph-name="circle" + unicode="" + horiz-adv-x="1792" d=" M149.3333333333334 896C149.3333333333334 483.6273867930074 483.6273867930075 149.3333333333333 896 149.3333333333333C1308.3726132069926 149.3333333333333 1642.6666666666667 483.6273867930074 1642.6666666666667 896C1642.6666666666667 1308.3726132069926 1308.3726132069926 1642.6666666666667 896 1642.6666666666667C483.6273867930075 1642.6666666666667 149.3333333333334 1308.3726132069926 149.3333333333334 896z" /> + <glyph glyph-name="circle-outline" + unicode="" + horiz-adv-x="1792" d=" M896 1642.6666666666667C483.4666666666667 1642.6666666666667 149.3333333333334 1308.5333333333333 149.3333333333334 896S483.4666666666667 149.3333333333333 896 149.3333333333333S1642.6666666666667 483.4666666666667 1642.6666666666667 896S1308.5333333333333 1642.6666666666667 896 1642.6666666666667zM896 298.6666666666665C566.72 298.6666666666665 298.6666666666667 566.7199999999998 298.6666666666667 896S566.72 1493.3333333333333 896 1493.3333333333333S1493.3333333333335 1225.28 1493.3333333333335 896S1225.2800000000002 298.6666666666665 896 298.6666666666665z" /> + <glyph glyph-name="circle-inner-circle" + unicode="" + horiz-adv-x="1792" d=" M896 1642.6666666666667C484.2133333333334 1642.6666666666667 149.3333333333334 1307.7866666666666 149.3333333333334 896S484.2133333333334 149.3333333333333 896 149.3333333333333S1642.6666666666667 484.2133333333331 1642.6666666666667 896S1307.7866666666669 1642.6666666666667 896 1642.6666666666667zM896 298.6666666666665C566.72 298.6666666666665 298.6666666666667 566.7199999999998 298.6666666666667 896S566.72 1493.3333333333333 896 1493.3333333333333S1493.3333333333335 1225.28 1493.3333333333335 896S1225.2800000000002 298.6666666666665 896 298.6666666666665zM1120 896C1120 772.4266666666666 1019.5733333333334 672 896 672S672 772.4266666666666 672 896S772.4266666666667 1120 896 1120S1120 1019.5733333333332 1120 896z" /> + <glyph glyph-name="hd" + unicode="" + horiz-adv-x="1792" d=" M1418.6666666666667 1568H373.3333333333334C290.4533333333333 1568 224 1500.8 224 1418.6666666666665V373.3333333333333C224 291.1999999999998 290.4533333333334 224 373.3333333333334 224H1418.6666666666667C1500.8000000000002 224 1568 291.1999999999998 1568 373.3333333333333V1418.6666666666665C1568 1500.8 1500.8000000000002 1568 1418.6666666666667 1568zM821.3333333333334 672H709.3333333333334V821.3333333333333H560V672H448V1120H560V933.3333333333331H709.3333333333334V1120H821.3333333333334V672zM970.6666666666669 1120H1269.3333333333335C1310.4 1120 1344 1086.4 1344 1045.3333333333333V746.6666666666665C1344 705.5999999999999 1310.4 672 1269.3333333333335 672H970.6666666666669V1120zM1082.6666666666667 783.9999999999999H1232V1008H1082.6666666666667V783.9999999999999z" /> + <glyph glyph-name="cancel" + unicode="" + horiz-adv-x="1792" d=" M896 1642.6666666666667C483.4666666666667 1642.6666666666667 149.3333333333334 1308.5333333333333 149.3333333333334 896S483.4666666666667 149.3333333333333 896 149.3333333333333S1642.6666666666667 483.4666666666667 1642.6666666666667 896S1308.5333333333333 1642.6666666666667 896 1642.6666666666667zM1269.3333333333335 628.3199999999999L1163.68 522.6666666666665L896 790.3466666666667L628.3199999999999 522.6666666666665L522.6666666666667 628.3199999999999L790.3466666666668 896L522.6666666666667 1163.68L628.3199999999999 1269.3333333333333L896 1001.6533333333332L1163.68 1269.3333333333333L1269.3333333333335 1163.68L1001.6533333333334 896L1269.3333333333335 628.3199999999999z" /> + <glyph glyph-name="replay" + unicode="" + horiz-adv-x="1792" d=" M896 1418.6666666666665V1717.3333333333333L522.6666666666667 1344L896 970.6666666666666V1269.3333333333333C1143.52 1269.3333333333333 1344 1068.8533333333332 1344 821.3333333333333S1143.52 373.3333333333333 896 373.3333333333333S448 573.813333333333 448 821.3333333333333H298.6666666666667C298.6666666666667 491.3066666666664 565.9733333333334 224 896 224S1493.3333333333335 491.3066666666664 1493.3333333333335 821.3333333333333S1226.0266666666669 1418.6666666666665 896 1418.6666666666665z" /> + <glyph glyph-name="facebook" + unicode="" + horiz-adv-x="1792" d=" M1343 1780V1516H1186Q1100 1516 1070 1480T1040 1372V1183H1333L1294 887H1040V128H734V887H479V1183H734V1401Q734 1587 838 1689.5T1115 1792Q1262 1792 1343 1780z" /> + <glyph glyph-name="gplus" + unicode="" + horiz-adv-x="1792" d=" M799 996Q799 960 831 925.5T908.5 857.5T999 784T1076 680T1108 538Q1108 448 1060 365Q988 243 849 185.5T551 128Q419 128 304.5 169.5T133 307Q96 367 96 438Q96 519 140.5 588T259 703Q390 785 663 803Q631 845 615.5 877T600 950Q600 986 621 1035Q575 1031 553 1031Q405 1031 303.5 1127.5T202 1372Q202 1454 238 1531T337 1662Q414 1728 519.5 1760T737 1792H1155L1017 1704H886Q960 1641 998 1571T1036 1411Q1036 1339 1011.5 1281.5T952.5 1188.5T883 1123.5T823.5 1062T799 996zM653 1092Q691 1092 731 1108.5T797 1152Q850 1209 850 1311Q850 1369 833 1436T784.5 1565.5T700 1669T583 1710Q541 1710 500.5 1690.5T435 1638Q388 1579 388 1478Q388 1432 398 1380.5T429.5 1277.5T481.5 1185T556.5 1118T653 1092zM655 219Q713 219 766.5 232T865.5 271T938.5 344T966 453Q966 478 959 502T944.5 544T917.5 585.5T888 620.5T849.5 655T813 684T771.5 714T735 740Q719 742 687 742Q634 742 582 735T474.5 710T377.5 664T309 589.5T282 484Q282 414 317 360.5T408.5 277.5T527.5 233.5T655 219zM1465 1095H1678V987H1465V768H1360V987H1148V1095H1360V1312H1465V1095z" /> + <glyph glyph-name="linkedin" + unicode="" + horiz-adv-x="1792" d=" M477 1167V176H147V1167H477zM498 1473Q499 1400 447.5 1351T312 1302H310Q228 1302 178 1351T128 1473Q128 1547 179.5 1595.5T314 1644T447 1595.5T498 1473zM1664 744V176H1335V706Q1335 811 1294.5 870.5T1168 930Q1105 930 1062.5 895.5T999 810Q988 780 988 729V176H659Q661 575 661 823T660 1119L659 1167H988V1023H986Q1006 1055 1027 1079T1083.5 1131T1170.5 1174.5T1285 1190Q1456 1190 1560 1076.5T1664 744z" /> + <glyph glyph-name="twitter" + unicode="" + horiz-adv-x="1792" d=" M1684 1384Q1617 1286 1522 1217Q1523 1203 1523 1175Q1523 1045 1485 915.5T1369.5 667T1185 456.5T927 310.5T604 256Q333 256 108 401Q143 397 186 397Q411 397 587 535Q482 537 399 599.5T285 759Q318 754 346 754Q389 754 431 765Q319 788 245.5 876.5T172 1082V1086Q240 1048 318 1045Q252 1089 213 1160T174 1314Q174 1402 218 1477Q339 1328 512.5 1238.5T884 1139Q876 1177 876 1213Q876 1347 970.5 1441.5T1199 1536Q1339 1536 1435 1434Q1544 1455 1640 1512Q1603 1397 1498 1334Q1591 1344 1684 1384z" /> + <glyph glyph-name="tumblr" + unicode="" + horiz-adv-x="1792" d=" M1328 463L1408 226Q1385 191 1297 160T1120 128Q1016 126 929.5 154T787 228T692 334T636.5 454T620 572V1116H452V1331Q524 1357 581 1400.5T672 1490.5T730 1592.5T764 1691.5T779 1780Q780 1785 783.5 1788.5T791 1792H1035V1368H1368V1116H1034V598Q1034 568 1040.5 542T1063 489.5T1112.5 448T1194 434Q1272 436 1328 463z" /> + <glyph glyph-name="pinterest" + unicode="" + horiz-adv-x="1792" d=" M1664 896Q1664 687 1561 510.5T1281.5 231T896 128Q785 128 678 160Q737 253 756 324Q765 358 810 535Q830 496 883 467.5T997 439Q1118 439 1213 507.5T1360 696T1412 966Q1412 1080 1352.5 1180T1180 1343T925 1406Q820 1406 729 1377T574.5 1300T465.5 1189.5T398.5 1060T377 926Q377 822 417 743T534 632Q564 620 572 652Q574 659 580 683T588 713Q594 736 577 756Q526 817 526 907Q526 1058 630.5 1166.5T904 1275Q1055 1275 1139.5 1193T1224 980Q1224 810 1155.5 691T980 572Q919 572 882 615.5T859 720Q867 755 885.5 813.5T915.5 916.5T927 992Q927 1042 900 1075T823 1108Q761 1108 718 1051T675 909Q675 836 700 787L601 369Q584 299 588 192Q382 283 255 473T128 896Q128 1105 231 1281.5T510.5 1561T896 1664T1281.5 1561T1561 1281.5T1664 896z" /> + <glyph glyph-name="audio-description" + unicode="" + horiz-adv-x="1792" d=" M795.5138904615 457.270933L795.5138904615 1221.5248286325C971.84576475 1225.085121904 1107.39330415 1232.12360523 1207.223857 1161.5835220499998C1303.033991 1093.8857027 1377.7922305 962.20560625 1364.3373135 792.9476205000001C1350.102593 613.9029365000001 1219.6655764999998 463.4600215 1050.12389545 448.2843645000001C965.8259268 440.7398275000001 798.21890505 448.2843645000001 798.21890505 448.2843645000001C798.21890505 448.2843645000001 795.2791410655 453.016494 795.5138904615 457.270933M966.1564647 649.0863960000001C1076.16084135 644.6767075 1152.385591 707.3020429999999 1163.8910079999998 807.9351875C1179.2994744999999 942.71878505 1089.73043585 1030.3691748 960.74508635 1020.7227954L960.74508635 658.08043C960.6196169500002 652.9482330000001 962.7606933 650.3134680000001 966.1564647 649.0863960000001 M1343.2299685 457.3517725000002C1389.9059734 444.3690160000001 1404.0840274999998 496.0596970000001 1424.48294065 532.2791494999999C1469.0084255 611.2788500000001 1502.5101322 712.8584189999999 1503.0416912 828.9881705C1503.8147453000001 995.5680973 1438.8404296 1117.7973688000002 1378.4383305 1200.62456881045L1348.652139905 1200.62456881045C1346.6001063899998 1187.06858424 1356.44474056 1175.024791325 1362.18395859 1164.6588891000001C1408.2649952 1081.49431985 1450.96645015 966.7230041 1451.57490975 834.9817034999999C1452.27106325 683.8655425000002 1402.00636065 557.5072264999999 1343.2299685 457.3517725000002 M1488.0379675 457.3517725000002C1534.7139723999999 444.3690160000001 1548.8825828 496.0671625 1569.29093965 532.2791494999999C1613.8164245 611.2788500000001 1647.3113856500001 712.8584189999999 1647.8496902000002 828.9881705C1648.6227442999998 995.5680973 1583.6484286 1117.7973688000002 1523.2463295 1200.62456881045L1493.460138905 1200.62456881045C1491.40810539 1187.06858424 1501.250041305 1175.021805755 1506.9919575899999 1164.6588891000001C1553.0729942 1081.49431985 1595.7757984 966.7230041 1596.3829087499998 834.9817034999999C1597.07906225 683.8655425000002 1546.8143596500001 557.5072264999999 1488.0379675 457.3517725000002 M1631.9130380000001 457.3517725000002C1678.5890429 444.3690160000001 1692.7576533 496.0671625 1713.1660101500001 532.2791494999999C1757.691495 611.2788500000001 1791.1864561500001 712.8584189999999 1791.7247607000002 828.9881705C1792.4978148 995.5680973 1727.5234991000002 1117.7973688000002 1667.1214 1200.62456881045L1637.3352094050001 1200.62456881045C1635.28317589 1187.06858424 1645.1251118050002 1175.02329854 1650.86702809 1164.6588891000001C1696.9480647 1081.49431985 1739.64951965 966.7230041 1740.25797925 834.9817034999999C1740.95413275 683.8655425000002 1690.6894301500001 557.5072264999999 1631.9130380000001 457.3517725000002 M15.66796875 451.481947L254.03034755 451.481947L319.0356932 551.1747990000001L543.6261075 551.6487970000001C543.6261075 551.6487970000001 543.8541115 483.7032095 543.8541115 451.481947L714.4993835 451.481947L714.4993835 1230.9210795L508.643051 1230.9210795C488.8579955 1197.5411595 15.66796875 451.481947 15.66796875 451.481947L15.66796875 451.481947zM550.0048155000001 959.9708615L550.0048155000001 710.916297L408.4199 711.8642895L550.0048155000001 959.9708615L550.0048155000001 959.9708615z" /> + <glyph glyph-name="audio" + unicode="" + horiz-adv-x="1792" d=" M896 1717.3333333333333C524.9066666666668 1717.3333333333333 224 1416.4266666666667 224 1045.3333333333333V522.6666666666665C224 399.0933333333333 324.4266666666667 298.6666666666665 448 298.6666666666665H672V896H373.3333333333334V1045.3333333333333C373.3333333333334 1333.92 607.4133333333334 1568 896 1568S1418.6666666666667 1333.92 1418.6666666666667 1045.3333333333333V896H1120V298.6666666666665H1344C1467.5733333333335 298.6666666666665 1568 399.0933333333333 1568 522.6666666666665V1045.3333333333333C1568 1416.4266666666667 1267.0933333333332 1717.3333333333333 896 1717.3333333333333z" /> + </font> +</defs> +</svg> diff --git a/addons/webinterface.default/lib/video-js/font/VideoJS.ttf b/addons/webinterface.default/lib/video-js/font/VideoJS.ttf Binary files differnew file mode 100644 index 0000000000..e23d02a49d --- /dev/null +++ b/addons/webinterface.default/lib/video-js/font/VideoJS.ttf diff --git a/addons/webinterface.default/lib/video-js/font/VideoJS.woff b/addons/webinterface.default/lib/video-js/font/VideoJS.woff Binary files differnew file mode 100644 index 0000000000..dc9d850472 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/font/VideoJS.woff diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/cast_sender.js b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/cast_sender.js new file mode 100644 index 0000000000..858b84a162 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/cast_sender.js @@ -0,0 +1,9 @@ +/** + * Google Chrome cast init script. + * + * @see http://www.gstatic.com/cv/js/sender/v1/cast_sender.js + * @docs https://developers.google.com/cast/docs/developers + */ +(function() {var e=function(){var a=window.navigator.userAgent.match(/Chrome\/([0-9]+)/);return a?parseInt(a[1],10):0},f=function(a){return document.currentScript&&(-1!=document.currentScript.src.indexOf("?"+a)||-1!=document.currentScript.src.indexOf("&"+a))},g=f("loadGamesSDK")?"/cast_game_sender.js":"/cast_sender.js",h=f("loadCastFramework"),k=function(){return"function"==typeof window.__onGCastApiAvailable?window.__onGCastApiAvailable:null},l=["boadgeojelhgndaghljhdicfkmllpafd","dliochdbjfkdbacpmhlcpmleaejidimm", + "enhhojjnijigcajfphajepfemndkmdlo","fmfcbgogabcbclcofgocippekhfcmgfj"],m=["pkedcjkdefgpdelpbcmbmeomcjbeemfm","fjhoaacokmgbjemoflkofnenfaiekifl"],n=50<=e()?m.concat(l):l.concat(m),p=function(a,c){var b=new XMLHttpRequest;b.onreadystatechange=function(){4==b.readyState&&200==b.status&&c(!0)};b.onerror=function(){c(!1)};try{b.open("GET",a,!0),b.send()}catch(d){c(!1)}},t=function(a){if(a>=n.length)q();else{var c=n[a],b="chrome-extension://"+c+g;0<=l.indexOf(c)?p(b,function(d){d?(window.chrome.cast=window.chrome.cast|| + {},window.chrome.cast.extensionId=c,r(b,q)):t(a+1)}):r(b,function(){t(a+1)})}},r=function(a,c,b){var d=document.createElement("script");d.onerror=c;b&&(d.onload=b);d.src=a;(document.head||document.documentElement).appendChild(d)},q=function(){var a=k();a&&a(!1,"No cast extension found")},u=function(){if(h){var a=2,c=k(),b=function(){a--;0==a&&c&&c(!0)};window.__onGCastApiAvailable=b;r("//www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js",q,b)}};a:{if(0<=window.navigator.userAgent.indexOf("CriOS")){var v=window.__gCrWeb&&window.__gCrWeb.message&&window.__gCrWeb.message.invokeOnHost;if(v){u();v({command:"cast.sender.init"});break a}}if(window.chrome){u();var w=window.navigator.userAgent;if(0<=w.indexOf("Android")&&0<=w.indexOf("Chrome/")&&window.navigator.presentation){var x="",y=e();55<=y?x="55":50<=y&&(x="50");r("//www.gstatic.com/eureka/clank"+x+g,q)}else t(0)}else q()};})();
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.eot b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.eot Binary files differnew file mode 100644 index 0000000000..da80703174 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.eot diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.svg b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.svg new file mode 100644 index 0000000000..0358ceaa6c --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.svg @@ -0,0 +1,30 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata></metadata> +<defs> +<font id="chromecastregular" horiz-adv-x="0" > +<font-face units-per-em="2048" ascent="2048" descent="0" /> +<missing-glyph horiz-adv-x="500" /> +<glyph d="M0 0z" /> +<glyph d="M0 0z" /> +<glyph horiz-adv-x="682" /> +<glyph d="M0 0z" /> +<glyph unicode=" " d="M0 0z" /> +<glyph unicode=" " d="M0 0z" /> +<glyph unicode=" " horiz-adv-x="682" /> +<glyph unicode=" " horiz-adv-x="1365" /> +<glyph unicode=" " horiz-adv-x="682" /> +<glyph unicode=" " horiz-adv-x="1365" /> +<glyph unicode=" " horiz-adv-x="455" /> +<glyph unicode=" " horiz-adv-x="341" /> +<glyph unicode=" " horiz-adv-x="227" /> +<glyph unicode=" " horiz-adv-x="227" /> +<glyph unicode=" " horiz-adv-x="170" /> +<glyph unicode=" " horiz-adv-x="273" /> +<glyph unicode=" " horiz-adv-x="75" /> +<glyph unicode=" " horiz-adv-x="273" /> +<glyph unicode=" " horiz-adv-x="341" /> +<glyph unicode="◼" horiz-adv-x="1000" d="M0 0z" /> +</font> +</defs></svg>
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.ttf b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.ttf Binary files differnew file mode 100644 index 0000000000..eb632222e2 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.ttf diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff Binary files differnew file mode 100644 index 0000000000..4f895a399b --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff2 b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff2 Binary files differnew file mode 100644 index 0000000000..12aaf5b2c9 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/fonts/chromecast.woff2 diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.css b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.css new file mode 100644 index 0000000000..053d5d4f20 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.css @@ -0,0 +1 @@ +@font-face{font-family:chromecast;src:url("fonts/chromecast.eot?#iefix") format("eot")}@font-face{font-family:chromecast;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg7RB+YAAAC8AAAAYGNtYXAXVdKJAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZjwDrFcAAAF4AAAAzGhlYWQKebynAAACRAAAADZoaGVhCTwFQQAAAnwAAAAkaG10eAk7AAAAAAKgAAAAFGxvY2EAKAB6AAACtAAAAAxtYXhwAAoALwAAAsAAAAAgbmFtZccyBsQAAALgAAABqnBvc3QAAwAAAAAEjAAAACAAAwU7AZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpAQQAAAAAAAQAAAAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6QH//f//AAAAAAAg6QH//f//AAH/4xcDAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAAEAAAAAAU7BAAADgATAB8ALAAAExEeARcRIREhHgEXIREhAxUzLgEnFR4DFzMuAycVHgMXMy4DJ08bNBoEGv1eCg8GAuz7FE+XD1E3LE09KQhqCDtZc0JSkG9HCWoKV4y2aAQA/k8GDwoBZ/0hGjQbA7H8l5c3UclqCCk9TSxCc1k7wmoJR2+QUmi2jFcKAAABAAAAAQAAsTF8aV8PPPUACwQAAAAAANMQO9UAAAAA0xA71QAAAAAFOwQAAAAACAACAAAAAAAAAAEAAAQAAAAAAAU7AAAAAAU7AAEAAAAAAAAAAAAAAAAAAAAFBAAAAAAAAAAAAAAAAAAAAAU7AAAAAAAAAAoAFAAeAGYAAQAAAAUALQAEAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAoAAAABAAAAAAACAAcAewABAAAAAAADAAoAPwABAAAAAAAEAAoAkAABAAAAAAAFAAsAHgABAAAAAAAGAAoAXQABAAAAAAAKABoArgADAAEECQABABQACgADAAEECQACAA4AggADAAEECQADABQASQADAAEECQAEABQAmgADAAEECQAFABYAKQADAAEECQAGABQAZwADAAEECQAKADQAyENocm9tZWNhc3QAQwBoAHIAbwBtAGUAYwBhAHMAdFZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMENocm9tZWNhc3QAQwBoAHIAbwBtAGUAYwBhAHMAdENocm9tZWNhc3QAQwBoAHIAbwBtAGUAYwBhAHMAdFJlZ3VsYXIAUgBlAGcAdQBsAGEAckNocm9tZWNhc3QAQwBoAHIAbwBtAGUAYwBhAHMAdEZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=) format("truetype"),url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAT4AAsAAAAABKwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDtEH5mNtYXAAAAFoAAAAVAAAAFQXVdKJZ2FzcAAAAbwAAAAIAAAACAAAABBnbHlmAAABxAAAAMwAAADMPAOsV2hlYWQAAAKQAAAANgAAADYKebynaGhlYQAAAsgAAAAkAAAAJAk8BUFobXR4AAAC7AAAABQAAAAUCTsAAGxvY2EAAAMAAAAADAAAAAwAKAB6bWF4cAAAAwwAAAAgAAAAIAAKAC9uYW1lAAADLAAAAaoAAAGqxzIGxHBvc3QAAATYAAAAIAAAACAAAwAAAAMFOwGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA6QEEAAAAAAAEAAAAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADgAAAAKAAgAAgACAAEAIOkB//3//wAAAAAAIOkB//3//wAB/+MXAwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAABAAAAAAFOwQAAA4AEwAfACwAABMRHgEXESERIR4BFyERIQMVMy4BJxUeAxczLgMnFR4DFzMuAydPGzQaBBr9XgoPBgLs+xRPlw9RNyxNPSkIagg7WXNCUpBvRwlqCleMtmgEAP5PBg8KAWf9IRo0GwOx/JeXN1HJaggpPU0sQnNZO8JqCUdvkFJotoxXCgAAAQAAAAEAALExfGlfDzz1AAsEAAAAAADTEDvVAAAAANMQO9UAAAAABTsEAAAAAAgAAgAAAAAAAAABAAAEAAAAAAAFOwAAAAAFOwABAAAAAAAAAAAAAAAAAAAABQQAAAAAAAAAAAAAAAAAAAAFOwAAAAAAAAAKABQAHgBmAAEAAAAFAC0ABAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAKAAAAAQAAAAAAAgAHAHsAAQAAAAAAAwAKAD8AAQAAAAAABAAKAJAAAQAAAAAABQALAB4AAQAAAAAABgAKAF0AAQAAAAAACgAaAK4AAwABBAkAAQAUAAoAAwABBAkAAgAOAIIAAwABBAkAAwAUAEkAAwABBAkABAAUAJoAAwABBAkABQAWACkAAwABBAkABgAUAGcAAwABBAkACgA0AMhDaHJvbWVjYXN0AEMAaAByAG8AbQBlAGMAYQBzAHRWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADBDaHJvbWVjYXN0AEMAaAByAG8AbQBlAGMAYQBzAHRDaHJvbWVjYXN0AEMAaAByAG8AbQBlAGMAYQBzAHRSZWd1bGFyAFIAZQBnAHUAbABhAHJDaHJvbWVjYXN0AEMAaAByAG8AbQBlAGMAYQBzAHRGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("woff"),url("fonts/chromecast.svg?chromecast") format("svg");font-weight:normal;font-style:normal}.vjs-icon-chromecast,.video-js .vjs-chromecast-button,.vjs-tech-chromecast .casting-overlay .casting-information .casting-icon{font-family:chromecast;font-weight:normal;font-style:normal}.vjs-icon-chromecast:before,.video-js .vjs-chromecast-button:before,.vjs-tech-chromecast .casting-overlay .casting-information .casting-icon:before{content:""}.video-js .vjs-chromecast-button{cursor:pointer}.video-js .vjs-chromecast-button{font-size:0.7em}.video-js .vjs-chromecast-button:before{line-height:2.3}.video-js .vjs-chromecast-button.connected{color:#66A8CC}.video-js .vjs-chromecast-button.error{color:#c70000}.vjs-tech-chromecast .casting-image{position:absolute;top:0;right:0;left:0;bottom:0;background-color:#000;background-repeat:no-repeat;background-size:contain;background-position:center}.vjs-tech-chromecast .casting-overlay{position:absolute;top:0;right:0;left:0;bottom:0;background-color:#000;background-color:rgba(0,0,0,0.3);cursor:default}.vjs-tech-chromecast .casting-overlay .casting-information{position:absolute;bottom:8em;right:8em;height:50px;color:#FFF}.vjs-tech-chromecast .casting-overlay .casting-information .casting-icon{font-size:44px;line-height:50px;margin-right:10px;float:left;width:58px;height:50px}.vjs-tech-chromecast .casting-overlay .casting-information .casting-description{height:50px;font-size:20px;line-height:20px}.vjs-tech-chromecast .casting-overlay .casting-information .casting-description small{font-size:11px}
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.js b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.js new file mode 100644 index 0000000000..c4ddf2a3ba --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.js @@ -0,0 +1,985 @@ +/** + * videojs-chromecast + * @version 2.0.8 + * @copyright 2016 Benjipott, Inc. + * @license Apache-2.0 + */ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.video || (g.video = {})).jsChromecast = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ +(function (global){ +/** + * @file chromecast-button.js + */ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null); + +var _videoJs2 = _interopRequireDefault(_videoJs); + +var Component = _videoJs2['default'].getComponent('Component'); +var ControlBar = _videoJs2['default'].getComponent('ControlBar'); +var Button = _videoJs2['default'].getComponent('Button'); + +/** + * The base class for buttons that toggle chromecast video + * + * @param {Player|Object} player + * @param {Object=} options + * @extends Button + * @class ChromeCastButton + */ + +var ChromeCastButton = (function (_Button) { + _inherits(ChromeCastButton, _Button); + + function ChromeCastButton(player, options) { + _classCallCheck(this, ChromeCastButton); + + _get(Object.getPrototypeOf(ChromeCastButton.prototype), 'constructor', this).call(this, player, options); + this.hide(); + this.initializeApi(); + options.appId = player.options_.chromecast.appId; + player.chromecast = this; + } + + /** + * Init chromecast sdk api + * + * @method initializeApi + */ + + _createClass(ChromeCastButton, [{ + key: 'initializeApi', + value: function initializeApi() { + var apiConfig = undefined; + var appId = undefined; + var sessionRequest = undefined; + + if (!_videoJs2['default'].browser.IS_CHROME || _videoJs2['default'].browser.IS_EDGE) { + return; + } + if (!chrome.cast || !chrome.cast.isAvailable) { + console.log(chrome.cast); + _videoJs2['default'].log('Cast APIs not available'); + if (this.tryingReconnect < 10) { + this.setTimeout(this.initializeApi, 1000); + ++this.tryingReconnect; + } + _videoJs2['default'].log('Cast APIs not available. Max reconnect attempt'); + return; + } + + _videoJs2['default'].log('Cast APIs are available'); + appId = this.options_.appId || chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID; + sessionRequest = new chrome.cast.SessionRequest(appId); + apiConfig = new chrome.cast.ApiConfig(sessionRequest, this.sessionJoinedListener.bind(this), this.receiverListener.bind(this)); + return chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.castError.bind(this)); + } + }, { + key: 'castError', + value: function castError(_castError) { + + var error = { + code: _castError.code, + message: _castError.description + }; + + switch (_castError.code) { + case chrome.cast.ErrorCode.API_NOT_INITIALIZED: + case chrome.cast.ErrorCode.EXTENSION_MISSING: + case chrome.cast.ErrorCode.EXTENSION_NOT_COMPATIBLE: + case chrome.cast.ErrorCode.INVALID_PARAMETER: + case chrome.cast.ErrorCode.LOAD_MEDIA_FAILED: + case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE: + case chrome.cast.ErrorCode.SESSION_ERROR: + case chrome.cast.ErrorCode.CHANNEL_ERROR: + case chrome.cast.ErrorCode.TIMEOUT: + this.addClass('error'); + break; + case chrome.cast.ErrorCode.CANCEL: + break; + default: + this.player_.error(error); + break; + } + return _videoJs2['default'].log('Cast Error: ' + JSON.stringify(_castError)); + } + }, { + key: 'onInitSuccess', + value: function onInitSuccess() { + return this.apiInitialized = true; + } + }, { + key: 'sessionJoinedListener', + value: function sessionJoinedListener(session) { + if (session.media.length) { + this.apiSession = session; + this.onMediaDiscovered(session.media[0]); + } + return console.log('Session joined'); + } + }, { + key: 'receiverListener', + value: function receiverListener(availability) { + if (availability === 'available') { + return this.show(); + } + } + }, { + key: 'doLaunch', + value: function doLaunch() { + _videoJs2['default'].log('Cast video: ' + this.player_.cache_.src); + if (this.apiInitialized) { + return chrome.cast.requestSession(this.onSessionSuccess.bind(this), this.castError.bind(this)); + } else { + return _videoJs2['default'].log('Session not initialized'); + } + } + }, { + key: 'onSessionSuccess', + value: function onSessionSuccess(session) { + var image = undefined; + var key = undefined; + var loadRequest = undefined; + var mediaInfo = undefined; + var ref = undefined; + var value = undefined; + + this.apiSession = session; + var source = this.player_.cache_.src; + var type = this.player_.currentType(); + + _videoJs2['default'].log('Session initialized: ' + session.sessionId + ' source : ' + source + ' type : ' + type); + + mediaInfo = new chrome.cast.media.MediaInfo(source, type); + mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); + if (this.options_.metadata) { + ref = this.options_.metadata; + for (key in ref) { + value = ref[key]; + mediaInfo.metadata[key] = value; + } + } + //Add poster image on player + var poster = this.player().poster(); + if (poster) { + image = new chrome.cast.Image(poster); + mediaInfo.metadata.images = [image]; + } + + // Load/Add caption tracks + var plTracks = this.player().textTracks(); + var remotePlTracks = this.player().remoteTextTrackEls(); + var tracks = []; + var i = 0; + var remotePlTrack = undefined; + var plTrack = undefined; + var trackId = 0; + var track = undefined; + if (plTracks) { + for (i = 0; i < plTracks.length; i++) { + plTrack = plTracks.tracks_[i]; + remotePlTrack = remotePlTracks && remotePlTracks.trackElements_ && remotePlTracks.trackElements_[i]; + trackId++; + track = new chrome.cast.media.Track(trackId, chrome.cast.media.TrackType.TEXT); + track.trackContentId = remotePlTrack ? remotePlTrack.src : 'caption_' + plTrack.language; + track.subtype = chrome.cast.media.TextTrackType.CAPTIONS; + track.name = plTrack.label; + track.language = plTrack.language; + track.customData = null; + tracks.push(track); + } + mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle(); + mediaInfo.textTrackStyle.foregroundColor = '#FFFFFF'; + mediaInfo.textTrackStyle.backgroundColor = '#00000060'; + mediaInfo.textTrackStyle.edgeType = chrome.cast.media.TextTrackEdgeType.DROP_SHADOW; + mediaInfo.textTrackStyle.windowType = chrome.cast.media.TextTrackWindowType.ROUNDED_CORNERS; + } + // Load/Add audio tracks + + try { + plTracks = this.player().audioTracks(); + if (plTracks) { + for (i = 0; i < plTracks.length; i++) { + plTrack = plTracks.tracks_[i]; + trackId++; + track = new chrome.cast.media.Track(trackId, chrome.cast.media.TrackType.AUDIO); + track.subtype = null; + track.name = plTrack.label; + track.language = plTrack.language; + track.customData = null; + tracks.push(track); + } + } + } catch (e) { + _videoJs2['default'].log('get player audioTracks fail' + e); + } + + if (tracks.length) { + mediaInfo.tracks = tracks; + } + + // Request load media source + loadRequest = new chrome.cast.media.LoadRequest(mediaInfo); + + loadRequest.autoplay = true; + loadRequest.currentTime = this.player_.currentTime(); + + this.apiSession.loadMedia(loadRequest, this.onMediaDiscovered.bind(this), this.castError.bind(this)); + this.apiSession.addUpdateListener(this.onSessionUpdate.bind(this)); + } + }, { + key: 'onMediaDiscovered', + value: function onMediaDiscovered(media) { + this.player_.loadTech_('Chromecast', { + type: 'cast', + apiMedia: media, + apiSession: this.apiSession + }); + + this.casting = true; + this.inactivityTimeout = this.player_.options_.inactivityTimeout; + this.player_.options_.inactivityTimeout = 0; + this.player_.userActive(true); + this.addClass('connected'); + this.removeClass('error'); + } + }, { + key: 'onSessionUpdate', + value: function onSessionUpdate(isAlive) { + if (!this.player_.apiMedia) { + return; + } + if (!isAlive) { + return this.onStopAppSuccess(); + } + } + }, { + key: 'stopCasting', + value: function stopCasting() { + return this.apiSession.stop(this.onStopAppSuccess.bind(this), this.castError.bind(this)); + } + }, { + key: 'onStopAppSuccess', + value: function onStopAppSuccess() { + this.casting = false; + var time = this.player_.currentTime(); + this.removeClass('connected'); + this.player_.src(this.player_.options_['sources']); + if (!this.player_.paused()) { + this.player_.one('seeked', function () { + return this.player_.play(); + }); + } + this.player_.currentTime(time); + this.player_.options_.inactivityTimeout = this.inactivityTimeout; + return this.apiSession = null; + } + + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ + }, { + key: 'buildCSSClass', + value: function buildCSSClass() { + return 'vjs-chromecast-button ' + _get(Object.getPrototypeOf(ChromeCastButton.prototype), 'buildCSSClass', this).call(this); + } + + /** + * Handle click on mute + * @method handleClick + */ + }, { + key: 'handleClick', + value: function handleClick() { + _get(Object.getPrototypeOf(ChromeCastButton.prototype), 'handleClick', this).call(this); + if (this.casting) { + return this.stopCasting(); + } else { + return this.doLaunch(); + } + } + }]); + + return ChromeCastButton; +})(Button); + +ChromeCastButton.prototype.tryingReconnect = 0; + +ChromeCastButton.prototype.inactivityTimeout = 2000; + +ChromeCastButton.prototype.controlText_ = 'Chromecast'; + +//Replace videojs CaptionButton child with this one +ControlBar.prototype.options_.children.splice(ControlBar.prototype.options_.children.length - 1, 0, 'chromeCastButton'); + +Component.registerComponent('ChromeCastButton', ChromeCastButton); +exports['default'] = ChromeCastButton; +module.exports = exports['default']; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],2:[function(require,module,exports){ +(function (global){ +/** + * @file chromecast.js + * Chromecast Media Controller - Wrapper for HTML5 Media API + */ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x2, _x3, _x4) { var _again = true; _function: while (_again) { var object = _x2, property = _x3, receiver = _x4; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x2 = parent; _x3 = property; _x4 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null); + +var _videoJs2 = _interopRequireDefault(_videoJs); + +var Component = _videoJs2['default'].getComponent('Component'); +var Tech = _videoJs2['default'].getComponent('Tech'); + +/** + * Chromecast Media Controller - Wrapper for HTML5 Media API + * + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function + * @extends Tech + * @class Chromecast + */ + +var Chromecast = (function (_Tech) { + _inherits(Chromecast, _Tech); + + function Chromecast(options, ready) { + var _this = this; + + _classCallCheck(this, Chromecast); + + _get(Object.getPrototypeOf(Chromecast.prototype), 'constructor', this).call(this, options, ready); + this.apiMedia = this.options_.source.apiMedia; + this.apiSession = this.options_.source.apiSession; + this.receiver = this.apiSession.receiver.friendlyName; + + var mediaStatusUpdateHandler = this.onMediaStatusUpdate.bind(this); + var sessionUpdateHanlder = this.onSessionUpdate.bind(this); + + this.apiMedia.addUpdateListener(mediaStatusUpdateHandler); + this.apiSession.addUpdateListener(sessionUpdateHanlder); + + this.on('dispose', function () { + _this.apiMedia.removeUpdateListener(mediaStatusUpdateHandler); + _this.apiSession.removeUpdateListener(sessionUpdateHanlder); + _this.onMediaStatusUpdate(); + _this.onSessionUpdate(false); + }); + + var tracks = this.textTracks(); + if (tracks) { + (function () { + var changeHandler = _this.handleTextTracksChange.bind(_this); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + + _this.handleTextTracksChange(); + })(); + } + + try { + tracks = this.audioTracks(); + if (tracks) { + (function () { + var changeHandler = _this.handleAudioTracksChange.bind(_this); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + })(); + } + } catch (e) { + _videoJs2['default'].log('get player audioTracks fail' + e); + } + + try { + tracks = this.videoTracks(); + if (tracks) { + (function () { + var changeHandler = _this.handleVideoTracksChange.bind(_this); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + })(); + } + } catch (e) { + _videoJs2['default'].log('get player videoTracks fail' + e); + } + + this.update(); + this.triggerReady(); + } + + _createClass(Chromecast, [{ + key: 'createEl', + value: function createEl() { + var el = _videoJs2['default'].createEl('div', { + id: this.options_.techId, + className: 'vjs-tech vjs-tech-chromecast' + }); + return el; + } + }, { + key: 'update', + value: function update() { + this.el_.innerHTML = '<div class="casting-image" style="background-image: url(\'' + this.options_.poster + '\')"></div><div class="casting-overlay"><div class="casting-information"><div class="casting-icon"></div><div class="casting-description"><small>' + this.localize('CASTING TO') + '</small><br>' + this.receiver + '</div></div></div>'; + } + }, { + key: 'onSessionUpdate', + value: function onSessionUpdate(isAlive) { + if (!this.apiMedia) { + return; + } + if (!isAlive) { + return this.onStopAppSuccess(); + } + } + }, { + key: 'onStopAppSuccess', + value: function onStopAppSuccess() { + this.stopTrackingCurrentTime(); + this.apiMedia = null; + } + }, { + key: 'onMediaStatusUpdate', + value: function onMediaStatusUpdate() { + if (!this.apiMedia) { + return; + } + switch (this.apiMedia.playerState) { + case chrome.cast.media.PlayerState.BUFFERING: + this.trigger('waiting'); + break; + case chrome.cast.media.PlayerState.IDLE: + this.trigger('timeupdate'); + break; + case chrome.cast.media.PlayerState.PAUSED: + this.trigger('pause'); + this.paused_ = true; + break; + case chrome.cast.media.PlayerState.PLAYING: + this.trigger('playing'); + this.trigger('play'); + this.paused_ = false; + break; + } + } + + /** + * Set video + * + * @param {Object=} src Source object + * @method setSrc + */ + }, { + key: 'src', + value: function src(_src) { + //do nothing + } + }, { + key: 'currentSrc', + value: function currentSrc() { + if (!this.apiMedia) { + return; + } + return this.apiMedia.media.contentId; + } + }, { + key: 'handleAudioTracksChange', + value: function handleAudioTracksChange() { + var trackInfo = []; + var tTracks = this.textTracks(); + var tracks = this.audioTracks(); + + if (!tracks) { + return; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + if (track['enabled']) { + //set id of cuurentTrack audio + trackInfo.push(i + 1 + tTracks.length); + } + } + + if (this.apiMedia && trackInfo.length) { + this.tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(trackInfo); + return this.apiMedia.editTracksInfo(this.tracksInfoRequest, this.onTrackSuccess.bind(this), this.onTrackError.bind(this)); + } + } + }, { + key: 'handleVideoTracksChange', + value: function handleVideoTracksChange() {} + }, { + key: 'handleTextTracksChange', + value: function handleTextTracksChange() { + var trackInfo = []; + var tracks = this.textTracks(); + + if (!tracks) { + return; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + if (track['mode'] === 'showing') { + trackInfo.push(i + 1); + } + } + + if (this.apiMedia && trackInfo.length) { + this.tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(trackInfo); + return this.apiMedia.editTracksInfo(this.tracksInfoRequest, this.onTrackSuccess.bind(this), this.onTrackError.bind(this)); + } + } + }, { + key: 'onTrackSuccess', + value: function onTrackSuccess() { + return _videoJs2['default'].log('track added'); + } + }, { + key: 'onTrackError', + value: function onTrackError(e) { + return _videoJs2['default'].log('Cast track Error: ' + JSON.stringify(e)); + } + }, { + key: 'castError', + value: function castError(e) { + return _videoJs2['default'].log('Cast Error: ' + JSON.stringify(e)); + } + }, { + key: 'play', + value: function play() { + if (!this.apiMedia) { + return; + } + if (this.paused_) { + this.apiMedia.play(null, this.mediaCommandSuccessCallback.bind(this, 'Playing: ' + this.apiMedia.sessionId), this.castError.bind(this)); + } + return this.paused_ = false; + } + }, { + key: 'pause', + value: function pause() { + if (!this.apiMedia) { + return; + } + if (!this.paused_) { + this.apiMedia.pause(null, this.mediaCommandSuccessCallback.bind(this, 'Paused: ' + this.apiMedia.sessionId), this.castError.bind(this)); + return this.paused_ = true; + } + } + }, { + key: 'paused', + value: function paused() { + return this.paused_; + } + }, { + key: 'currentTime', + value: function currentTime() { + if (!this.apiMedia) { + return 0; + } + return this.apiMedia.getEstimatedTime(); + } + }, { + key: 'setCurrentTime', + value: function setCurrentTime(position) { + + if (!this.apiMedia) { + return 0; + } + var request = undefined; + request = new chrome.cast.media.SeekRequest(); + request.currentTime = position; + //if (this.player_.controlBar.progressControl.seekBar.videoWasPlaying) { + // request.resumeState = chrome.cast.media.ResumeState.PLAYBACK_START; + //} + return this.apiMedia.seek(request, this.onSeekSuccess.bind(this, position), this.castError.bind(this)); + } + }, { + key: 'onSeekSuccess', + value: function onSeekSuccess(position) { + _videoJs2['default'].log('seek success' + position); + } + }, { + key: 'volume', + value: function volume() { + return this.volume_; + } + }, { + key: 'duration', + value: function duration() { + if (!this.apiMedia) { + return 0; + } + return this.apiMedia.media.duration || Infinity; + } + }, { + key: 'controls', + value: function controls() { + return false; + } + }, { + key: 'setVolume', + value: function setVolume(level) { + var mute = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + + var request = undefined; + var volume = undefined; + if (!this.apiMedia) { + return; + } + volume = new chrome.cast.Volume(); + volume.level = level; + volume.muted = mute; + this.volume_ = volume.level; + this.muted_ = mute; + request = new chrome.cast.media.VolumeRequest(); + request.volume = volume; + this.apiMedia.setVolume(request, this.mediaCommandSuccessCallback.bind(this, 'Volume changed'), this.castError.bind(this)); + return this.trigger('volumechange'); + } + }, { + key: 'mediaCommandSuccessCallback', + value: function mediaCommandSuccessCallback(information) { + _videoJs2['default'].log(information); + } + }, { + key: 'muted', + value: function muted() { + return this.muted_; + } + }, { + key: 'setMuted', + value: function setMuted(muted) { + return this.setVolume(this.volume_, muted); + } + }, { + key: 'supportsFullScreen', + value: function supportsFullScreen() { + return false; + } + }, { + key: 'resetSrc_', + value: function resetSrc_(callback) { + callback(); + } + }, { + key: 'dispose', + value: function dispose() { + this.resetSrc_(Function.prototype); + _get(Object.getPrototypeOf(Chromecast.prototype), 'dispose', this).call(this, this); + } + }]); + + return Chromecast; +})(Tech); + +Chromecast.prototype.paused_ = false; + +Chromecast.prototype.options_ = {}; + +Chromecast.prototype.timerStep = 1000; + +/* Chromecast Support Testing -------------------------------------------------------- */ + +Chromecast.isSupported = function () { + return true; +}; + +// Add Source Handler pattern functions to this tech +Tech.withSourceHandlers(Chromecast); + +/* + * The default native source handler. + * This simply passes the source to the video element. Nothing fancy. + * + * @param {Object} source The source object + * @param {Flash} tech The instance of the Flash tech + */ +Chromecast.nativeSourceHandler = {}; + +/** + * Check if Flash can play the given videotype + * @param {String} type The mimetype to check + * @return {String} 'probably', 'maybe', or '' (empty string) + */ +Chromecast.nativeSourceHandler.canPlayType = function (source) { + + var dashTypeRE = /^application\/(?:dash\+xml|(x-|vnd\.apple\.)mpegurl)/i; + var dashExtRE = /^video\/(mpd|mp4|webm|m3u8)/i; + + if (dashTypeRE.test(source)) { + return 'probably'; + } else if (dashExtRE.test(source)) { + return 'maybe'; + } else { + return ''; + } +}; + +/* + * Check Flash can handle the source natively + * + * @param {Object} source The source object + * @return {String} 'probably', 'maybe', or '' (empty string) + */ +Chromecast.nativeSourceHandler.canHandleSource = function (source) { + + // If a type was provided we should rely on that + if (source.type) { + return Chromecast.nativeSourceHandler.canPlayType(source.type); + } else if (source.src) { + return Chromecast.nativeSourceHandler.canPlayType(source.src); + } + + return ''; +}; + +/* + * Pass the source to the flash object + * Adaptive source handlers will have more complicated workflows before passing + * video data to the video element + * + * @param {Object} source The source object + * @param {Flash} tech The instance of the Flash tech + */ +Chromecast.nativeSourceHandler.handleSource = function (source, tech) { + tech.src(source.src); +}; + +/* + * Clean up the source handler when disposing the player or switching sources.. + * (no cleanup is needed when supporting the format natively) + */ +Chromecast.nativeSourceHandler.dispose = function () {}; + +// Register the native source handler +Chromecast.registerSourceHandler(Chromecast.nativeSourceHandler); + +/* + * Set the tech's volume control support status + * + * @type {Boolean} + */ +Chromecast.prototype['featuresVolumeControl'] = true; + +/* + * Set the tech's playbackRate support status + * + * @type {Boolean} + */ +Chromecast.prototype['featuresPlaybackRate'] = false; + +/* + * Set the tech's status on moving the video element. + * In iOS, if you move a video element in the DOM, it breaks video playback. + * + * @type {Boolean} + */ +Chromecast.prototype['movingMediaElementInDOM'] = false; + +/* + * Set the the tech's fullscreen resize support status. + * HTML video is able to automatically resize when going to fullscreen. + * (No longer appears to be used. Can probably be removed.) + */ +Chromecast.prototype['featuresFullscreenResize'] = false; + +/* + * Set the tech's timeupdate event support status + * (this disables the manual timeupdate events of the Tech) + */ +Chromecast.prototype['featuresTimeupdateEvents'] = false; + +/* + * Set the tech's progress event support status + * (this disables the manual progress events of the Tech) + */ +Chromecast.prototype['featuresProgressEvents'] = false; + +/* + * Sets the tech's status on native text track support + * + * @type {Boolean} + */ +Chromecast.prototype['featuresNativeTextTracks'] = true; + +/* + * Sets the tech's status on native audio track support + * + * @type {Boolean} + */ +Chromecast.prototype['featuresNativeAudioTracks'] = true; + +/* + * Sets the tech's status on native video track support + * + * @type {Boolean} + */ +Chromecast.prototype['featuresNativeVideoTracks'] = false; + +_videoJs2['default'].options.chromecast = {}; + +Component.registerComponent('Chromecast', Chromecast); +Tech.registerTech('Chromecast', Chromecast); +exports['default'] = Chromecast; +module.exports = exports['default']; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],3:[function(require,module,exports){ +(function (global){ +/** + * ! videojs-chromecast - v1.0.0 - 2016-02-15 + * Copyright (c) 2015 benjipott + * Licensed under the Apache-2.0 license. + * @file videojs-chromecast.js + **/ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null); + +var _videoJs2 = _interopRequireDefault(_videoJs); + +var _componentControlBarChromecastButton = require('./component/control-bar/chromecast-button'); + +var _componentControlBarChromecastButton2 = _interopRequireDefault(_componentControlBarChromecastButton); + +var _techChromecast = require('./tech/chromecast'); + +var _techChromecast2 = _interopRequireDefault(_techChromecast); + +var Component = _videoJs2['default'].getComponent('Component'); + +/** + * Initialize the plugin. + * @param options (optional) {object} configuration for the plugin + */ + +var Chromecast = (function (_Component) { + _inherits(Chromecast, _Component); + + function Chromecast(player, options) { + _classCallCheck(this, Chromecast); + + _get(Object.getPrototypeOf(Chromecast.prototype), 'constructor', this).call(this, player, options); + } + + return Chromecast; +})(Component); + +Chromecast.prototype.options_ = {}; + +// register the plugin +_videoJs2['default'].options.children.push('chromecast'); + +_videoJs2['default'].addLanguage('en', { + 'CASTING TO': 'WIEDERGABE AUF' +}); + +_videoJs2['default'].addLanguage('de', { + 'CASTING TO': 'WIEDERGABE AUF' +}); + +_videoJs2['default'].addLanguage('it', { + 'CASTING TO': 'PLAYBACK SU' +}); + +_videoJs2['default'].addLanguage('fr', { + 'CASTING TO': 'CAST EN COURS SUR' +}); + +var USER_AGENT = window.navigator.userAgent; + +_videoJs2['default'].browser.IS_EDGE = /Edge/i.test(USER_AGENT); + +Component.registerComponent('Chromecast', Chromecast); +exports['default'] = Chromecast; +module.exports = exports['default']; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./component/control-bar/chromecast-button":1,"./tech/chromecast":2}],4:[function(require,module,exports){ +(function (global){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null); + +var _videoJs2 = _interopRequireDefault(_videoJs); + +var _videojsChromecast = require('./videojs-chromecast'); + +var _videojsChromecast2 = _interopRequireDefault(_videojsChromecast); + +/** + * The video.js playlist plugin. Invokes the playlist-maker to create a + * playlist function on the specific player. + * + * @param {Array} list + */ +var plugin = function plugin(options) { + var player = this; + player.addChild('Chromecast', options); +}; + +_videoJs2['default'].plugin('chromecast', plugin); + +exports['default'] = plugin; +module.exports = exports['default']; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./videojs-chromecast":3}]},{},[4])(4) +});
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.min.js b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.min.js new file mode 100644 index 0000000000..43de3967b2 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/plugins/videojs-chromecast/videojs-chromecast.min.js @@ -0,0 +1,7 @@ +/** + * videojs-chromecast + * @version 2.0.8 + * @copyright 2016 Benjipott, Inc. + * @license Apache-2.0 + */ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,(t.video||(t.video={})).jsChromecast=e()}}(function(){return function e(t,i,o){function n(r,s){if(!i[r]){if(!t[r]){var c="function"==typeof require&&require;if(!s&&c)return c(r,!0);if(a)return a(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[r]={exports:{}};t[r][0].call(d.exports,function(e){var i=t[r][1][e];return n(i?i:e)},d,d.exports,e,t,i,o)}return i[r].exports}for(var a="function"==typeof require&&require,r=0;r<o.length;r++)n(o[r]);return n}({1:[function(e,t,i){(function(e){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var r=function(){function e(e,t){for(var i=0;i<t.length;i++){var o=t[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,i,o){return i&&e(t.prototype,i),o&&e(t,o),t}}(),s=function(e,t,i){for(var o=!0;o;){var n=e,a=t,r=i;o=!1,null===n&&(n=Function.prototype);var s=Object.getOwnPropertyDescriptor(n,a);if(void 0!==s){if("value"in s)return s.value;var c=s.get;if(void 0===c)return;return c.call(r)}var u=Object.getPrototypeOf(n);if(null===u)return;e=u,t=a,i=r,o=!0,s=u=void 0}},c="undefined"!=typeof window?window.videojs:"undefined"!=typeof e?e.videojs:null,u=o(c),d=u["default"].getComponent("Component"),l=u["default"].getComponent("ControlBar"),p=u["default"].getComponent("Button"),h=function(e){function t(e,i){n(this,t),s(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e,i),this.hide(),this.initializeApi(),i.appId=e.options_.chromecast.appId,e.chromecast=this}return a(t,e),r(t,[{key:"initializeApi",value:function(){var e=void 0,t=void 0,i=void 0;return u["default"].browser.IS_CHROME&&!u["default"].browser.IS_EDGE?chrome.cast&&chrome.cast.isAvailable?(u["default"].log("Cast APIs are available"),t=this.options_.appId||chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,i=new chrome.cast.SessionRequest(t),e=new chrome.cast.ApiConfig(i,this.sessionJoinedListener.bind(this),this.receiverListener.bind(this)),chrome.cast.initialize(e,this.onInitSuccess.bind(this),this.castError.bind(this))):(u["default"].log("Cast APIs not available"),this.tryingReconnect<10&&(this.setTimeout(this.initializeApi,1e3),++this.tryingReconnect),void u["default"].log("Cast APIs not available. Max reconnect attempt")):void 0}},{key:"castError",value:function(e){var t={code:e.code,message:e.description};switch(e.code){case chrome.cast.ErrorCode.API_NOT_INITIALIZED:case chrome.cast.ErrorCode.EXTENSION_MISSING:case chrome.cast.ErrorCode.EXTENSION_NOT_COMPATIBLE:case chrome.cast.ErrorCode.INVALID_PARAMETER:case chrome.cast.ErrorCode.LOAD_MEDIA_FAILED:case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:case chrome.cast.ErrorCode.SESSION_ERROR:case chrome.cast.ErrorCode.CHANNEL_ERROR:case chrome.cast.ErrorCode.TIMEOUT:this.addClass("error");break;case chrome.cast.ErrorCode.CANCEL:break;default:this.player_.error(t)}return u["default"].log("Cast Error: "+JSON.stringify(e))}},{key:"onInitSuccess",value:function(){return this.apiInitialized=!0}},{key:"sessionJoinedListener",value:function(e){return e.media.length&&(this.apiSession=e,this.onMediaDiscovered(e.media[0])),console.log("Session joined")}},{key:"receiverListener",value:function(e){return"available"===e?this.show():void 0}},{key:"doLaunch",value:function(){return u["default"].log("Cast video: "+this.player_.cache_.src),this.apiInitialized?chrome.cast.requestSession(this.onSessionSuccess.bind(this),this.castError.bind(this)):u["default"].log("Session not initialized")}},{key:"onSessionSuccess",value:function(e){var t=void 0,i=void 0,o=void 0,n=void 0,a=void 0,r=void 0;this.apiSession=e;var s=this.player_.cache_.src,c=this.player_.currentType();if(u["default"].log("Session initialized: "+e.sessionId+" source : "+s+" type : "+c),n=new chrome.cast.media.MediaInfo(s,c),n.metadata=new chrome.cast.media.GenericMediaMetadata,this.options_.metadata){a=this.options_.metadata;for(i in a)r=a[i],n.metadata[i]=r}var d=this.player().poster();d&&(t=new chrome.cast.Image(d),n.metadata.images=[t]);var l=this.player().textTracks(),p=this.player().remoteTextTrackEls(),h=[],f=0,v=void 0,y=void 0,m=0,g=void 0;if(l){for(f=0;f<l.length;f++)y=l.tracks_[f],v=p&&p.trackElements_&&p.trackElements_[f],m++,g=new chrome.cast.media.Track(m,chrome.cast.media.TrackType.TEXT),g.trackContentId=v?v.src:"caption_"+y.language,g.subtype=chrome.cast.media.TextTrackType.CAPTIONS,g.name=y.label,g.language=y.language,g.customData=null,h.push(g);n.textTrackStyle=new chrome.cast.media.TextTrackStyle,n.textTrackStyle.foregroundColor="#FFFFFF",n.textTrackStyle.backgroundColor="#00000060",n.textTrackStyle.edgeType=chrome.cast.media.TextTrackEdgeType.DROP_SHADOW,n.textTrackStyle.windowType=chrome.cast.media.TextTrackWindowType.ROUNDED_CORNERS}try{if(l=this.player().audioTracks())for(f=0;f<l.length;f++)y=l.tracks_[f],m++,g=new chrome.cast.media.Track(m,chrome.cast.media.TrackType.AUDIO),g.subtype=null,g.name=y.label,g.language=y.language,g.customData=null,h.push(g)}catch(b){u["default"].log("get player audioTracks fail"+b)}h.length&&(n.tracks=h),o=new chrome.cast.media.LoadRequest(n),o.autoplay=!0,o.currentTime=this.player_.currentTime(),this.apiSession.loadMedia(o,this.onMediaDiscovered.bind(this),this.castError.bind(this)),this.apiSession.addUpdateListener(this.onSessionUpdate.bind(this))}},{key:"onMediaDiscovered",value:function(e){this.player_.loadTech_("Chromecast",{type:"cast",apiMedia:e,apiSession:this.apiSession}),this.casting=!0,this.inactivityTimeout=this.player_.options_.inactivityTimeout,this.player_.options_.inactivityTimeout=0,this.player_.userActive(!0),this.addClass("connected"),this.removeClass("error")}},{key:"onSessionUpdate",value:function(e){return this.player_.apiMedia?e?void 0:this.onStopAppSuccess():void 0}},{key:"stopCasting",value:function(){return this.apiSession.stop(this.onStopAppSuccess.bind(this),this.castError.bind(this))}},{key:"onStopAppSuccess",value:function(){this.casting=!1;var e=this.player_.currentTime();return this.removeClass("connected"),this.player_.src(this.player_.options_.sources),this.player_.paused()||this.player_.one("seeked",function(){return this.player_.play()}),this.player_.currentTime(e),this.player_.options_.inactivityTimeout=this.inactivityTimeout,this.apiSession=null}},{key:"buildCSSClass",value:function(){return"vjs-chromecast-button "+s(Object.getPrototypeOf(t.prototype),"buildCSSClass",this).call(this)}},{key:"handleClick",value:function(){return s(Object.getPrototypeOf(t.prototype),"handleClick",this).call(this),this.casting?this.stopCasting():this.doLaunch()}}]),t}(p);h.prototype.tryingReconnect=0,h.prototype.inactivityTimeout=2e3,h.prototype.controlText_="Chromecast",l.prototype.options_.children.splice(l.prototype.options_.children.length-1,0,"chromeCastButton"),d.registerComponent("ChromeCastButton",h),i["default"]=h,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(e,t,i){(function(e){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var r=function(){function e(e,t){for(var i=0;i<t.length;i++){var o=t[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,i,o){return i&&e(t.prototype,i),o&&e(t,o),t}}(),s=function(e,t,i){for(var o=!0;o;){var n=e,a=t,r=i;o=!1,null===n&&(n=Function.prototype);var s=Object.getOwnPropertyDescriptor(n,a);if(void 0!==s){if("value"in s)return s.value;var c=s.get;if(void 0===c)return;return c.call(r)}var u=Object.getPrototypeOf(n);if(null===u)return;e=u,t=a,i=r,o=!0,s=u=void 0}},c="undefined"!=typeof window?window.videojs:"undefined"!=typeof e?e.videojs:null,u=o(c),d=u["default"].getComponent("Component"),l=u["default"].getComponent("Tech"),p=function(e){function t(e,i){var o=this;n(this,t),s(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e,i),this.apiMedia=this.options_.source.apiMedia,this.apiSession=this.options_.source.apiSession,this.receiver=this.apiSession.receiver.friendlyName;var a=this.onMediaStatusUpdate.bind(this),r=this.onSessionUpdate.bind(this);this.apiMedia.addUpdateListener(a),this.apiSession.addUpdateListener(r),this.on("dispose",function(){o.apiMedia.removeUpdateListener(a),o.apiSession.removeUpdateListener(r),o.onMediaStatusUpdate(),o.onSessionUpdate(!1)});var c=this.textTracks();c&&!function(){var e=o.handleTextTracksChange.bind(o);c.addEventListener("change",e),o.on("dispose",function(){c.removeEventListener("change",e)}),o.handleTextTracksChange()}();try{c=this.audioTracks(),c&&!function(){var e=o.handleAudioTracksChange.bind(o);c.addEventListener("change",e),o.on("dispose",function(){c.removeEventListener("change",e)})}()}catch(d){u["default"].log("get player audioTracks fail"+d)}try{c=this.videoTracks(),c&&!function(){var e=o.handleVideoTracksChange.bind(o);c.addEventListener("change",e),o.on("dispose",function(){c.removeEventListener("change",e)})}()}catch(d){u["default"].log("get player videoTracks fail"+d)}this.update(),this.triggerReady()}return a(t,e),r(t,[{key:"createEl",value:function(){var e=u["default"].createEl("div",{id:this.options_.techId,className:"vjs-tech vjs-tech-chromecast"});return e}},{key:"update",value:function(){this.el_.innerHTML='<div class="casting-image" style="background-image: url(\''+this.options_.poster+'\')"></div><div class="casting-overlay"><div class="casting-information"><div class="casting-icon"></div><div class="casting-description"><small>'+this.localize("CASTING TO")+"</small><br>"+this.receiver+"</div></div></div>"}},{key:"onSessionUpdate",value:function(e){return this.apiMedia?e?void 0:this.onStopAppSuccess():void 0}},{key:"onStopAppSuccess",value:function(){this.stopTrackingCurrentTime(),this.apiMedia=null}},{key:"onMediaStatusUpdate",value:function(){if(this.apiMedia)switch(this.apiMedia.playerState){case chrome.cast.media.PlayerState.BUFFERING:this.trigger("waiting");break;case chrome.cast.media.PlayerState.IDLE:this.trigger("timeupdate");break;case chrome.cast.media.PlayerState.PAUSED:this.trigger("pause"),this.paused_=!0;break;case chrome.cast.media.PlayerState.PLAYING:this.trigger("playing"),this.trigger("play"),this.paused_=!1}}},{key:"src",value:function(e){}},{key:"currentSrc",value:function(){return this.apiMedia?this.apiMedia.media.contentId:void 0}},{key:"handleAudioTracksChange",value:function(){var e=[],t=this.textTracks(),i=this.audioTracks();if(i){for(var o=0;o<i.length;o++){var n=i[o];n.enabled&&e.push(o+1+t.length)}return this.apiMedia&&e.length?(this.tracksInfoRequest=new chrome.cast.media.EditTracksInfoRequest(e),this.apiMedia.editTracksInfo(this.tracksInfoRequest,this.onTrackSuccess.bind(this),this.onTrackError.bind(this))):void 0}}},{key:"handleVideoTracksChange",value:function(){}},{key:"handleTextTracksChange",value:function(){var e=[],t=this.textTracks();if(t){for(var i=0;i<t.length;i++){var o=t[i];"showing"===o.mode&&e.push(i+1)}return this.apiMedia&&e.length?(this.tracksInfoRequest=new chrome.cast.media.EditTracksInfoRequest(e),this.apiMedia.editTracksInfo(this.tracksInfoRequest,this.onTrackSuccess.bind(this),this.onTrackError.bind(this))):void 0}}},{key:"onTrackSuccess",value:function(){return u["default"].log("track added")}},{key:"onTrackError",value:function(e){return u["default"].log("Cast track Error: "+JSON.stringify(e))}},{key:"castError",value:function(e){return u["default"].log("Cast Error: "+JSON.stringify(e))}},{key:"play",value:function(){return this.apiMedia?(this.paused_&&this.apiMedia.play(null,this.mediaCommandSuccessCallback.bind(this,"Playing: "+this.apiMedia.sessionId),this.castError.bind(this)),this.paused_=!1):void 0}},{key:"pause",value:function(){return this.apiMedia?this.paused_?void 0:(this.apiMedia.pause(null,this.mediaCommandSuccessCallback.bind(this,"Paused: "+this.apiMedia.sessionId),this.castError.bind(this)),this.paused_=!0):void 0}},{key:"paused",value:function(){return this.paused_}},{key:"currentTime",value:function(){return this.apiMedia?this.apiMedia.getEstimatedTime():0}},{key:"setCurrentTime",value:function(e){if(!this.apiMedia)return 0;var t=void 0;return t=new chrome.cast.media.SeekRequest,t.currentTime=e,this.apiMedia.seek(t,this.onSeekSuccess.bind(this,e),this.castError.bind(this))}},{key:"onSeekSuccess",value:function(e){u["default"].log("seek success"+e)}},{key:"volume",value:function(){return this.volume_}},{key:"duration",value:function(){return this.apiMedia?this.apiMedia.media.duration||1/0:0}},{key:"controls",value:function(){return!1}},{key:"setVolume",value:function(e){var t=arguments.length<=1||void 0===arguments[1]?!1:arguments[1],i=void 0,o=void 0;return this.apiMedia?(o=new chrome.cast.Volume,o.level=e,o.muted=t,this.volume_=o.level,this.muted_=t,i=new chrome.cast.media.VolumeRequest,i.volume=o,this.apiMedia.setVolume(i,this.mediaCommandSuccessCallback.bind(this,"Volume changed"),this.castError.bind(this)),this.trigger("volumechange")):void 0}},{key:"mediaCommandSuccessCallback",value:function(e){u["default"].log(e)}},{key:"muted",value:function(){return this.muted_}},{key:"setMuted",value:function(e){return this.setVolume(this.volume_,e)}},{key:"supportsFullScreen",value:function(){return!1}},{key:"resetSrc_",value:function(e){e()}},{key:"dispose",value:function(){this.resetSrc_(Function.prototype),s(Object.getPrototypeOf(t.prototype),"dispose",this).call(this,this)}}]),t}(l);p.prototype.paused_=!1,p.prototype.options_={},p.prototype.timerStep=1e3,p.isSupported=function(){return!0},l.withSourceHandlers(p),p.nativeSourceHandler={},p.nativeSourceHandler.canPlayType=function(e){var t=/^application\/(?:dash\+xml|(x-|vnd\.apple\.)mpegurl)/i,i=/^video\/(mpd|mp4|webm|m3u8)/i;return t.test(e)?"probably":i.test(e)?"maybe":""},p.nativeSourceHandler.canHandleSource=function(e){return e.type?p.nativeSourceHandler.canPlayType(e.type):e.src?p.nativeSourceHandler.canPlayType(e.src):""},p.nativeSourceHandler.handleSource=function(e,t){t.src(e.src)},p.nativeSourceHandler.dispose=function(){},p.registerSourceHandler(p.nativeSourceHandler),p.prototype.featuresVolumeControl=!0,p.prototype.featuresPlaybackRate=!1,p.prototype.movingMediaElementInDOM=!1,p.prototype.featuresFullscreenResize=!1,p.prototype.featuresTimeupdateEvents=!1,p.prototype.featuresProgressEvents=!1,p.prototype.featuresNativeTextTracks=!0,p.prototype.featuresNativeAudioTracks=!0,p.prototype.featuresNativeVideoTracks=!1,u["default"].options.chromecast={},d.registerComponent("Chromecast",p),l.registerTech("Chromecast",p),i["default"]=p,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(e,t,i){(function(o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var s=function(e,t,i){for(var o=!0;o;){var n=e,a=t,r=i;o=!1,null===n&&(n=Function.prototype);var s=Object.getOwnPropertyDescriptor(n,a);if(void 0!==s){if("value"in s)return s.value;var c=s.get;if(void 0===c)return;return c.call(r)}var u=Object.getPrototypeOf(n);if(null===u)return;e=u,t=a,i=r,o=!0,s=u=void 0}},c="undefined"!=typeof window?window.videojs:"undefined"!=typeof o?o.videojs:null,u=n(c),d=e("./component/control-bar/chromecast-button"),l=(n(d),e("./tech/chromecast")),p=(n(l),u["default"].getComponent("Component")),h=function(e){function t(e,i){a(this,t),s(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e,i)}return r(t,e),t}(p);h.prototype.options_={},u["default"].options.children.push("chromecast"),u["default"].addLanguage("en",{"CASTING TO":"WIEDERGABE AUF"}),u["default"].addLanguage("de",{"CASTING TO":"WIEDERGABE AUF"}),u["default"].addLanguage("it",{"CASTING TO":"PLAYBACK SU"}),u["default"].addLanguage("fr",{"CASTING TO":"CAST EN COURS SUR"});var f=window.navigator.userAgent;u["default"].browser.IS_EDGE=/Edge/i.test(f),p.registerComponent("Chromecast",h),i["default"]=h,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./component/control-bar/chromecast-button":1,"./tech/chromecast":2}],4:[function(e,t,i){(function(o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(i,"__esModule",{value:!0});var a="undefined"!=typeof window?window.videojs:"undefined"!=typeof o?o.videojs:null,r=n(a),s=e("./videojs-chromecast"),c=(n(s),function(e){var t=this;t.addChild("Chromecast",e)});r["default"].plugin("chromecast",c),i["default"]=c,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./videojs-chromecast":3}]},{},[4])(4)});
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/video-js.css b/addons/webinterface.default/lib/video-js/video-js.css new file mode 100644 index 0000000000..493e55a6c1 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/video-js.css @@ -0,0 +1,1307 @@ +.video-js .vjs-big-play-button:before, .video-js .vjs-control:before, .video-js .vjs-modal-dialog, .vjs-modal-dialog .vjs-modal-dialog-content { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + +.video-js .vjs-big-play-button:before, .video-js .vjs-control:before { + text-align: center; } + +@font-face { + font-family: VideoJS; + src: url("font/VideoJS.eot?#iefix") format("eot"); } + +@font-face { + font-family: VideoJS; + src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAA54AAoAAAAAFmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAAA9AAAAD4AAABWUZFeBWNtYXAAAAE0AAAAOgAAAUriMBC2Z2x5ZgAAAXAAAAouAAAPUFvx6AdoZWFkAAALoAAAACsAAAA2DIPpX2hoZWEAAAvMAAAAGAAAACQOogcgaG10eAAAC+QAAAAPAAAAfNkAAABsb2NhAAAL9AAAAEAAAABAMMg06m1heHAAAAw0AAAAHwAAACABMAB5bmFtZQAADFQAAAElAAACCtXH9aBwb3N0AAANfAAAAPwAAAGBZkSN43icY2BkZ2CcwMDKwMFSyPKMgYHhF4RmjmEIZzzHwMDEwMrMgBUEpLmmMDh8ZPwoxw7iLmSHCDOCCADvEAo+AAB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZgYGD7K/f8PUvCREUTzM0DVAwEjG8OIBwCPdwbVAAB4nI1Xe1CU1xX/zv1eLItLln0JwrIfC7sJGET2hRJ2N1GUoBJE8AESQEEhmBHjaB7UuBMTO4GMaSu7aY3RNlOdRPNqO2pqRmuTaSZtR6JJILUZk00a/4imjpmiecB303O/XUgMJOPufvd+99xzzz33nN855y4HHH7EfrGfIxwHRiANvF/sH71I9BzHszmpW+rGOQOXxXE6YhI4PoMT8zkT4cDFuf1cwMrZJI5cglM0HKVv0MaUFDgIFfg9mJJCG+kbKn1JkqBOVaFOkuhLpARq8fu0Nnc9/zdvfY9PxXW4PdH0C6N+PCejhorxFjAqRjgFRXSINEARbBGsoxcFK7IJmr4OycFJnInL59zIXwxui80fkGRbEHyosMWaATJKUfCskmwJQsAWANkmnIGOhlf514h7U8HNIv3owoHB0WMt0Eb3sx0guLi5pq/8Ny1q6969fKR9X9GBV6dPv6dp04K99SOwtmyPl47ApRa6n4ZpP1yjr5fn7MmYP/vXLUJs715UguklHBaHOZHZmG1N9FAIW2mf0MqWCIdo/8RZ1yGfxKUldDcGIbFA7ICO+vqOMSPTh/ZrSqgHi/bB/O8E8Mnzp+M+acxfpsTShBwej26TiGxBn7m4eEIO+Rueu6Hj+IFBnh88cAEUEQ//nVLx5C7kf+yIR47QEe+eMlhz9SqsGbe3hh2R03NGzoY6O42Kz8l7fB6fAk6LYnTyFo/FYyT6GGyNx2Jx2sdH4rA1Fo/HyCXaFyOp8dhYBCfJb2NIn1ImE6CYNGmgSTb52DawJR6jfXEmDU4xyTEmpgHHOIStoxfjSGdkbsK2w2jbdMQG4sgAstEONgURYCwGHhEhhscioQaAhhCf7McifEQc0l6+mxj9nI+gmSdiQ0Zbm7gZnIO7GSMEXG6UDAVocxAV8GcEXCKg1a02RcTtwANWRGIAyElor6n/+ZU2yOB3+T77Hb1MLqhn4KHVnQBjJnqe9QZSon6Kc5DxAD2vMdPL/BXSmQGwspa67z9wLUjdi9TN7QC7lyyBr9rpt7uXVC1CMpyjKRoXnGPHTuiaPLsNdc2dbAFQLAooPkXEh33FodHl4XpC6sPCIa0ftUIhHSYXVSu5iME+DIXsbZJ51BeidCgajcai43jU9nVzoSn2dPqcFvSoxSzJzgRKAx47WMRxOrIj3Wf0+hndxhJTiOkSEqxar3b3RKM9hY64oxBA64ieURLvCfpkDb8siBdUJ1bgT+urJ5PGfewQrmm5R5+0HmfyIPySD7OYkT0WxRePah8oEiyjlxIP74thVoRTURpmL6QhGuWS+QDjdANXjIM8SQa/1w128ODx0Qp4aLMNg9+JL3joUn8AMxW+aLNiuKjarn4uyyTdXjOzZTsh21uwldUvJoYza+zELALfu3p1L8/3krtyZ0Ag058J3hxHghvbGZn0dHZy6Mim/7Blre4lpHd1c28yVqRViO153F2oIWoXCIKbL4Z0cM1iaQn9mI5KuV2SzEvWXJDMNtkANpMdQoDDhIdD4A/YrP6Aye9ysxyE+uOEAcTDorgvVZJjcua043PnZ/PmdDqcbibZlXOOT8uSo7Kof0YUn9GL+Jo17ficymxiTofC6znUso0DhAxs1Fo+kF+d36vLmgZ8mk5cdGv2mwYj5k3Dm9m3LhJ1aVRNm6HrTbLgYAoWXDhDd/u4PGy5CT+xGMdiaBovewUCF/1BiWNljI9MLn7jeScpg+WyH6mfU62eVDql7hsrmvx1ezp/YldE2LhjbkiDnAn8tGy/MW3IXRMYJduvq9HpmIcKuFt+JCtgdGEGKAcF6UacVwIYbVPGfw/+YuNBS4cx/CUHcnyfc+wRDMtTr72mMSBjT/yn/GKSdeDWQUCH6Xoqq5R10RE60gV6erUL0iCti16d0hZjxut4QI/rEpgSh6WjnJXdBXRg1GKCucGJPtFqM27aD1tOqqKonsQ2KsFSSmEpmvRlsR+TcD9OFwrqXxIclL4sJTnGMSuG8KpkZvKdeVIOKDyWSyPLV16/p1QMPbP8NihwUzr47bdnXtwtjdCvqqpO0H+pOvIl3Pzv46e5CT/tQjklXCXXym1AaWY7bzHLkuDMc7ldKCvgxzLn8wYkJLBhEDyK7MT8bTbwbkxbfp+3mKAGsmTBpabSIEECzMIcQlzOPAMKsxMs7uhsnxPLuofPDTc1hkuq6MX9j16YU7CqegcYHbmWYuvAP6tCS97tgWf7dlQvnl25YPavXLVZvrzQPeHCpZmzzEUVq/xzu5sChnSTPTW7oOYmh69z4zL/gk3b+O6hoa733uviP82vnFcbqWlc9tDmZa23LVzaV1yXURi+JX+28NeBuj3+O8IrQ080Vm1eWB4OKjPmrJu7c1udWynvKF6/vs479lSW9+5gZkn+dKfellNGDPllzeULustz+A0bPvhgw7lkvEUwn/N4Ty7U7nhGsEpFkOfy+kutbOh1JQxhVDJumoW11hnkPThznh6FFlhfT+ra1x9sF56kx5YuDzVY9PQYAYA7iblw4frQ4TPCk2MK/xGU3rlmze62trHz6lsko+v+So/do74PT8KVkpJfOErKcv8znrMGsHTNxoEkWy1mYgDB6XBbPaWsuiS6CryGaL6zCjaXBgvtkuyXBua1wOKnh+k7L9AvPnYWffxK18FcJbuosGf3/Jo7amY+CE1vppzY+UTrva0FXc1i55pKQ/YjVL187N5fCn1kW5uot/1hi+DiZ+5atnJR9E+prvydJ9ZZ5mwOpU5gM4KYysMBQ71UzPuMTl9QQOyUo5nwioeYCPjFklrbK6s6X+ypUZ6rum9+CZYzWRiBJfSP0xzzSmrg7f86g0DKVj/wwFzieD9rRfPGFbeKMl05pn5j9/rsQJJ2iEgRrpohlyBo3f4QK7Kl+EcAYZgAoNVmZWXK704YAa3FwBxgSGUOs5htvGRz4Sgj3yFkSJFBuv/sxu5yk998T8WDJzvv/2RX19HtTUW1S+wpKRKRjJ6zzz/1/OPdFdWGlAKbvzS4PHOtURikg9AGz0LbIB85S/cPOpoXvuue8/iV2H1vPTy3ddvOeZ37HGmO3OmSzVzR+NS53+84dHlFhXPLqtzSO+5ruHM2vXtBdxP87LOzKAD359j/INYIbyPabIi3Cq6Wa+SaGe78diIzu7qcblcAa6/fJRvNopXFJnO+U9KKM5bqH5LM0iQSVmpPCPDu7ZT4Aoubz3709EBTyrTDjyx8MQXgUH1nqm7TWng4TzE4i4AsKskBITXfSyC4Fkl5MxnJDiKSIDSJAsGvd1y+/eNDp2e+A+5d8HeiiunrTkT6TqWLIs+/QRoWr98s0qj8uuzLuS22Ytufg3rdTaHn1m46sfgGKHXt0MGnLaRHdnwN37tvHcWKo2V6lnPxL4UvUQcRdOzmZSQs8X5CH5OxXMXpkATuDz8Et0SH4uyCRR+TjmBDP1GvsVrWEGVzEj33YVQ9jAtIKpqsl/s/0xrocwAAeJxjYGRgYADig3cEzsTz23xl4GZnAIHLRucNkWl2BrA4BwMTiAIAF4IITwB4nGNgZGBgZwCChWASxGZkQAXyABOUANh4nGNnYGBgHyAMADa8ANoAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqHicY2BkYGCQZ8hlYGcAASYg5gJCBob/YD4DABbVAaoAeJxdkE1qg0AYhl8Tk9AIoVDaVSmzahcF87PMARLIMoFAl0ZHY1BHdBJIT9AT9AQ9RQ9Qeqy+yteNMzDzfM+88w0K4BY/cNAMB6N2bUaPPBLukybCLvleeAAPj8JD+hfhMV7hC3u4wxs7OO4NzQSZcI/8Ltwnfwi75E/hAR7wJTyk/xYeY49fYQ/PztM+jbTZ7LY6OWdBJdX/pqs6NYWa+zMxa13oKrA6Uoerqi/JwtpYxZXJ1coUVmeZUWVlTjq0/tHacjmdxuL90OR8O0UEDYMNdtiSEpz5XQGqzlm30kzUdAYFFOb8R7NOZk0q2lwAyz1i7oAr1xoXvrOgtYhZx8wY5KRV269JZ5yGpmzPTjQhvY9je6vEElPOuJP3mWKnP5M3V+YAAAB4nG2P2XLCMAxFfYFspGUp3Te+IB9lHJF4cOzUS2n/voaEGR6qB+lKo+WITdhga/a/bRnDBFPMkCBFhhwF5ihxg1sssMQKa9xhg3s84BFPeMYLXvGGd3zgE9tZr/hveXKVkFYoSnoeHJXfRoWOqi54mo9ameNFdrK+dLSyaVf7oJQTlkhXpD3Z5XXhR/rUfQVuKXO91Jps4cLOS6/I5YL3XhodRRsVWZe4NnZOhWnSAWgxhMoEr6SmzZieF43Mk7ZOBdeCVGrp9Eu+54J2xhySplfB5XHwQLXUmT9KH6+kPnQ7ZYuIEzNyfs1DLU1VU4SWZ6LkXGHsD1ZKbMw=) format("woff"), url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMlGRXgUAAAEoAAAAVmNtYXDiMBC2AAAB/AAAAUpnbHlmW/HoBwAAA4gAAA9QaGVhZAyD6V8AAADQAAAANmhoZWEOogcgAAAArAAAACRobXR42QAAAAAAAYAAAAB8bG9jYTDINOoAAANIAAAAQG1heHABMAB5AAABCAAAACBuYW1l1cf1oAAAEtgAAAIKcG9zdGZEjeMAABTkAAABgQABAAAHAAAAAKEHAAAAAAAHAAABAAAAAAAAAAAAAAAAAAAAHwABAAAAAQAAwdxheF8PPPUACwcAAAAAANMyzzEAAAAA0zLPMQAAAAAHAAcAAAAACAACAAAAAAAAAAEAAAAfAG0ABwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQcAAZAABQAIBHEE5gAAAPoEcQTmAAADXABXAc4AAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA8QHxHgcAAAAAoQcAAAAAAAABAAAAAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAAAAAMAAAADAAAAHAABAAAAAABEAAMAAQAAABwABAAoAAAABgAEAAEAAgAA8R7//wAAAADxAf//AAAPAAABAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqAABAAAAAAWLBYsAAgAAAREBAlUDNgWL++oCCwAAAwAAAAAGawZrAAIADgAaAAAJAhMEAAMSAAUkABMCAAEmACc2ADcWABcGAALrAcD+QJX+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgIwAVABUAGbCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAAAAgAAAAAFQAWLAAMABwAAASERKQERIREBwAEr/tUCVQErAXUEFvvqBBYAAAAEAAAAAAYgBiAABgATACQAJwAAAS4BJxUXNjcGBxc+ATUmACcVFhIBBwEhESEBEQEGBxU+ATcXNwEHFwTQAWVVuAO7AidxJSgF/t/lpc77t18BYf6fASsBdQE+TF1OijuZX/1gnJwDgGSeK6W4GBhqW3FGnFT0AWM4mjT+9AHrX/6f/kD+iwH2/sI7HZoSRDGYXwSWnJwAAAEAAAAABKsF1gAFAAABESEBEQECCwEqAXb+igRg/kD+iwSq/osAAAACAAAAAAVmBdYABgAMAAABLgEnET4BAREhAREBBWUBZVRUZfwRASsBdf6LA4Bkniv9piueAUT+QP6LBKr+iwAAAwAAAAAGIAYPAAUADAAaAAATESEBEQEFLgEnET4BAxUWEhcGAgcVNgA3JgDgASsBdf6LAsUBZVVVZbqlzgMDzqXlASEFBf7fBGD+QP6LBKr+i+Bkniv9piueAvOaNP70tbX+9DSaOAFi9fUBYgAAAAQAAAAABYsFiwAFAAsAEQAXAAABIxEhNSMDMzUzNSEBIxUhESMDFTMVMxECC5YBduCWluD+igOA4AF2luDglgLr/oqWAgrglvyAlgF2AqCW4AF2AAQAAAAABYsFiwAFAAsAEQAXAAABMxUzESETIxUhESMBMzUzNSETNSMRITUBdeCW/org4AF2lgHAluD+ipaWAXYCVeABdgHAlgF2++rglgHA4P6KlgAAAAACAAAAAAXWBdYADwATAAABIQ4BBxEeARchPgE3ES4BAyERIQVA/IA/VQEBVT8DgD9VAQFVP/yAA4AF1QFVP/yAP1UBAVU/A4A/VfvsA4AAAAYAAAAABmsGawAHAAwAEwAbACAAKAAACQEmJw4BBwElLgEnAQUhATYSNyYFAQYCBxYXIQUeARcBMwEWFz4BNwECvgFkTlSH8GEBEgOONemh/u4C5f3QAXpcaAEB/BP+3VxoAQEOAjD95DXpoQESeP7dTlSH8GH+7gPwAmgSAQFYUP4nd6X2Pv4nS/1zZAEBk01NAfhk/v+TTUhLpfY+Adn+CBIBAVhQAdkAAAAFAAAAAAZrBdYADwATABcAGwAfAAABIQ4BBxEeARchPgE3ES4BASEVIQEhNSEFITUhNSE1IQXV+1ZAVAICVEAEqkBUAgJU+xYBKv7WAur9FgLqAcD+1gEq/RYC6gXVAVU//IA/VQEBVT8DgD9V/ayV/tWVlZWWlQADAAAAAAYgBdYADwAnAD8AAAEhDgEHER4BFyE+ATcRLgEBIzUjFTM1MxUUBgcjLgEnET4BNzMeARUFIzUjFTM1MxUOAQcjLgE1ETQ2NzMeARcFi/vqP1QCAlQ/BBY/VAICVP1rcJWVcCog4CAqAQEqIOAgKgILcJWVcAEqIOAgKiog4CAqAQXVAVU//IA/VQEBVT8DgD9V/fcl4CVKICoBASogASogKgEBKiBKJeAlSiAqAQEqIAEqICoBASogAAAGAAAAAAYgBPYAAwAHAAsADwATABcAABMzNSMRMzUjETM1IwEhNSERITUhERUhNeCVlZWVlZUBKwQV++sEFfvrBBUDNZb+QJUBwJX+QJb+QJUCVZWVAAAAAQAAAAAGIAZsAC4AAAEiBgcBNjQnAR4BMz4BNy4BJw4BBxQXAS4BIw4BBx4BFzI2NwEGBx4BFz4BNy4BBUArSh797AcHAg8eTixffwICf19ffwIH/fEeTixffwICf18sTh4CFAUBA3tcXHsDA3sCTx8bATcZNhkBNB0gAn9fX38CAn9fGxn+zRwgAn9fX38CIBz+yhcaXHsCAntcXXsAAAIAAAAABlkGawBDAE8AAAE2NCc3PgEnAy4BDwEmLwEuASchDgEPAQYHJyYGBwMGFh8BBhQXBw4BFxMeAT8BFh8BHgEXIT4BPwE2NxcWNjcTNiYnBS4BJz4BNx4BFw4BBasFBZ4KBgeWBxkNujpEHAMUD/7WDxQCHEU5ug0aB5UHBQudBQWdCwUHlQcaDbo5RRwCFA8BKg8UAhxFOboNGgeVBwUL/ThvlAIClG9vlAIClAM3JEokewkaDQEDDAkFSy0cxg4RAQERDsYcLUsFCQz+/QwbCXskSiR7CRoN/v0MCQVLLRzGDhEBAREOxhwtSwUJDAEDDBsJQQKUb2+UAgKUb2+UAAAAAAEAAAAABmsGawALAAATEgAFJAATAgAlBACVCAGmAT0BPQGmCAj+Wv7D/sP+WgOA/sP+WggIAaYBPQE9AaYICP5aAAAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAASYAJzYANxYAFwYAA4D+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgZrCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAADAAAAAAZrBmsACwAXACMAAAEEAAMSAAUkABMCAAEmACc2ADcWABcGAAMOAQcuASc+ATceAQOA/sP+WggIAaYBPQE9AaYICP5a/sP9/q4GBgFS/f0BUgYG/q4dAn9fX38CAn9fX38Gawj+Wv7D/sP+WggIAaYBPQE9Aab6yAYBUv39AVIGBv6u/f3+rgJPX38CAn9fX38CAn8AAAAEAAAAAAYgBiAADwAbACUAKQAAASEOAQcRHgEXIT4BNxEuAQEjNSMVIxEzFTM1OwEhHgEXEQ4BByE3MzUjBYv76j9UAgJUPwQWP1QCAlT9a3CVcHCVcJYBKiAqAQEqIP7WcJWVBiACVD/76j9UAgJUPwQWP1T8gpWVAcC7uwEqIP7WICoBcOAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAEwcJAScJATcJARcBA4D+w/5aCAgBpgE9AT0BpggI/lo4af70/vRpAQv+9WkBDAEMaf71BmsI/lr+w/7D/loICAGmAT0BPQGm/BFpAQv+9WkBDAEMaf71AQtp/vQAAQAAAAAF1ga2ABYAAAERCQERHgEXDgEHLgEnIxYAFzYANyYAA4D+iwF1vv0FBf2+vv0FlQYBUf7+AVEGBv6vBYsBKv6L/osBKgT9v779BQX9vv7+rwYGAVH+/gFRAAAAAQAAAAAFPwcAABQAAAERIyIGHQEhAyMRIREjETM1NDYzMgU/nVY8ASUn/v7O///QrZMG9P74SEi9/tj9CQL3ASjaus0AAAAABAAAAAAGjgcAADAARQBgAGwAAAEUHgMVFAcGBCMiJicmNTQ2NzYlLgE1NDcGIyImNTQ2Nz4BMyEHIx4BFRQOAycyNjc2NTQuAiMiBgcGFRQeAxMyPgI1NC4BLwEmLwImIyIOAxUUHgIBMxUjFSM1IzUzNTMDH0BbWkAwSP7qn4TlOSVZSoMBESAfFS4WlMtIP03TcAGiioNKTDFFRjGSJlAaNSI/akAqURkvFCs9WTY6a1s3Dg8THgocJU4QIDVob1M2RnF9A2vV1WnU1GkD5CRFQ1CATlpTenNTYDxHUYouUhIqQCkkMQTBlFKaNkJAWD+MWkhzRztAPiEbOWY6hn1SJyE7ZS5nZ1I0/JcaNF4+GTAkGCMLFx04Ag4kOF07Rms7HQNsbNvbbNkAAwAAAAAGgAZsAAMADgAqAAABESERARYGKwEiJjQ2MhYBESERNCYjIgYHBhURIRIQLwEhFSM+AzMyFgHd/rYBXwFnVAJSZGemZASP/rdRVj9VFQv+twIBAQFJAhQqR2c/q9AEj/whA98BMkliYpNhYfzd/cgCEml3RTMeM/3XAY8B8DAwkCAwOB/jAAABAAAAAAaUBgAAMQAAAQYHFhUUAg4BBCMgJxYzMjcuAScWMzI3LgE9ARYXLgE1NDcWBBcmNTQ2MzIXNjcGBzYGlENfAUyb1v7SrP7x4SMr4bBpph8hHCsqcJNETkJOLHkBW8YIvYaMYG1gJWldBWhiRQ4cgv797rdtkQSKAn1hBQsXsXUEJgMsjlNYS5WzCiYkhr1mFTlzPwoAAAABAAAAAAWABwAAIgAAARcOAQcGLgM1ESM1PgQ3PgE7AREhFSERFB4CNzYFMFAXsFlorXBOIahIckQwFAUBBwT0AU3+sg0gQzBOAc/tIz4BAjhceHg6AiDXGlddb1ctBQf+WPz9+h40NR4BAgABAAAAAAaABoAASgAAARQCBCMiJzY/AR4BMzI+ATU0LgEjIg4DFRQWFxY/ATY3NicmNTQ2MzIWFRQGIyImNz4CNTQmIyIGFRQXAwYXJgI1NBIkIAQSBoDO/p/Rb2s7EzYUaj15vmh34o5ptn9bK1BNHggIBgIGETPRqZepiWs9Sg4IJRc2Mj5WGWMRBM7+zgFhAaIBYc4DgNH+n84gXUfTJzmJ8JZyyH46YH2GQ2ieIAwgHxgGFxQ9WpfZpIOq7lc9I3VZHzJCclVJMf5eRmtbAXzp0QFhzs7+nwAABwAAAAAHAATPAA4AFwAqAD0AUABaAF0AAAERNh4CBw4BBwYmIycmNxY2NzYmBxEUBRY2Nz4BNy4BJyMGHwEeARcOARcWNjc+ATcuAScjBh8BHgEXFAYXFjY3PgE3LgEnIwYfAR4BFw4BBTM/ARUzESMGAyUVJwMchM2UWwgNq4JHrQgBAapUaAoJcWMBfiIhDiMrAQJLMB0BBAokNAIBPmMiIQ4iLAECSzAeAQUKJDQBP2MiIQ4iLAECSzAeAQUKJDQBAT75g+5B4arNLNIBJ44ByQL9BQ9mvYCKwA8FBQMDwwJVTGdzBf6VB8IHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvVJkAWUDDEf+tYP5AQAAAAEAAAAABiAGtgAbAAABBAADER4BFzMRITU2ADcWABcVIREzPgE3EQIAA4D+4v6FBwJ/X+D+1QYBJ97eAScG/tXgX38CB/6FBrUH/oX+4v32X38CAlWV3gEnBgb+2d6V/asCf18CCgEeAXsAAAAAEADGAAEAAAAAAAEABwAAAAEAAAAAAAIABwAHAAEAAAAAAAMABwAOAAEAAAAAAAQABwAVAAEAAAAAAAUACwAcAAEAAAAAAAYABwAnAAEAAAAAAAoAKwAuAAEAAAAAAAsAEwBZAAMAAQQJAAEADgBsAAMAAQQJAAIADgB6AAMAAQQJAAMADgCIAAMAAQQJAAQADgCWAAMAAQQJAAUAFgCkAAMAAQQJAAYADgC6AAMAAQQJAAoAVgDIAAMAAQQJAAsAJgEeVmlkZW9KU1JlZ3VsYXJWaWRlb0pTVmlkZW9KU1ZlcnNpb24gMS4wVmlkZW9KU0dlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAFYAaQBkAGUAbwBKAFMAUgBlAGcAdQBsAGEAcgBWAGkAZABlAG8ASgBTAFYAaQBkAGUAbwBKAFMAVgBlAHIAcwBpAG8AbgAgADEALgAwAFYAaQBkAGUAbwBKAFMARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAABAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8EcGxheQtwbGF5LWNpcmNsZQVwYXVzZQt2b2x1bWUtbXV0ZQp2b2x1bWUtbG93CnZvbHVtZS1taWQLdm9sdW1lLWhpZ2gQZnVsbHNjcmVlbi1lbnRlcg9mdWxsc2NyZWVuLWV4aXQGc3F1YXJlB3NwaW5uZXIJc3VidGl0bGVzCGNhcHRpb25zCGNoYXB0ZXJzBXNoYXJlA2NvZwZjaXJjbGUOY2lyY2xlLW91dGxpbmUTY2lyY2xlLWlubmVyLWNpcmNsZQJoZAZjYW5jZWwGcmVwbGF5CGZhY2Vib29rBWdwbHVzCGxpbmtlZGluB3R3aXR0ZXIGdHVtYmxyCXBpbnRlcmVzdBFhdWRpby1kZXNjcmlwdGlvbgVhdWRpbwAAAAAA) format("truetype"); + font-weight: normal; + font-style: normal; } + +.vjs-icon-play, .video-js .vjs-big-play-button, .video-js .vjs-play-control { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-play:before, .video-js .vjs-big-play-button:before, .video-js .vjs-play-control:before { + content: "\f101"; } + +.vjs-icon-play-circle { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-play-circle:before { + content: "\f102"; } + +.vjs-icon-pause, .video-js .vjs-play-control.vjs-playing { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing:before { + content: "\f103"; } + +.vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0, +.video-js .vjs-volume-menu-button.vjs-vol-0 { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0:before, + .video-js .vjs-volume-menu-button.vjs-vol-0:before { + content: "\f104"; } + +.vjs-icon-volume-low, .video-js .vjs-mute-control.vjs-vol-1, +.video-js .vjs-volume-menu-button.vjs-vol-1 { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1:before, + .video-js .vjs-volume-menu-button.vjs-vol-1:before { + content: "\f105"; } + +.vjs-icon-volume-mid, .video-js .vjs-mute-control.vjs-vol-2, +.video-js .vjs-volume-menu-button.vjs-vol-2 { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2:before, + .video-js .vjs-volume-menu-button.vjs-vol-2:before { + content: "\f106"; } + +.vjs-icon-volume-high, .video-js .vjs-mute-control, +.video-js .vjs-volume-menu-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-volume-high:before, .video-js .vjs-mute-control:before, + .video-js .vjs-volume-menu-button:before { + content: "\f107"; } + +.vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control:before { + content: "\f108"; } + +.vjs-icon-fullscreen-exit, .video-js.vjs-fullscreen .vjs-fullscreen-control { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control:before { + content: "\f109"; } + +.vjs-icon-square { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-square:before { + content: "\f10a"; } + +.vjs-icon-spinner { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-spinner:before { + content: "\f10b"; } + +.vjs-icon-subtitles, .video-js .vjs-subtitles-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-subtitles:before, .video-js .vjs-subtitles-button:before { + content: "\f10c"; } + +.vjs-icon-captions, .video-js .vjs-captions-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-captions:before, .video-js .vjs-captions-button:before { + content: "\f10d"; } + +.vjs-icon-chapters, .video-js .vjs-chapters-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-chapters:before, .video-js .vjs-chapters-button:before { + content: "\f10e"; } + +.vjs-icon-share { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-share:before { + content: "\f10f"; } + +.vjs-icon-cog { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-cog:before { + content: "\f110"; } + +.vjs-icon-circle, .video-js .vjs-mouse-display, .video-js .vjs-play-progress, .video-js .vjs-volume-level { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-circle:before, .video-js .vjs-mouse-display:before, .video-js .vjs-play-progress:before, .video-js .vjs-volume-level:before { + content: "\f111"; } + +.vjs-icon-circle-outline { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-circle-outline:before { + content: "\f112"; } + +.vjs-icon-circle-inner-circle { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-circle-inner-circle:before { + content: "\f113"; } + +.vjs-icon-hd { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-hd:before { + content: "\f114"; } + +.vjs-icon-cancel, .video-js .vjs-control.vjs-close-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-cancel:before, .video-js .vjs-control.vjs-close-button:before { + content: "\f115"; } + +.vjs-icon-replay { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-replay:before { + content: "\f116"; } + +.vjs-icon-facebook { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-facebook:before { + content: "\f117"; } + +.vjs-icon-gplus { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-gplus:before { + content: "\f118"; } + +.vjs-icon-linkedin { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-linkedin:before { + content: "\f119"; } + +.vjs-icon-twitter { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-twitter:before { + content: "\f11a"; } + +.vjs-icon-tumblr { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-tumblr:before { + content: "\f11b"; } + +.vjs-icon-pinterest { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-pinterest:before { + content: "\f11c"; } + +.vjs-icon-audio-description, .video-js .vjs-descriptions-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-audio-description:before, .video-js .vjs-descriptions-button:before { + content: "\f11d"; } + +.vjs-icon-audio, .video-js .vjs-audio-button { + font-family: VideoJS; + font-weight: normal; + font-style: normal; } + .vjs-icon-audio:before, .video-js .vjs-audio-button:before { + content: "\f11e"; } + +.video-js { + display: block; + vertical-align: top; + box-sizing: border-box; + color: #fff; + background-color: #000; + position: relative; + padding: 0; + font-size: 10px; + line-height: 1; + font-weight: normal; + font-style: normal; + font-family: Arial, Helvetica, sans-serif; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .video-js:-moz-full-screen { + position: absolute; } + .video-js:-webkit-full-screen { + width: 100% !important; + height: 100% !important; } + +.video-js *, +.video-js *:before, +.video-js *:after { + box-sizing: inherit; } + +.video-js ul { + font-family: inherit; + font-size: inherit; + line-height: inherit; + list-style-position: outside; + margin-left: 0; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; } + +.video-js.vjs-fluid, +.video-js.vjs-16-9, +.video-js.vjs-4-3 { + width: 100%; + max-width: 100%; + height: 0; } + +.video-js.vjs-16-9 { + padding-top: 56.25%; } + +.video-js.vjs-4-3 { + padding-top: 75%; } + +.video-js.vjs-fill { + width: 100%; + height: 100%; } + +.video-js .vjs-tech { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + +body.vjs-full-window { + padding: 0; + margin: 0; + height: 100%; + overflow-y: auto; } + +.vjs-full-window .video-js.vjs-fullscreen { + position: fixed; + overflow: hidden; + z-index: 1000; + left: 0; + top: 0; + bottom: 0; + right: 0; } + +.video-js.vjs-fullscreen { + width: 100% !important; + height: 100% !important; + padding-top: 0 !important; } + +.video-js.vjs-fullscreen.vjs-user-inactive { + cursor: none; } + +.vjs-hidden { + display: none !important; } + +.vjs-disabled { + opacity: 0.5; + cursor: default; } + +.video-js .vjs-offscreen { + height: 1px; + left: -9999px; + position: absolute; + top: 0; + width: 1px; } + +.vjs-lock-showing { + display: block !important; + opacity: 1; + visibility: visible; } + +.vjs-no-js { + padding: 20px; + color: #fff; + background-color: #000; + font-size: 18px; + font-family: Arial, Helvetica, sans-serif; + text-align: center; + width: 300px; + height: 150px; + margin: 0px auto; } + +.vjs-no-js a, +.vjs-no-js a:visited { + color: #66A8CC; } + +.video-js .vjs-big-play-button { + font-size: 3em; + line-height: 1.5em; + height: 1.5em; + width: 3em; + display: block; + position: absolute; + top: 10px; + left: 10px; + padding: 0; + cursor: pointer; + opacity: 1; + border: 0.06666em solid #fff; + background-color: #2B333F; + background-color: rgba(43, 51, 63, 0.7); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; + -webkit-transition: all 0.4s; + -moz-transition: all 0.4s; + -o-transition: all 0.4s; + transition: all 0.4s; } + +.vjs-big-play-centered .vjs-big-play-button { + top: 50%; + left: 50%; + margin-top: -0.75em; + margin-left: -1.5em; } + +.video-js:hover .vjs-big-play-button, +.video-js .vjs-big-play-button:focus { + outline: 0; + border-color: #fff; + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); + -webkit-transition: all 0s; + -moz-transition: all 0s; + -o-transition: all 0s; + transition: all 0s; } + +.vjs-controls-disabled .vjs-big-play-button, +.vjs-has-started .vjs-big-play-button, +.vjs-using-native-controls .vjs-big-play-button, +.vjs-error .vjs-big-play-button { + display: none; } + +.video-js button { + background: none; + border: none; + color: inherit; + display: inline-block; + overflow: visible; + font-size: inherit; + line-height: inherit; + text-transform: none; + text-decoration: none; + transition: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } + +.video-js .vjs-control.vjs-close-button { + cursor: pointer; + height: 3em; + position: absolute; + right: 0; + top: 0.5em; + z-index: 2; } + +.vjs-menu-button { + cursor: pointer; } + +.vjs-menu-button.vjs-disabled { + cursor: default; } + +.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu { + display: none; } + +.vjs-menu .vjs-menu-content { + display: block; + padding: 0; + margin: 0; + overflow: auto; + font-family: Arial, Helvetica, sans-serif; } + +.vjs-scrubbing .vjs-menu-button:hover .vjs-menu { + display: none; } + +.vjs-menu li { + list-style: none; + margin: 0; + padding: 0.2em 0; + line-height: 1.4em; + font-size: 1.2em; + text-align: center; + text-transform: lowercase; } + +.vjs-menu li.vjs-menu-item:focus, +.vjs-menu li.vjs-menu-item:hover { + outline: 0; + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); } + +.vjs-menu li.vjs-selected, +.vjs-menu li.vjs-selected:focus, +.vjs-menu li.vjs-selected:hover { + background-color: #fff; + color: #2B333F; } + +.vjs-menu li.vjs-menu-title { + text-align: center; + text-transform: uppercase; + font-size: 1em; + line-height: 2em; + padding: 0; + margin: 0 0 0.3em 0; + font-weight: bold; + cursor: default; } + +.vjs-menu-button-popup .vjs-menu { + display: none; + position: absolute; + bottom: 0; + width: 10em; + left: -3em; + height: 0em; + margin-bottom: 1.5em; + border-top-color: rgba(43, 51, 63, 0.7); } + +.vjs-menu-button-popup .vjs-menu .vjs-menu-content { + background-color: #2B333F; + background-color: rgba(43, 51, 63, 0.7); + position: absolute; + width: 100%; + bottom: 1.5em; + max-height: 15em; } + +.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu, +.vjs-menu-button-popup .vjs-menu.vjs-lock-showing { + display: block; } + +.video-js .vjs-menu-button-inline { + -webkit-transition: all 0.4s; + -moz-transition: all 0.4s; + -o-transition: all 0.4s; + transition: all 0.4s; + overflow: hidden; } + +.video-js .vjs-menu-button-inline:before { + width: 2.222222222em; } + +.video-js .vjs-menu-button-inline:hover, +.video-js .vjs-menu-button-inline:focus, +.video-js .vjs-menu-button-inline.vjs-slider-active, +.video-js.vjs-no-flex .vjs-menu-button-inline { + width: 12em; } + +.video-js .vjs-menu-button-inline.vjs-slider-active { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; } + +.vjs-menu-button-inline .vjs-menu { + opacity: 0; + height: 100%; + width: auto; + position: absolute; + left: 4em; + top: 0; + padding: 0; + margin: 0; + -webkit-transition: all 0.4s; + -moz-transition: all 0.4s; + -o-transition: all 0.4s; + transition: all 0.4s; } + +.vjs-menu-button-inline:hover .vjs-menu, +.vjs-menu-button-inline:focus .vjs-menu, +.vjs-menu-button-inline.vjs-slider-active .vjs-menu { + display: block; + opacity: 1; } + +.vjs-no-flex .vjs-menu-button-inline .vjs-menu { + display: block; + opacity: 1; + position: relative; + width: auto; } + +.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu, +.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu, +.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu { + width: auto; } + +.vjs-menu-button-inline .vjs-menu-content { + width: auto; + height: 100%; + margin: 0; + overflow: hidden; } + +.video-js .vjs-control-bar { + display: none; + width: 100%; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 3.0em; + background-color: #2B333F; + background-color: rgba(43, 51, 63, 0.7); } + +.vjs-has-started .vjs-control-bar { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + visibility: visible; + opacity: 1; + -webkit-transition: visibility 0.1s, opacity 0.1s; + -moz-transition: visibility 0.1s, opacity 0.1s; + -o-transition: visibility 0.1s, opacity 0.1s; + transition: visibility 0.1s, opacity 0.1s; } + +.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { + visibility: visible; + opacity: 0; + -webkit-transition: visibility 1s, opacity 1s; + -moz-transition: visibility 1s, opacity 1s; + -o-transition: visibility 1s, opacity 1s; + transition: visibility 1s, opacity 1s; } + +.vjs-controls-disabled .vjs-control-bar, +.vjs-using-native-controls .vjs-control-bar, +.vjs-error .vjs-control-bar { + display: none !important; } + +.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { + opacity: 1; + visibility: visible; } + +.vjs-has-started.vjs-no-flex .vjs-control-bar { + display: table; } + +.video-js .vjs-control { + outline: none; + position: relative; + text-align: center; + margin: 0; + padding: 0; + height: 100%; + width: 4em; + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; } + .video-js .vjs-control:before { + font-size: 1.8em; + line-height: 1.67; } + +.video-js .vjs-control:focus:before, +.video-js .vjs-control:hover:before, +.video-js .vjs-control:focus { + text-shadow: 0em 0em 1em white; } + +.video-js .vjs-control-text { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.vjs-no-flex .vjs-control { + display: table-cell; + vertical-align: middle; } + +.video-js .vjs-custom-control-spacer { + display: none; } + +.video-js .vjs-progress-control { + -webkit-box-flex: auto; + -moz-box-flex: auto; + -webkit-flex: auto; + -ms-flex: auto; + flex: auto; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + min-width: 4em; } + +.vjs-live .vjs-progress-control { + display: none; } + +.video-js .vjs-progress-holder { + -webkit-box-flex: auto; + -moz-box-flex: auto; + -webkit-flex: auto; + -ms-flex: auto; + flex: auto; + -webkit-transition: all 0.2s; + -moz-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; + height: 0.3em; } + +.video-js .vjs-progress-control:hover .vjs-progress-holder { + font-size: 1.666666666666666666em; } + +/* If we let the font size grow as much as everything else, the current time tooltip ends up + ginormous. If you'd like to enable the current time tooltip all the time, this should be disabled + to avoid a weird hitch when you roll off the hover. */ +.video-js .vjs-progress-control:hover .vjs-time-tooltip, +.video-js .vjs-progress-control:hover .vjs-mouse-display:after, +.video-js .vjs-progress-control:hover .vjs-play-progress:after { + font-family: Arial, Helvetica, sans-serif; + visibility: visible; + font-size: 0.6em; } + +.video-js .vjs-progress-holder .vjs-play-progress, +.video-js .vjs-progress-holder .vjs-load-progress, +.video-js .vjs-progress-holder .vjs-tooltip-progress-bar, +.video-js .vjs-progress-holder .vjs-load-progress div { + position: absolute; + display: block; + height: 0.3em; + margin: 0; + padding: 0; + width: 0; + left: 0; + top: 0; } + +.video-js .vjs-mouse-display:before { + display: none; } + +.video-js .vjs-play-progress { + background-color: #fff; } + .video-js .vjs-play-progress:before { + position: absolute; + top: -0.333333333333333em; + right: -0.5em; + font-size: 0.9em; } + +.video-js .vjs-time-tooltip, +.video-js .vjs-mouse-display:after, +.video-js .vjs-play-progress:after { + visibility: hidden; + pointer-events: none; + position: absolute; + top: -3.4em; + right: -1.9em; + font-size: 0.9em; + color: #000; + content: attr(data-current-time); + padding: 6px 8px 8px 8px; + background-color: #fff; + background-color: rgba(255, 255, 255, 0.8); + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; } + +.video-js .vjs-time-tooltip, +.video-js .vjs-play-progress:before, +.video-js .vjs-play-progress:after { + z-index: 1; } + +.video-js .vjs-progress-control .vjs-keep-tooltips-inside:after { + display: none; } + +.video-js .vjs-load-progress { + background: #bfc7d3; + background: rgba(115, 133, 159, 0.5); } + +.video-js .vjs-load-progress div { + background: white; + background: rgba(115, 133, 159, 0.75); } + +.video-js.vjs-no-flex .vjs-progress-control { + width: auto; } + +.video-js .vjs-time-tooltip { + display: inline-block; + height: 2.4em; + position: relative; + float: right; + right: -1.9em; } + +.vjs-tooltip-progress-bar { + visibility: hidden; } + +.video-js .vjs-progress-control .vjs-mouse-display { + display: none; + position: absolute; + width: 1px; + height: 100%; + background-color: #000; + z-index: 1; } + +.vjs-no-flex .vjs-progress-control .vjs-mouse-display { + z-index: 0; } + +.video-js .vjs-progress-control:hover .vjs-mouse-display { + display: block; } + +.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display, +.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display:after { + visibility: hidden; + opacity: 0; + -webkit-transition: visibility 1s, opacity 1s; + -moz-transition: visibility 1s, opacity 1s; + -o-transition: visibility 1s, opacity 1s; + transition: visibility 1s, opacity 1s; } + +.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display, +.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display:after { + display: none; } + +.vjs-mouse-display .vjs-time-tooltip, +.video-js .vjs-progress-control .vjs-mouse-display:after { + color: #fff; + background-color: #000; + background-color: rgba(0, 0, 0, 0.8); } + +.video-js .vjs-slider { + outline: 0; + position: relative; + cursor: pointer; + padding: 0; + margin: 0 0.45em 0 0.45em; + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); } + +.video-js .vjs-slider:focus { + text-shadow: 0em 0em 1em white; + -webkit-box-shadow: 0 0 1em #fff; + -moz-box-shadow: 0 0 1em #fff; + box-shadow: 0 0 1em #fff; } + +.video-js .vjs-mute-control, +.video-js .vjs-volume-menu-button { + cursor: pointer; + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; } + +.video-js .vjs-volume-control { + width: 5em; + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; } + +.video-js .vjs-volume-bar { + margin: 1.35em 0.45em; } + +.vjs-volume-bar.vjs-slider-horizontal { + width: 5em; + height: 0.3em; } + +.vjs-volume-bar.vjs-slider-vertical { + width: 0.3em; + height: 5em; + margin: 1.35em auto; } + +.video-js .vjs-volume-level { + position: absolute; + bottom: 0; + left: 0; + background-color: #fff; } + .video-js .vjs-volume-level:before { + position: absolute; + font-size: 0.9em; } + +.vjs-slider-vertical .vjs-volume-level { + width: 0.3em; } + .vjs-slider-vertical .vjs-volume-level:before { + top: -0.5em; + left: -0.3em; } + +.vjs-slider-horizontal .vjs-volume-level { + height: 0.3em; } + .vjs-slider-horizontal .vjs-volume-level:before { + top: -0.3em; + right: -0.5em; } + +.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level { + height: 100%; } + +.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level { + width: 100%; } + +.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu { + display: block; + width: 0; + height: 0; + border-top-color: transparent; } + +.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu { + left: 0.5em; + height: 8em; } + +.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu { + left: -2em; } + +.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu-content { + height: 0; + width: 0; + overflow-x: hidden; + overflow-y: hidden; } + +.vjs-volume-menu-button-vertical:hover .vjs-menu-content, +.vjs-volume-menu-button-vertical:focus .vjs-menu-content, +.vjs-volume-menu-button-vertical.vjs-slider-active .vjs-menu-content, +.vjs-volume-menu-button-vertical .vjs-lock-showing .vjs-menu-content { + height: 8em; + width: 2.9em; } + +.vjs-volume-menu-button-horizontal:hover .vjs-menu-content, +.vjs-volume-menu-button-horizontal:focus .vjs-menu-content, +.vjs-volume-menu-button-horizontal .vjs-slider-active .vjs-menu-content, +.vjs-volume-menu-button-horizontal .vjs-lock-showing .vjs-menu-content { + height: 2.9em; + width: 8em; } + +.vjs-volume-menu-button.vjs-menu-button-inline .vjs-menu-content { + background-color: transparent !important; } + +.vjs-poster { + display: inline-block; + vertical-align: middle; + background-repeat: no-repeat; + background-position: 50% 50%; + background-size: contain; + background-color: #000000; + cursor: pointer; + margin: 0; + padding: 0; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 100%; } + +.vjs-poster img { + display: block; + vertical-align: middle; + margin: 0 auto; + max-height: 100%; + padding: 0; + width: 100%; } + +.vjs-has-started .vjs-poster { + display: none; } + +.vjs-audio.vjs-has-started .vjs-poster { + display: block; } + +.vjs-controls-disabled .vjs-poster { + display: none; } + +.vjs-using-native-controls .vjs-poster { + display: none; } + +.video-js .vjs-live-control { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-flex: auto; + -moz-box-flex: auto; + -webkit-flex: auto; + -ms-flex: auto; + flex: auto; + font-size: 1em; + line-height: 3em; } + +.vjs-no-flex .vjs-live-control { + display: table-cell; + width: auto; + text-align: left; } + +.video-js .vjs-time-control { + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; + font-size: 1em; + line-height: 3em; + min-width: 2em; + width: auto; + padding-left: 1em; + padding-right: 1em; } + +.vjs-live .vjs-time-control { + display: none; } + +.video-js .vjs-current-time, +.vjs-no-flex .vjs-current-time { + display: none; } + +.video-js .vjs-duration, +.vjs-no-flex .vjs-duration { + display: none; } + +.vjs-time-divider { + display: none; + line-height: 3em; } + +.vjs-live .vjs-time-divider { + display: none; } + +.video-js .vjs-play-control { + cursor: pointer; + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; } + +.vjs-text-track-display { + position: absolute; + bottom: 3em; + left: 0; + right: 0; + top: 0; + pointer-events: none; } + +.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display { + bottom: 1em; } + +.video-js .vjs-text-track { + font-size: 1.4em; + text-align: center; + margin-bottom: 0.1em; + background-color: #000; + background-color: rgba(0, 0, 0, 0.5); } + +.vjs-subtitles { + color: #fff; } + +.vjs-captions { + color: #fc6; } + +.vjs-tt-cue { + display: block; } + +video::-webkit-media-text-track-display { + -moz-transform: translateY(-3em); + -ms-transform: translateY(-3em); + -o-transform: translateY(-3em); + -webkit-transform: translateY(-3em); + transform: translateY(-3em); } + +.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display { + -moz-transform: translateY(-1.5em); + -ms-transform: translateY(-1.5em); + -o-transform: translateY(-1.5em); + -webkit-transform: translateY(-1.5em); + transform: translateY(-1.5em); } + +.video-js .vjs-fullscreen-control { + cursor: pointer; + -webkit-box-flex: none; + -moz-box-flex: none; + -webkit-flex: none; + -ms-flex: none; + flex: none; } + +.vjs-playback-rate .vjs-playback-rate-value { + font-size: 1.5em; + line-height: 2; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; } + +.vjs-playback-rate .vjs-menu { + width: 4em; + left: 0em; } + +.vjs-error .vjs-error-display .vjs-modal-dialog-content { + font-size: 1.4em; + text-align: center; } + +.vjs-error .vjs-error-display:before { + color: #fff; + content: 'X'; + font-family: Arial, Helvetica, sans-serif; + font-size: 4em; + left: 0; + line-height: 1; + margin-top: -0.5em; + position: absolute; + text-shadow: 0.05em 0.05em 0.1em #000; + text-align: center; + top: 50%; + vertical-align: middle; + width: 100%; } + +.vjs-loading-spinner { + display: none; + position: absolute; + top: 50%; + left: 50%; + margin: -25px 0 0 -25px; + opacity: 0.85; + text-align: left; + border: 6px solid rgba(43, 51, 63, 0.7); + box-sizing: border-box; + background-clip: padding-box; + width: 50px; + height: 50px; + border-radius: 25px; } + +.vjs-seeking .vjs-loading-spinner, +.vjs-waiting .vjs-loading-spinner { + display: block; } + +.vjs-loading-spinner:before, +.vjs-loading-spinner:after { + content: ""; + position: absolute; + margin: -6px; + box-sizing: inherit; + width: inherit; + height: inherit; + border-radius: inherit; + opacity: 1; + border: inherit; + border-color: transparent; + border-top-color: white; } + +.vjs-seeking .vjs-loading-spinner:before, +.vjs-seeking .vjs-loading-spinner:after, +.vjs-waiting .vjs-loading-spinner:before, +.vjs-waiting .vjs-loading-spinner:after { + -webkit-animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; + animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; } + +.vjs-seeking .vjs-loading-spinner:before, +.vjs-waiting .vjs-loading-spinner:before { + border-top-color: white; } + +.vjs-seeking .vjs-loading-spinner:after, +.vjs-waiting .vjs-loading-spinner:after { + border-top-color: white; + -webkit-animation-delay: 0.44s; + animation-delay: 0.44s; } + +@keyframes vjs-spinner-spin { + 100% { + transform: rotate(360deg); } } + +@-webkit-keyframes vjs-spinner-spin { + 100% { + -webkit-transform: rotate(360deg); } } + +@keyframes vjs-spinner-fade { + 0% { + border-top-color: #73859f; } + 20% { + border-top-color: #73859f; } + 35% { + border-top-color: white; } + 60% { + border-top-color: #73859f; } + 100% { + border-top-color: #73859f; } } + +@-webkit-keyframes vjs-spinner-fade { + 0% { + border-top-color: #73859f; } + 20% { + border-top-color: #73859f; } + 35% { + border-top-color: white; } + 60% { + border-top-color: #73859f; } + 100% { + border-top-color: #73859f; } } + +.vjs-chapters-button .vjs-menu ul { + width: 24em; } + +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer { + -webkit-box-flex: auto; + -moz-box-flex: auto; + -webkit-flex: auto; + -ms-flex: auto; + flex: auto; } + +.video-js.vjs-layout-tiny:not(.vjs-fullscreen).vjs-no-flex .vjs-custom-control-spacer { + width: auto; } + +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-remaining-time, +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-playback-rate, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-progress-control, +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-control, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-menu-button, +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-captions-button, +.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-audio-button { + display: none; } + +.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-remaining-time, +.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-playback-rate, +.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-control, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-menu-button, +.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-captions-button, +.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-audio-button { + display: none; } + +.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-remaining-time, +.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-playback-rate, +.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-volume-control, +.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-captions-button, +.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-subtitles-button .vjs-audio-button { + display: none; } + +.vjs-caption-settings { + position: relative; + top: 1em; + background-color: #2B333F; + background-color: rgba(43, 51, 63, 0.75); + color: #fff; + margin: 0 auto; + padding: 0.5em; + height: 16em; + font-size: 12px; + width: 40em; } + +.vjs-caption-settings .vjs-tracksettings { + top: 0; + bottom: 1em; + left: 0; + right: 0; + position: absolute; + overflow: auto; } + +.vjs-caption-settings .vjs-tracksettings-colors, +.vjs-caption-settings .vjs-tracksettings-font { + float: left; } + +.vjs-caption-settings .vjs-tracksettings-colors:after, +.vjs-caption-settings .vjs-tracksettings-font:after, +.vjs-caption-settings .vjs-tracksettings-controls:after { + clear: both; } + +.vjs-caption-settings .vjs-tracksettings-controls { + position: absolute; + bottom: 1em; + right: 1em; } + +.vjs-caption-settings .vjs-tracksetting { + margin: 5px; + padding: 3px; + min-height: 40px; + border: none; } + +.vjs-caption-settings .vjs-tracksetting label, +.vjs-caption-settings .vjs-tracksetting legend { + display: block; + width: 100px; + margin-bottom: 5px; } + +.vjs-caption-settings .vjs-tracksetting span { + display: inline; + margin-left: 5px; + vertical-align: top; + float: right; } + +.vjs-caption-settings .vjs-tracksetting > div { + margin-bottom: 5px; + min-height: 20px; } + +.vjs-caption-settings .vjs-tracksetting > div:last-child { + margin-bottom: 0; + padding-bottom: 0; + min-height: 0; } + +.vjs-caption-settings label > input { + margin-right: 10px; } + +.vjs-caption-settings fieldset { + margin-top: 1em; + margin-left: .5em; } + +.vjs-caption-settings fieldset .vjs-label { + position: absolute; + clip: rect(1px 1px 1px 1px); + /* for Internet Explorer */ + clip: rect(1px, 1px, 1px, 1px); + padding: 0; + border: 0; + height: 1px; + width: 1px; + overflow: hidden; } + +.vjs-caption-settings input[type="button"] { + width: 40px; + height: 40px; } + +.video-js .vjs-modal-dialog { + background: rgba(0, 0, 0, 0.8); + background: -webkit-linear-gradient(-90deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0)); + background: linear-gradient(180deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0)); } + +.vjs-modal-dialog .vjs-modal-dialog-content { + font-size: 1.2em; + line-height: 1.5; + padding: 20px 24px; + z-index: 1; } + +@media print { + .video-js > *:not(.vjs-tech):not(.vjs-poster) { + visibility: hidden; } } + +@media \0screen { + .vjs-user-inactive.vjs-playing .vjs-control-bar :before { + content: ""; + } +} + +@media \0screen { + .vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { + visibility: hidden; + } +} diff --git a/addons/webinterface.default/lib/video-js/video-js.min.css b/addons/webinterface.default/lib/video-js/video-js.min.css new file mode 100644 index 0000000000..75f6e3861a --- /dev/null +++ b/addons/webinterface.default/lib/video-js/video-js.min.css @@ -0,0 +1 @@ +.video-js .vjs-audio-button,.video-js .vjs-big-play-button,.video-js .vjs-captions-button,.video-js .vjs-chapters-button,.video-js .vjs-control.vjs-close-button,.video-js .vjs-descriptions-button,.video-js .vjs-fullscreen-control,.video-js .vjs-mouse-display,.video-js .vjs-mute-control,.video-js .vjs-mute-control.vjs-vol-0,.video-js .vjs-mute-control.vjs-vol-1,.video-js .vjs-mute-control.vjs-vol-2,.video-js .vjs-play-control,.video-js .vjs-play-control.vjs-playing,.video-js .vjs-play-progress,.video-js .vjs-subtitles-button,.video-js .vjs-volume-level,.video-js .vjs-volume-menu-button,.video-js .vjs-volume-menu-button.vjs-vol-0,.video-js .vjs-volume-menu-button.vjs-vol-1,.video-js .vjs-volume-menu-button.vjs-vol-2,.video-js.vjs-fullscreen .vjs-fullscreen-control,.vjs-icon-audio,.vjs-icon-audio-description,.vjs-icon-cancel,.vjs-icon-captions,.vjs-icon-chapters,.vjs-icon-circle,.vjs-icon-circle-inner-circle,.vjs-icon-circle-outline,.vjs-icon-cog,.vjs-icon-facebook,.vjs-icon-fullscreen-enter,.vjs-icon-fullscreen-exit,.vjs-icon-gplus,.vjs-icon-hd,.vjs-icon-linkedin,.vjs-icon-pause,.vjs-icon-pinterest,.vjs-icon-play,.vjs-icon-play-circle,.vjs-icon-replay,.vjs-icon-spinner,.vjs-icon-square,.vjs-icon-subtitles,.vjs-icon-tumblr,.vjs-icon-twitter,.vjs-icon-volume-high,.vjs-icon-volume-low,.vjs-icon-volume-mid,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js,.vjs-no-js{color:#fff;background-color:#000}.video-js .vjs-big-play-button:before,.video-js .vjs-control,.video-js .vjs-control:before,.vjs-menu li,.vjs-no-js{text-align:center}.video-js .vjs-big-play-button:before,.video-js .vjs-control:before,.video-js .vjs-modal-dialog,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}@font-face{font-family:VideoJS;src:url(font/VideoJS.eot?#iefix) format("eot")}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAA54AAoAAAAAFmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAAA9AAAAD4AAABWUZFeBWNtYXAAAAE0AAAAOgAAAUriMBC2Z2x5ZgAAAXAAAAouAAAPUFvx6AdoZWFkAAALoAAAACsAAAA2DIPpX2hoZWEAAAvMAAAAGAAAACQOogcgaG10eAAAC+QAAAAPAAAAfNkAAABsb2NhAAAL9AAAAEAAAABAMMg06m1heHAAAAw0AAAAHwAAACABMAB5bmFtZQAADFQAAAElAAACCtXH9aBwb3N0AAANfAAAAPwAAAGBZkSN43icY2BkZ2CcwMDKwMFSyPKMgYHhF4RmjmEIZzzHwMDEwMrMgBUEpLmmMDh8ZPwoxw7iLmSHCDOCCADvEAo+AAB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZgYGD7K/f8PUvCREUTzM0DVAwEjG8OIBwCPdwbVAAB4nI1Xe1CU1xX/zv1eLItLln0JwrIfC7sJGET2hRJ2N1GUoBJE8AESQEEhmBHjaB7UuBMTO4GMaSu7aY3RNlOdRPNqO2pqRmuTaSZtR6JJILUZk00a/4imjpmiecB303O/XUgMJOPufvd+99xzzz33nN855y4HHH7EfrGfIxwHRiANvF/sH71I9BzHszmpW+rGOQOXxXE6YhI4PoMT8zkT4cDFuf1cwMrZJI5cglM0HKVv0MaUFDgIFfg9mJJCG+kbKn1JkqBOVaFOkuhLpARq8fu0Nnc9/zdvfY9PxXW4PdH0C6N+PCejhorxFjAqRjgFRXSINEARbBGsoxcFK7IJmr4OycFJnInL59zIXwxui80fkGRbEHyosMWaATJKUfCskmwJQsAWANkmnIGOhlf514h7U8HNIv3owoHB0WMt0Eb3sx0guLi5pq/8Ny1q6969fKR9X9GBV6dPv6dp04K99SOwtmyPl47ApRa6n4ZpP1yjr5fn7MmYP/vXLUJs715UguklHBaHOZHZmG1N9FAIW2mf0MqWCIdo/8RZ1yGfxKUldDcGIbFA7ICO+vqOMSPTh/ZrSqgHi/bB/O8E8Mnzp+M+acxfpsTShBwej26TiGxBn7m4eEIO+Rueu6Hj+IFBnh88cAEUEQ//nVLx5C7kf+yIR47QEe+eMlhz9SqsGbe3hh2R03NGzoY6O42Kz8l7fB6fAk6LYnTyFo/FYyT6GGyNx2Jx2sdH4rA1Fo/HyCXaFyOp8dhYBCfJb2NIn1ImE6CYNGmgSTb52DawJR6jfXEmDU4xyTEmpgHHOIStoxfjSGdkbsK2w2jbdMQG4sgAstEONgURYCwGHhEhhscioQaAhhCf7McifEQc0l6+mxj9nI+gmSdiQ0Zbm7gZnIO7GSMEXG6UDAVocxAV8GcEXCKg1a02RcTtwANWRGIAyElor6n/+ZU2yOB3+T77Hb1MLqhn4KHVnQBjJnqe9QZSon6Kc5DxAD2vMdPL/BXSmQGwspa67z9wLUjdi9TN7QC7lyyBr9rpt7uXVC1CMpyjKRoXnGPHTuiaPLsNdc2dbAFQLAooPkXEh33FodHl4XpC6sPCIa0ftUIhHSYXVSu5iME+DIXsbZJ51BeidCgajcai43jU9nVzoSn2dPqcFvSoxSzJzgRKAx47WMRxOrIj3Wf0+hndxhJTiOkSEqxar3b3RKM9hY64oxBA64ieURLvCfpkDb8siBdUJ1bgT+urJ5PGfewQrmm5R5+0HmfyIPySD7OYkT0WxRePah8oEiyjlxIP74thVoRTURpmL6QhGuWS+QDjdANXjIM8SQa/1w128ODx0Qp4aLMNg9+JL3joUn8AMxW+aLNiuKjarn4uyyTdXjOzZTsh21uwldUvJoYza+zELALfu3p1L8/3krtyZ0Ag058J3hxHghvbGZn0dHZy6Mim/7Blre4lpHd1c28yVqRViO153F2oIWoXCIKbL4Z0cM1iaQn9mI5KuV2SzEvWXJDMNtkANpMdQoDDhIdD4A/YrP6Aye9ysxyE+uOEAcTDorgvVZJjcua043PnZ/PmdDqcbibZlXOOT8uSo7Kof0YUn9GL+Jo17ficymxiTofC6znUso0DhAxs1Fo+kF+d36vLmgZ8mk5cdGv2mwYj5k3Dm9m3LhJ1aVRNm6HrTbLgYAoWXDhDd/u4PGy5CT+xGMdiaBovewUCF/1BiWNljI9MLn7jeScpg+WyH6mfU62eVDql7hsrmvx1ezp/YldE2LhjbkiDnAn8tGy/MW3IXRMYJduvq9HpmIcKuFt+JCtgdGEGKAcF6UacVwIYbVPGfw/+YuNBS4cx/CUHcnyfc+wRDMtTr72mMSBjT/yn/GKSdeDWQUCH6Xoqq5R10RE60gV6erUL0iCti16d0hZjxut4QI/rEpgSh6WjnJXdBXRg1GKCucGJPtFqM27aD1tOqqKonsQ2KsFSSmEpmvRlsR+TcD9OFwrqXxIclL4sJTnGMSuG8KpkZvKdeVIOKDyWSyPLV16/p1QMPbP8NihwUzr47bdnXtwtjdCvqqpO0H+pOvIl3Pzv46e5CT/tQjklXCXXym1AaWY7bzHLkuDMc7ldKCvgxzLn8wYkJLBhEDyK7MT8bTbwbkxbfp+3mKAGsmTBpabSIEECzMIcQlzOPAMKsxMs7uhsnxPLuofPDTc1hkuq6MX9j16YU7CqegcYHbmWYuvAP6tCS97tgWf7dlQvnl25YPavXLVZvrzQPeHCpZmzzEUVq/xzu5sChnSTPTW7oOYmh69z4zL/gk3b+O6hoa733uviP82vnFcbqWlc9tDmZa23LVzaV1yXURi+JX+28NeBuj3+O8IrQ080Vm1eWB4OKjPmrJu7c1udWynvKF6/vs479lSW9+5gZkn+dKfellNGDPllzeULustz+A0bPvhgw7lkvEUwn/N4Ty7U7nhGsEpFkOfy+kutbOh1JQxhVDJumoW11hnkPThznh6FFlhfT+ra1x9sF56kx5YuDzVY9PQYAYA7iblw4frQ4TPCk2MK/xGU3rlmze62trHz6lsko+v+So/do74PT8KVkpJfOErKcv8znrMGsHTNxoEkWy1mYgDB6XBbPaWsuiS6CryGaL6zCjaXBgvtkuyXBua1wOKnh+k7L9AvPnYWffxK18FcJbuosGf3/Jo7amY+CE1vppzY+UTrva0FXc1i55pKQ/YjVL187N5fCn1kW5uot/1hi+DiZ+5atnJR9E+prvydJ9ZZ5mwOpU5gM4KYysMBQ71UzPuMTl9QQOyUo5nwioeYCPjFklrbK6s6X+ypUZ6rum9+CZYzWRiBJfSP0xzzSmrg7f86g0DKVj/wwFzieD9rRfPGFbeKMl05pn5j9/rsQJJ2iEgRrpohlyBo3f4QK7Kl+EcAYZgAoNVmZWXK704YAa3FwBxgSGUOs5htvGRz4Sgj3yFkSJFBuv/sxu5yk998T8WDJzvv/2RX19HtTUW1S+wpKRKRjJ6zzz/1/OPdFdWGlAKbvzS4PHOtURikg9AGz0LbIB85S/cPOpoXvuue8/iV2H1vPTy3ddvOeZ37HGmO3OmSzVzR+NS53+84dHlFhXPLqtzSO+5ruHM2vXtBdxP87LOzKAD359j/INYIbyPabIi3Cq6Wa+SaGe78diIzu7qcblcAa6/fJRvNopXFJnO+U9KKM5bqH5LM0iQSVmpPCPDu7ZT4Aoubz3709EBTyrTDjyx8MQXgUH1nqm7TWng4TzE4i4AsKskBITXfSyC4Fkl5MxnJDiKSIDSJAsGvd1y+/eNDp2e+A+5d8HeiiunrTkT6TqWLIs+/QRoWr98s0qj8uuzLuS22Ytufg3rdTaHn1m46sfgGKHXt0MGnLaRHdnwN37tvHcWKo2V6lnPxL4UvUQcRdOzmZSQs8X5CH5OxXMXpkATuDz8Et0SH4uyCRR+TjmBDP1GvsVrWEGVzEj33YVQ9jAtIKpqsl/s/0xrocwAAeJxjYGRgYADig3cEzsTz23xl4GZnAIHLRucNkWl2BrA4BwMTiAIAF4IITwB4nGNgZGBgZwCChWASxGZkQAXyABOUANh4nGNnYGBgHyAMADa8ANoAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqHicY2BkYGCQZ8hlYGcAASYg5gJCBob/YD4DABbVAaoAeJxdkE1qg0AYhl8Tk9AIoVDaVSmzahcF87PMARLIMoFAl0ZHY1BHdBJIT9AT9AQ9RQ9Qeqy+yteNMzDzfM+88w0K4BY/cNAMB6N2bUaPPBLukybCLvleeAAPj8JD+hfhMV7hC3u4wxs7OO4NzQSZcI/8Ltwnfwi75E/hAR7wJTyk/xYeY49fYQ/PztM+jbTZ7LY6OWdBJdX/pqs6NYWa+zMxa13oKrA6Uoerqi/JwtpYxZXJ1coUVmeZUWVlTjq0/tHacjmdxuL90OR8O0UEDYMNdtiSEpz5XQGqzlm30kzUdAYFFOb8R7NOZk0q2lwAyz1i7oAr1xoXvrOgtYhZx8wY5KRV269JZ5yGpmzPTjQhvY9je6vEElPOuJP3mWKnP5M3V+YAAAB4nG2P2XLCMAxFfYFspGUp3Te+IB9lHJF4cOzUS2n/voaEGR6qB+lKo+WITdhga/a/bRnDBFPMkCBFhhwF5ihxg1sssMQKa9xhg3s84BFPeMYLXvGGd3zgE9tZr/hveXKVkFYoSnoeHJXfRoWOqi54mo9ameNFdrK+dLSyaVf7oJQTlkhXpD3Z5XXhR/rUfQVuKXO91Jps4cLOS6/I5YL3XhodRRsVWZe4NnZOhWnSAWgxhMoEr6SmzZieF43Mk7ZOBdeCVGrp9Eu+54J2xhySplfB5XHwQLXUmT9KH6+kPnQ7ZYuIEzNyfs1DLU1VU4SWZ6LkXGHsD1ZKbMw=) format("woff"),url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMlGRXgUAAAEoAAAAVmNtYXDiMBC2AAAB/AAAAUpnbHlmW/HoBwAAA4gAAA9QaGVhZAyD6V8AAADQAAAANmhoZWEOogcgAAAArAAAACRobXR42QAAAAAAAYAAAAB8bG9jYTDINOoAAANIAAAAQG1heHABMAB5AAABCAAAACBuYW1l1cf1oAAAEtgAAAIKcG9zdGZEjeMAABTkAAABgQABAAAHAAAAAKEHAAAAAAAHAAABAAAAAAAAAAAAAAAAAAAAHwABAAAAAQAAwdxheF8PPPUACwcAAAAAANMyzzEAAAAA0zLPMQAAAAAHAAcAAAAACAACAAAAAAAAAAEAAAAfAG0ABwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQcAAZAABQAIBHEE5gAAAPoEcQTmAAADXABXAc4AAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA8QHxHgcAAAAAoQcAAAAAAAABAAAAAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAAAAAMAAAADAAAAHAABAAAAAABEAAMAAQAAABwABAAoAAAABgAEAAEAAgAA8R7//wAAAADxAf//AAAPAAABAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqAABAAAAAAWLBYsAAgAAAREBAlUDNgWL++oCCwAAAwAAAAAGawZrAAIADgAaAAAJAhMEAAMSAAUkABMCAAEmACc2ADcWABcGAALrAcD+QJX+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgIwAVABUAGbCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAAAAgAAAAAFQAWLAAMABwAAASERKQERIREBwAEr/tUCVQErAXUEFvvqBBYAAAAEAAAAAAYgBiAABgATACQAJwAAAS4BJxUXNjcGBxc+ATUmACcVFhIBBwEhESEBEQEGBxU+ATcXNwEHFwTQAWVVuAO7AidxJSgF/t/lpc77t18BYf6fASsBdQE+TF1OijuZX/1gnJwDgGSeK6W4GBhqW3FGnFT0AWM4mjT+9AHrX/6f/kD+iwH2/sI7HZoSRDGYXwSWnJwAAAEAAAAABKsF1gAFAAABESEBEQECCwEqAXb+igRg/kD+iwSq/osAAAACAAAAAAVmBdYABgAMAAABLgEnET4BAREhAREBBWUBZVRUZfwRASsBdf6LA4Bkniv9piueAUT+QP6LBKr+iwAAAwAAAAAGIAYPAAUADAAaAAATESEBEQEFLgEnET4BAxUWEhcGAgcVNgA3JgDgASsBdf6LAsUBZVVVZbqlzgMDzqXlASEFBf7fBGD+QP6LBKr+i+Bkniv9piueAvOaNP70tbX+9DSaOAFi9fUBYgAAAAQAAAAABYsFiwAFAAsAEQAXAAABIxEhNSMDMzUzNSEBIxUhESMDFTMVMxECC5YBduCWluD+igOA4AF2luDglgLr/oqWAgrglvyAlgF2AqCW4AF2AAQAAAAABYsFiwAFAAsAEQAXAAABMxUzESETIxUhESMBMzUzNSETNSMRITUBdeCW/org4AF2lgHAluD+ipaWAXYCVeABdgHAlgF2++rglgHA4P6KlgAAAAACAAAAAAXWBdYADwATAAABIQ4BBxEeARchPgE3ES4BAyERIQVA/IA/VQEBVT8DgD9VAQFVP/yAA4AF1QFVP/yAP1UBAVU/A4A/VfvsA4AAAAYAAAAABmsGawAHAAwAEwAbACAAKAAACQEmJw4BBwElLgEnAQUhATYSNyYFAQYCBxYXIQUeARcBMwEWFz4BNwECvgFkTlSH8GEBEgOONemh/u4C5f3QAXpcaAEB/BP+3VxoAQEOAjD95DXpoQESeP7dTlSH8GH+7gPwAmgSAQFYUP4nd6X2Pv4nS/1zZAEBk01NAfhk/v+TTUhLpfY+Adn+CBIBAVhQAdkAAAAFAAAAAAZrBdYADwATABcAGwAfAAABIQ4BBxEeARchPgE3ES4BASEVIQEhNSEFITUhNSE1IQXV+1ZAVAICVEAEqkBUAgJU+xYBKv7WAur9FgLqAcD+1gEq/RYC6gXVAVU//IA/VQEBVT8DgD9V/ayV/tWVlZWWlQADAAAAAAYgBdYADwAnAD8AAAEhDgEHER4BFyE+ATcRLgEBIzUjFTM1MxUUBgcjLgEnET4BNzMeARUFIzUjFTM1MxUOAQcjLgE1ETQ2NzMeARcFi/vqP1QCAlQ/BBY/VAICVP1rcJWVcCog4CAqAQEqIOAgKgILcJWVcAEqIOAgKiog4CAqAQXVAVU//IA/VQEBVT8DgD9V/fcl4CVKICoBASogASogKgEBKiBKJeAlSiAqAQEqIAEqICoBASogAAAGAAAAAAYgBPYAAwAHAAsADwATABcAABMzNSMRMzUjETM1IwEhNSERITUhERUhNeCVlZWVlZUBKwQV++sEFfvrBBUDNZb+QJUBwJX+QJb+QJUCVZWVAAAAAQAAAAAGIAZsAC4AAAEiBgcBNjQnAR4BMz4BNy4BJw4BBxQXAS4BIw4BBx4BFzI2NwEGBx4BFz4BNy4BBUArSh797AcHAg8eTixffwICf19ffwIH/fEeTixffwICf18sTh4CFAUBA3tcXHsDA3sCTx8bATcZNhkBNB0gAn9fX38CAn9fGxn+zRwgAn9fX38CIBz+yhcaXHsCAntcXXsAAAIAAAAABlkGawBDAE8AAAE2NCc3PgEnAy4BDwEmLwEuASchDgEPAQYHJyYGBwMGFh8BBhQXBw4BFxMeAT8BFh8BHgEXIT4BPwE2NxcWNjcTNiYnBS4BJz4BNx4BFw4BBasFBZ4KBgeWBxkNujpEHAMUD/7WDxQCHEU5ug0aB5UHBQudBQWdCwUHlQcaDbo5RRwCFA8BKg8UAhxFOboNGgeVBwUL/ThvlAIClG9vlAIClAM3JEokewkaDQEDDAkFSy0cxg4RAQERDsYcLUsFCQz+/QwbCXskSiR7CRoN/v0MCQVLLRzGDhEBAREOxhwtSwUJDAEDDBsJQQKUb2+UAgKUb2+UAAAAAAEAAAAABmsGawALAAATEgAFJAATAgAlBACVCAGmAT0BPQGmCAj+Wv7D/sP+WgOA/sP+WggIAaYBPQE9AaYICP5aAAAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAASYAJzYANxYAFwYAA4D+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgZrCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAADAAAAAAZrBmsACwAXACMAAAEEAAMSAAUkABMCAAEmACc2ADcWABcGAAMOAQcuASc+ATceAQOA/sP+WggIAaYBPQE9AaYICP5a/sP9/q4GBgFS/f0BUgYG/q4dAn9fX38CAn9fX38Gawj+Wv7D/sP+WggIAaYBPQE9Aab6yAYBUv39AVIGBv6u/f3+rgJPX38CAn9fX38CAn8AAAAEAAAAAAYgBiAADwAbACUAKQAAASEOAQcRHgEXIT4BNxEuAQEjNSMVIxEzFTM1OwEhHgEXEQ4BByE3MzUjBYv76j9UAgJUPwQWP1QCAlT9a3CVcHCVcJYBKiAqAQEqIP7WcJWVBiACVD/76j9UAgJUPwQWP1T8gpWVAcC7uwEqIP7WICoBcOAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAEwcJAScJATcJARcBA4D+w/5aCAgBpgE9AT0BpggI/lo4af70/vRpAQv+9WkBDAEMaf71BmsI/lr+w/7D/loICAGmAT0BPQGm/BFpAQv+9WkBDAEMaf71AQtp/vQAAQAAAAAF1ga2ABYAAAERCQERHgEXDgEHLgEnIxYAFzYANyYAA4D+iwF1vv0FBf2+vv0FlQYBUf7+AVEGBv6vBYsBKv6L/osBKgT9v779BQX9vv7+rwYGAVH+/gFRAAAAAQAAAAAFPwcAABQAAAERIyIGHQEhAyMRIREjETM1NDYzMgU/nVY8ASUn/v7O///QrZMG9P74SEi9/tj9CQL3ASjaus0AAAAABAAAAAAGjgcAADAARQBgAGwAAAEUHgMVFAcGBCMiJicmNTQ2NzYlLgE1NDcGIyImNTQ2Nz4BMyEHIx4BFRQOAycyNjc2NTQuAiMiBgcGFRQeAxMyPgI1NC4BLwEmLwImIyIOAxUUHgIBMxUjFSM1IzUzNTMDH0BbWkAwSP7qn4TlOSVZSoMBESAfFS4WlMtIP03TcAGiioNKTDFFRjGSJlAaNSI/akAqURkvFCs9WTY6a1s3Dg8THgocJU4QIDVob1M2RnF9A2vV1WnU1GkD5CRFQ1CATlpTenNTYDxHUYouUhIqQCkkMQTBlFKaNkJAWD+MWkhzRztAPiEbOWY6hn1SJyE7ZS5nZ1I0/JcaNF4+GTAkGCMLFx04Ag4kOF07Rms7HQNsbNvbbNkAAwAAAAAGgAZsAAMADgAqAAABESERARYGKwEiJjQ2MhYBESERNCYjIgYHBhURIRIQLwEhFSM+AzMyFgHd/rYBXwFnVAJSZGemZASP/rdRVj9VFQv+twIBAQFJAhQqR2c/q9AEj/whA98BMkliYpNhYfzd/cgCEml3RTMeM/3XAY8B8DAwkCAwOB/jAAABAAAAAAaUBgAAMQAAAQYHFhUUAg4BBCMgJxYzMjcuAScWMzI3LgE9ARYXLgE1NDcWBBcmNTQ2MzIXNjcGBzYGlENfAUyb1v7SrP7x4SMr4bBpph8hHCsqcJNETkJOLHkBW8YIvYaMYG1gJWldBWhiRQ4cgv797rdtkQSKAn1hBQsXsXUEJgMsjlNYS5WzCiYkhr1mFTlzPwoAAAABAAAAAAWABwAAIgAAARcOAQcGLgM1ESM1PgQ3PgE7AREhFSERFB4CNzYFMFAXsFlorXBOIahIckQwFAUBBwT0AU3+sg0gQzBOAc/tIz4BAjhceHg6AiDXGlddb1ctBQf+WPz9+h40NR4BAgABAAAAAAaABoAASgAAARQCBCMiJzY/AR4BMzI+ATU0LgEjIg4DFRQWFxY/ATY3NicmNTQ2MzIWFRQGIyImNz4CNTQmIyIGFRQXAwYXJgI1NBIkIAQSBoDO/p/Rb2s7EzYUaj15vmh34o5ptn9bK1BNHggIBgIGETPRqZepiWs9Sg4IJRc2Mj5WGWMRBM7+zgFhAaIBYc4DgNH+n84gXUfTJzmJ8JZyyH46YH2GQ2ieIAwgHxgGFxQ9WpfZpIOq7lc9I3VZHzJCclVJMf5eRmtbAXzp0QFhzs7+nwAABwAAAAAHAATPAA4AFwAqAD0AUABaAF0AAAERNh4CBw4BBwYmIycmNxY2NzYmBxEUBRY2Nz4BNy4BJyMGHwEeARcOARcWNjc+ATcuAScjBh8BHgEXFAYXFjY3PgE3LgEnIwYfAR4BFw4BBTM/ARUzESMGAyUVJwMchM2UWwgNq4JHrQgBAapUaAoJcWMBfiIhDiMrAQJLMB0BBAokNAIBPmMiIQ4iLAECSzAeAQUKJDQBP2MiIQ4iLAECSzAeAQUKJDQBAT75g+5B4arNLNIBJ44ByQL9BQ9mvYCKwA8FBQMDwwJVTGdzBf6VB8IHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvVJkAWUDDEf+tYP5AQAAAAEAAAAABiAGtgAbAAABBAADER4BFzMRITU2ADcWABcVIREzPgE3EQIAA4D+4v6FBwJ/X+D+1QYBJ97eAScG/tXgX38CB/6FBrUH/oX+4v32X38CAlWV3gEnBgb+2d6V/asCf18CCgEeAXsAAAAAEADGAAEAAAAAAAEABwAAAAEAAAAAAAIABwAHAAEAAAAAAAMABwAOAAEAAAAAAAQABwAVAAEAAAAAAAUACwAcAAEAAAAAAAYABwAnAAEAAAAAAAoAKwAuAAEAAAAAAAsAEwBZAAMAAQQJAAEADgBsAAMAAQQJAAIADgB6AAMAAQQJAAMADgCIAAMAAQQJAAQADgCWAAMAAQQJAAUAFgCkAAMAAQQJAAYADgC6AAMAAQQJAAoAVgDIAAMAAQQJAAsAJgEeVmlkZW9KU1JlZ3VsYXJWaWRlb0pTVmlkZW9KU1ZlcnNpb24gMS4wVmlkZW9KU0dlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAFYAaQBkAGUAbwBKAFMAUgBlAGcAdQBsAGEAcgBWAGkAZABlAG8ASgBTAFYAaQBkAGUAbwBKAFMAVgBlAHIAcwBpAG8AbgAgADEALgAwAFYAaQBkAGUAbwBKAFMARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAABAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8EcGxheQtwbGF5LWNpcmNsZQVwYXVzZQt2b2x1bWUtbXV0ZQp2b2x1bWUtbG93CnZvbHVtZS1taWQLdm9sdW1lLWhpZ2gQZnVsbHNjcmVlbi1lbnRlcg9mdWxsc2NyZWVuLWV4aXQGc3F1YXJlB3NwaW5uZXIJc3VidGl0bGVzCGNhcHRpb25zCGNoYXB0ZXJzBXNoYXJlA2NvZwZjaXJjbGUOY2lyY2xlLW91dGxpbmUTY2lyY2xlLWlubmVyLWNpcmNsZQJoZAZjYW5jZWwGcmVwbGF5CGZhY2Vib29rBWdwbHVzCGxpbmtlZGluB3R3aXR0ZXIGdHVtYmxyCXBpbnRlcmVzdBFhdWRpby1kZXNjcmlwdGlvbgVhdWRpbwAAAAAA) format("truetype");font-weight:400;font-style:normal}.video-js .vjs-big-play-button:before,.video-js .vjs-play-control:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0:before,.video-js .vjs-volume-menu-button.vjs-vol-0:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1:before,.video-js .vjs-volume-menu-button.vjs-vol-1:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2:before,.video-js .vjs-volume-menu-button.vjs-vol-2:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control:before,.video-js .vjs-volume-menu-button:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subtitles-button:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-mouse-display:before,.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before{content:"\f111"}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button:before,.vjs-icon-cancel:before{content:"\f115"}.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button:before,.vjs-icon-audio:before{content:"\f11e"}.video-js{display:block;vertical-align:top;box-sizing:border-box;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js .vjs-tech,.video-js.vjs-fill{width:100%;height:100%}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin:0}.vjs-error .vjs-error-display:before,.vjs-menu .vjs-menu-content,.vjs-no-js{font-family:Arial,Helvetica,sans-serif}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js .vjs-tech{position:absolute;top:0;left:0}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;font-size:18px;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66A8CC}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.5em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2B333F;background-color:rgba(43,51,63,.7);-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.75em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{outline:0;border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);-webkit-transition:all 0s;-moz-transition:all 0s;-o-transition:all 0s;transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;overflow:visible;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;overflow:auto}.vjs-scrubbing .vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-transform:lowercase}.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{outline:0;background-color:#73859f;background-color:rgba(115,133,159,.5)}.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2B333F}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2B333F;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.video-js .vjs-menu-button-inline.vjs-slider-active{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2B333F;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;visibility:visible;opacity:1;-webkit-transition:visibility .1s,opacity .1s;-moz-transition:visibility .1s,opacity .1s;-o-transition:visibility .1s,opacity .1s;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{outline:0;position:relative;margin:0;padding:0;height:100%;width:4em;-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none}.video-js .vjs-control:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{-webkit-box-flex:auto;-moz-box-flex:auto;-webkit-flex:auto;-ms-flex:auto;flex:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;min-width:4em}.vjs-live .vjs-progress-control{display:none}.video-js .vjs-progress-holder{-webkit-box-flex:auto;-moz-box-flex:auto;-webkit-flex:auto;-ms-flex:auto;flex:auto;-webkit-transition:all .2s;-moz-transition:all .2s;-o-transition:all .2s;transition:all .2s;height:.3em}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.666666666666666666em}.video-js .vjs-progress-control:hover .vjs-mouse-display:after,.video-js .vjs-progress-control:hover .vjs-play-progress:after,.video-js .vjs-progress-control:hover .vjs-time-tooltip{font-family:Arial,Helvetica,sans-serif;visibility:visible;font-size:.6em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress,.video-js .vjs-progress-holder .vjs-tooltip-progress-bar{position:absolute;display:block;height:.3em;margin:0;padding:0;width:0;left:0;top:0}.video-js .vjs-mouse-display:before,.video-js .vjs-progress-control .vjs-keep-tooltips-inside:after{display:none}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{position:absolute;top:-.333333333333333em;right:-.5em;font-size:.9em}.video-js .vjs-mouse-display:after,.video-js .vjs-play-progress:after,.video-js .vjs-time-tooltip{visibility:hidden;pointer-events:none;position:absolute;top:-3.4em;right:-1.9em;font-size:.9em;color:#000;content:attr(data-current-time);padding:6px 8px 8px;background-color:#fff;background-color:rgba(255,255,255,.8);-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em}.video-js .vjs-play-progress:after,.video-js .vjs-play-progress:before,.video-js .vjs-time-tooltip{z-index:1}.video-js .vjs-load-progress{background:#bfc7d3;background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:#fff;background:rgba(115,133,159,.75)}.video-js.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-time-tooltip{display:inline-block;height:2.4em;position:relative;float:right;right:-1.9em}.vjs-tooltip-progress-bar{visibility:hidden}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display,.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display:after{visibility:hidden;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display,.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display:after{display:none}.video-js .vjs-progress-control .vjs-mouse-display:after,.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{outline:0;position:relative;cursor:pointer;padding:0;margin:0 .45em;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control,.video-js .vjs-volume-menu-button{cursor:pointer;-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none}.video-js .vjs-volume-control{width:5em;-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu{display:block;width:0;height:0;border-top-color:transparent}.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu{left:.5em;height:8em}.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu{left:-2em}.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu-content{height:0;width:0;overflow-x:hidden;overflow-y:hidden}.vjs-volume-menu-button-vertical .vjs-lock-showing .vjs-menu-content,.vjs-volume-menu-button-vertical.vjs-slider-active .vjs-menu-content,.vjs-volume-menu-button-vertical:focus .vjs-menu-content,.vjs-volume-menu-button-vertical:hover .vjs-menu-content{height:8em;width:2.9em}.vjs-volume-menu-button-horizontal .vjs-lock-showing .vjs-menu-content,.vjs-volume-menu-button-horizontal .vjs-slider-active .vjs-menu-content,.vjs-volume-menu-button-horizontal:focus .vjs-menu-content,.vjs-volume-menu-button-horizontal:hover .vjs-menu-content{height:2.9em;width:8em}.vjs-volume-menu-button.vjs-menu-button-inline .vjs-menu-content{background-color:transparent!important}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-poster img{display:block;vertical-align:middle;margin:0 auto;max-height:100%;padding:0;width:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-controls-disabled .vjs-poster,.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-flex:auto;-moz-box-flex:auto;-webkit-flex:auto;-ms-flex:auto;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js .vjs-current-time,.video-js .vjs-duration,.vjs-live .vjs-time-control,.vjs-live .vjs-time-divider,.vjs-no-flex .vjs-current-time,.vjs-no-flex .vjs-duration{display:none}.video-js .vjs-time-control{-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-time-divider{display:none;line-height:3em}.video-js .vjs-play-control{cursor:pointer;-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em;background-color:#000;background-color:rgba(0,0,0,.5)}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{-moz-transform:translateY(-3em);-ms-transform:translateY(-3em);-o-transform:translateY(-3em);-webkit-transform:translateY(-3em);transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{-moz-transform:translateY(-1.5em);-ms-transform:translateY(-1.5em);-o-transform:translateY(-1.5em);-webkit-transform:translateY(-1.5em);transform:translateY(-1.5em)}.video-js .vjs-fullscreen-control{cursor:pointer;-webkit-box-flex:none;-moz-box-flex:none;-webkit-flex:none;-ms-flex:none;flex:none}.vjs-playback-rate .vjs-playback-rate-value{font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:'X';font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:#fff transparent transparent}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%,100%,20%,60%{border-top-color:#73859f}35%{border-top-color:#fff}}@-webkit-keyframes vjs-spinner-fade{0%,100%,20%,60%{border-top-color:#73859f}35%{border-top-color:#fff}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer{-webkit-box-flex:auto;-moz-box-flex:auto;-webkit-flex:auto;-ms-flex:auto;flex:auto}.video-js.vjs-layout-tiny:not(.vjs-fullscreen).vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-subtitles-button .vjs-audio-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-volume-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-audio-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-progress-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-subtitles-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-menu-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-audio-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-subtitles-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-control,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-menu-button{display:none}.vjs-caption-settings{position:relative;top:1em;background-color:#2B333F;background-color:rgba(43,51,63,.75);color:#fff;margin:0 auto;padding:.5em;height:16em;font-size:12px;width:40em}.vjs-caption-settings .vjs-tracksettings{top:0;bottom:1em;left:0;right:0;position:absolute;overflow:auto}.vjs-caption-settings .vjs-tracksettings-colors,.vjs-caption-settings .vjs-tracksettings-font{float:left}.vjs-caption-settings .vjs-tracksettings-colors:after,.vjs-caption-settings .vjs-tracksettings-controls:after,.vjs-caption-settings .vjs-tracksettings-font:after{clear:both}.vjs-caption-settings .vjs-tracksettings-controls{position:absolute;bottom:1em;right:1em}.vjs-caption-settings .vjs-tracksetting{margin:5px;padding:3px;min-height:40px;border:none}.vjs-caption-settings .vjs-tracksetting label,.vjs-caption-settings .vjs-tracksetting legend{display:block;width:100px;margin-bottom:5px}.vjs-caption-settings .vjs-tracksetting span{display:inline;margin-left:5px;vertical-align:top;float:right}.vjs-caption-settings .vjs-tracksetting>div{margin-bottom:5px;min-height:20px}.vjs-caption-settings .vjs-tracksetting>div:last-child{margin-bottom:0;padding-bottom:0;min-height:0}.vjs-caption-settings label>input{margin-right:10px}.vjs-caption-settings fieldset{margin-top:1em;margin-left:.5em}.vjs-caption-settings fieldset .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-caption-settings input[type=button]{width:40px;height:40px}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:-webkit-linear-gradient(-90deg,rgba(0,0,0,.8),rgba(255,255,255,0));background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0))}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}@media \0screen{.vjs-user-inactive.vjs-playing .vjs-control-bar :before{content:""}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:hidden}}
\ No newline at end of file diff --git a/addons/webinterface.default/lib/video-js/video-js.swf b/addons/webinterface.default/lib/video-js/video-js.swf Binary files differnew file mode 100644 index 0000000000..34ca9dc0b4 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/video-js.swf diff --git a/addons/webinterface.default/lib/video-js/video.js b/addons/webinterface.default/lib/video-js/video.js new file mode 100644 index 0000000000..1bc87dc0a1 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/video.js @@ -0,0 +1,26667 @@ +/** + * @license + * Video.js 5.15.1 <http://videojs.com/> + * Copyright Brightcove, Inc. <https://www.brightcove.com/> + * Available under Apache License Version 2.0 + * <https://github.com/videojs/video.js/blob/master/LICENSE> + * + * Includes vtt.js <https://github.com/mozilla/vtt.js> + * Available under Apache License Version 2.0 + * <https://github.com/mozilla/vtt.js/blob/master/LICENSE> + */ + +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _button = _dereq_(2); + +var _button2 = _interopRequireDefault(_button); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file big-play-button.js + */ + + +/** + * The initial play button that shows before the video has played. The hiding of the + * `BigPlayButton` get done via CSS and `Player` states. + * + * @extends Button + */ +var BigPlayButton = function (_Button) { + _inherits(BigPlayButton, _Button); + + function BigPlayButton() { + _classCallCheck(this, BigPlayButton); + + return _possibleConstructorReturn(this, _Button.apply(this, arguments)); + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. Always returns 'vjs-big-play-button'. + */ + BigPlayButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-big-play-button'; + }; + + /** + * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent} + * for more detailed information on what a click can be. + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + BigPlayButton.prototype.handleClick = function handleClick(event) { + this.player_.play(); + }; + + return BigPlayButton; +}(_button2['default']); + +/** + * The text that should display over the `BigPlayButton`s controls. Added to for localization. + * + * @type {string} + * @private + */ + + +BigPlayButton.prototype.controlText_ = 'Play Video'; + +_component2['default'].registerComponent('BigPlayButton', BigPlayButton); +exports['default'] = BigPlayButton; + +},{"2":2,"5":5}],2:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _clickableComponent = _dereq_(3); + +var _clickableComponent2 = _interopRequireDefault(_clickableComponent); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _obj = _dereq_(88); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file button.js + */ + + +/** + * Base class for all buttons. + * + * @extends ClickableComponent + */ +var Button = function (_ClickableComponent) { + _inherits(Button, _ClickableComponent); + + function Button() { + _classCallCheck(this, Button); + + return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments)); + } + + /** + * Create the `Button`s DOM element. + * + * @param {string} [tag=button] + * Element's node type. e.g. 'button' + * + * @param {Object} [props={}] + * An object of properties that should be set on the element. + * + * @param {Object} [attributes={}] + * An object of attributes that should be set on the element. + * + * @return {Element} + * The element that gets created. + */ + Button.prototype.createEl = function createEl() { + var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button'; + var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + props = (0, _obj.assign)({ + className: this.buildCSSClass() + }, props); + + if (tag !== 'button') { + _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); + + // Add properties for clickable element which is not a native HTML button + props = (0, _obj.assign)({ + tabIndex: 0 + }, props); + + // Add ARIA attributes for clickable element which is not a native HTML button + attributes = (0, _obj.assign)({ + role: 'button' + }, attributes); + } + + // Add attributes for button element + attributes = (0, _obj.assign)({ + + // Necessary since the default button type is "submit" + 'type': 'button', + + // let the screen reader user know that the text of the button may change + 'aria-live': 'polite' + }, attributes); + + var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); + + this.createControlTextEl(el); + + return el; + }; + + /** + * Add a child `Component` inside of this `Button`. + * + * @param {string|Component} child + * The name or instance of a child to add. + * + * @param {Object} [options={}] + * The key/value store of options that will get passed to children of + * the child. + * + * @return {Component} + * The `Component` that gets added as a child. When using a string the + * `Component` will get created by this process. + * + * @deprecated since version 5 + */ + + + Button.prototype.addChild = function addChild(child) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var className = this.constructor.name; + + _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); + + // Avoid the error message generated by ClickableComponent's addChild method + return _component2['default'].prototype.addChild.call(this, child, options); + }; + + /** + * Enable the `Button` element so that it can be activated or clicked. Use this with + * {@link Button#disable}. + */ + + + Button.prototype.enable = function enable() { + _ClickableComponent.prototype.enable.call(this); + this.el_.removeAttribute('disabled'); + }; + + /** + * Enable the `Button` element so that it cannot be activated or clicked. Use this with + * {@link Button#enable}. + */ + + + Button.prototype.disable = function disable() { + _ClickableComponent.prototype.disable.call(this); + this.el_.setAttribute('disabled', 'disabled'); + }; + + /** + * This gets called when a `Button` has focus and `keydown` is triggered via a key + * press. + * + * @param {EventTarget~Event} event + * The event that caused this function to get called. + * + * @listens keydown + */ + + + Button.prototype.handleKeyPress = function handleKeyPress(event) { + + // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. + if (event.which === 32 || event.which === 13) { + return; + } + + // Pass keypress handling up for unsupported keys + _ClickableComponent.prototype.handleKeyPress.call(this, event); + }; + + return Button; +}(_clickableComponent2['default']); + +_component2['default'].registerComponent('Button', Button); +exports['default'] = Button; + +},{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _obj = _dereq_(88); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file button.js + */ + + +/** + * Clickable Component which is clickable or keyboard actionable, + * but is not a native HTML button. + * + * @extends Component + */ +var ClickableComponent = function (_Component) { + _inherits(ClickableComponent, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function ClickableComponent(player, options) { + _classCallCheck(this, ClickableComponent); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.emitTapEvents(); + + _this.enable(); + return _this; + } + + /** + * Create the `Component`s DOM element. + * + * @param {string} [tag=div] + * The element's node type. + * + * @param {Object} [props={}] + * An object of properties that should be set on the element. + * + * @param {Object} [attributes={}] + * An object of attributes that should be set on the element. + * + * @return {Element} + * The element that gets created. + */ + + + ClickableComponent.prototype.createEl = function createEl() { + var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; + var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + props = (0, _obj.assign)({ + className: this.buildCSSClass(), + tabIndex: 0 + }, props); + + if (tag === 'button') { + _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); + } + + // Add ARIA attributes for clickable element which is not a native HTML button + attributes = (0, _obj.assign)({ + 'role': 'button', + + // let the screen reader user know that the text of the element may change + 'aria-live': 'polite' + }, attributes); + + this.tabIndex_ = props.tabIndex; + + var el = _Component.prototype.createEl.call(this, tag, props, attributes); + + this.createControlTextEl(el); + + return el; + }; + + /** + * Create a control text element on this `Component` + * + * @param {Element} [el] + * Parent element for the control text. + * + * @return {Element} + * The control text element that gets created. + */ + + + ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { + this.controlTextEl_ = Dom.createEl('span', { + className: 'vjs-control-text' + }); + + if (el) { + el.appendChild(this.controlTextEl_); + } + + this.controlText(this.controlText_, el); + + return this.controlTextEl_; + }; + + /** + * Get or set the localize text to use for the controls on the `Component`. + * + * @param {string} [text] + * Control text for element. + * + * @param {Element} [el=this.el()] + * Element to set the title on. + * + * @return {string|ClickableComponent} + * - The control text when getting + * - Returns itself when setting; method can be chained. + */ + + + ClickableComponent.prototype.controlText = function controlText(text) { + var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el(); + + if (!text) { + return this.controlText_ || 'Need Text'; + } + + var localizedText = this.localize(text); + + this.controlText_ = text; + this.controlTextEl_.innerHTML = localizedText; + el.setAttribute('title', localizedText); + + return this; + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); + }; + + /** + * Enable this `Component`s element. + * + * @return {ClickableComponent} + * Returns itself; method can be chained. + */ + + + ClickableComponent.prototype.enable = function enable() { + this.removeClass('vjs-disabled'); + this.el_.setAttribute('aria-disabled', 'false'); + if (typeof this.tabIndex_ !== 'undefined') { + this.el_.setAttribute('tabIndex', this.tabIndex_); + } + this.on('tap', this.handleClick); + this.on('click', this.handleClick); + this.on('focus', this.handleFocus); + this.on('blur', this.handleBlur); + return this; + }; + + /** + * Disable this `Component`s element. + * + * @return {ClickableComponent} + * Returns itself; method can be chained. + */ + + + ClickableComponent.prototype.disable = function disable() { + this.addClass('vjs-disabled'); + this.el_.setAttribute('aria-disabled', 'true'); + if (typeof this.tabIndex_ !== 'undefined') { + this.el_.removeAttribute('tabIndex'); + } + this.off('tap', this.handleClick); + this.off('click', this.handleClick); + this.off('focus', this.handleFocus); + this.off('blur', this.handleBlur); + return this; + }; + + /** + * This gets called when a `ClickableComponent` gets: + * - Clicked (via the `click` event, listening starts in the constructor) + * - Tapped (via the `tap` event, listening starts in the constructor) + * - The following things happen in order: + * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the + * `ClickableComponent`. + * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using + * {@link ClickableComponent#handleKeyPress}. + * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses + * the space or enter key. + * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown` + * event as a parameter. + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + * @abstract + */ + + + ClickableComponent.prototype.handleClick = function handleClick(event) {}; + + /** + * This gets called when a `ClickableComponent` gains focus via a `focus` event. + * Turns on listening for `keydown` events. When they happen it + * calls `this.handleKeyPress`. + * + * @param {EventTarget~Event} event + * The `focus` event that caused this function to be called. + * + * @listens focus + */ + + + ClickableComponent.prototype.handleFocus = function handleFocus(event) { + Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); + }; + + /** + * Called when this ClickableComponent has focus and a key gets pressed down. By + * default it will call `this.handleClick` when the key is space or enter. + * + * @param {EventTarget~Event} event + * The `keydown` event that caused this function to be called. + * + * @listens keydown + */ + + + ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) { + + // Support Space (32) or Enter (13) key operation to fire a click event + if (event.which === 32 || event.which === 13) { + event.preventDefault(); + this.handleClick(event); + } else if (_Component.prototype.handleKeyPress) { + + // Pass keypress handling up for unsupported keys + _Component.prototype.handleKeyPress.call(this, event); + } + }; + + /** + * Called when a `ClickableComponent` loses focus. Turns off the listener for + * `keydown` events. Which Stops `this.handleKeyPress` from getting called. + * + * @param {EventTarget~Event} event + * The `blur` event that caused this function to be called. + * + * @listens blur + */ + + + ClickableComponent.prototype.handleBlur = function handleBlur(event) { + Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); + }; + + return ClickableComponent; +}(_component2['default']); + +_component2['default'].registerComponent('ClickableComponent', ClickableComponent); +exports['default'] = ClickableComponent; + +},{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _button = _dereq_(2); + +var _button2 = _interopRequireDefault(_button); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file close-button.js + */ + + +/** + * The `CloseButton` is a `{@link Button}` that fires a `close` event when + * it gets clicked. + * + * @extends Button + */ +var CloseButton = function (_Button) { + _inherits(CloseButton, _Button); + + /** + * Creates an instance of the this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function CloseButton(player, options) { + _classCallCheck(this, CloseButton); + + var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); + + _this.controlText(options && options.controlText || _this.localize('Close')); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + CloseButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); + }; + + /** + * This gets called when a `CloseButton` gets clicked. See + * {@link ClickableComponent#handleClick} for more information on when this will be + * triggered + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + * @fires CloseButton#close + */ + + + CloseButton.prototype.handleClick = function handleClick(event) { + + /** + * Triggered when the a `CloseButton` is clicked. + * + * @event CloseButton#close + * @type {EventTarget~Event} + * + * @property {boolean} [bubbles=false] + * set to false so that the close event does not + * bubble up to parents if there is no listener + */ + this.trigger({ type: 'close', bubbles: false }); + }; + + return CloseButton; +}(_button2['default']); + +_component2['default'].registerComponent('CloseButton', CloseButton); +exports['default'] = CloseButton; + +},{"2":2,"5":5}],5:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _guid = _dereq_(85); + +var Guid = _interopRequireWildcard(_guid); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** + * Player Component - Base class for all UI objects + * + * @file component.js + */ + + +/** + * Base class for all UI Components. + * Components are UI objects which represent both a javascript object and an element + * in the DOM. They can be children of other components, and can have + * children themselves. + * + * Components can also use methods from {@link EventTarget} + */ +var Component = function () { + + /** + * A callback that is called when a component is ready. Does not have any + * paramters and any callback value will be ignored. + * + * @callback Component~ReadyCallback + * @this Component + */ + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + # + * @param {Object[]} [options.children] + * An array of children objects to intialize this component with. Children objects have + * a name property that will be used if more than one component of the same type needs to be + * added. + * + * @param {Component~ReadyCallback} [ready] + * Function that gets called when the `Component` is ready. + */ + function Component(player, options, ready) { + _classCallCheck(this, Component); + + // The component might be the player itself and we can't pass `this` to super + if (!player && this.play) { + this.player_ = player = this; // eslint-disable-line + } else { + this.player_ = player; + } + + // Make a copy of prototype.options_ to protect against overriding defaults + this.options_ = (0, _mergeOptions2['default'])({}, this.options_); + + // Updated options with supplied options + options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options); + + // Get ID from options or options element if one is supplied + this.id_ = options.id || options.el && options.el.id; + + // If there was no ID from the options, generate one + if (!this.id_) { + // Don't require the player ID function in the case of mock players + var id = player && player.id && player.id() || 'no_player'; + + this.id_ = id + '_component_' + Guid.newGUID(); + } + + this.name_ = options.name || null; + + // Create element if one wasn't provided in options + if (options.el) { + this.el_ = options.el; + } else if (options.createEl !== false) { + this.el_ = this.createEl(); + } + + this.children_ = []; + this.childIndex_ = {}; + this.childNameIndex_ = {}; + + // Add any child components in options + if (options.initChildren !== false) { + this.initChildren(); + } + + this.ready(ready); + // Don't want to trigger ready here or it will before init is actually + // finished for all children that run this constructor + + if (options.reportTouchActivity !== false) { + this.enableTouchActivity(); + } + } + + /** + * Dispose of the `Component` and all child components. + * + * @fires Component#dispose + */ + + + Component.prototype.dispose = function dispose() { + + /** + * Triggered when a `Component` is disposed. + * + * @event Component#dispose + * @type {EventTarget~Event} + * + * @property {boolean} [bubbles=false] + * set to false so that the close event does not + * bubble up + */ + this.trigger({ type: 'dispose', bubbles: false }); + + // Dispose all children. + if (this.children_) { + for (var i = this.children_.length - 1; i >= 0; i--) { + if (this.children_[i].dispose) { + this.children_[i].dispose(); + } + } + } + + // Delete child references + this.children_ = null; + this.childIndex_ = null; + this.childNameIndex_ = null; + + // Remove all event listeners. + this.off(); + + // Remove element from DOM + if (this.el_.parentNode) { + this.el_.parentNode.removeChild(this.el_); + } + + Dom.removeElData(this.el_); + this.el_ = null; + }; + + /** + * Return the {@link Player} that the `Component` has attached to. + * + * @return {Player} + * The player that this `Component` has attached to. + */ + + + Component.prototype.player = function player() { + return this.player_; + }; + + /** + * Deep merge of options objects with new options. + * > Note: When both `obj` and `options` contain properties whose values are objects. + * The two properties get merged using {@link module:mergeOptions} + * + * @param {Object} obj + * The object that contains new options. + * + * @return {Object} + * A new object of `this.options_` and `obj` merged together. + * + * @deprecated since version 5 + */ + + + Component.prototype.options = function options(obj) { + _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); + + if (!obj) { + return this.options_; + } + + this.options_ = (0, _mergeOptions2['default'])(this.options_, obj); + return this.options_; + }; + + /** + * Get the `Component`s DOM element + * + * @return {Element} + * The DOM element for this `Component`. + */ + + + Component.prototype.el = function el() { + return this.el_; + }; + + /** + * Create the `Component`s DOM element. + * + * @param {string} [tagName] + * Element's DOM node type. e.g. 'div' + * + * @param {Object} [properties] + * An object of properties that should be set. + * + * @param {Object} [attributes] + * An object of attributes that should be set. + * + * @return {Element} + * The element that gets created. + */ + + + Component.prototype.createEl = function createEl(tagName, properties, attributes) { + return Dom.createEl(tagName, properties, attributes); + }; + + /** + * Localize a string given the string in english. + * + * @param {string} string + * The string to localize. + * + * @return {string} + * The localized string or if no localization exists the english string. + */ + + + Component.prototype.localize = function localize(string) { + var code = this.player_.language && this.player_.language(); + var languages = this.player_.languages && this.player_.languages(); + + if (!code || !languages) { + return string; + } + + var language = languages[code]; + + if (language && language[string]) { + return language[string]; + } + + var primaryCode = code.split('-')[0]; + var primaryLang = languages[primaryCode]; + + if (primaryLang && primaryLang[string]) { + return primaryLang[string]; + } + + return string; + }; + + /** + * Return the `Component`s DOM element. This is where children get inserted. + * This will usually be the the same as the element returned in {@link Component#el}. + * + * @return {Element} + * The content element for this `Component`. + */ + + + Component.prototype.contentEl = function contentEl() { + return this.contentEl_ || this.el_; + }; + + /** + * Get this `Component`s ID + * + * @return {string} + * The id of this `Component` + */ + + + Component.prototype.id = function id() { + return this.id_; + }; + + /** + * Get the `Component`s name. The name gets used to reference the `Component` + * and is set during registration. + * + * @return {string} + * The name of this `Component`. + */ + + + Component.prototype.name = function name() { + return this.name_; + }; + + /** + * Get an array of all child components + * + * @return {Array} + * The children + */ + + + Component.prototype.children = function children() { + return this.children_; + }; + + /** + * Returns the child `Component` with the given `id`. + * + * @param {string} id + * The id of the child `Component` to get. + * + * @return {Component|undefined} + * The child `Component` with the given `id` or undefined. + */ + + + Component.prototype.getChildById = function getChildById(id) { + return this.childIndex_[id]; + }; + + /** + * Returns the child `Component` with the given `name`. + * + * @param {string} name + * The name of the child `Component` to get. + * + * @return {Component|undefined} + * The child `Component` with the given `name` or undefined. + */ + + + Component.prototype.getChild = function getChild(name) { + if (!name) { + return; + } + + name = (0, _toTitleCase2['default'])(name); + + return this.childNameIndex_[name]; + }; + + /** + * Add a child `Component` inside the current `Component`. + * + * + * @param {string|Component} child + * The name or instance of a child to add. + * + * @param {Object} [options={}] + * The key/value store of options that will get passed to children of + * the child. + * + * @param {number} [index=this.children_.length] + * The index to attempt to add a child into. + * + * @return {Component} + * The `Component` that gets added as a child. When using a string the + * `Component` will get created by this process. + */ + + + Component.prototype.addChild = function addChild(child) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length; + + var component = void 0; + var componentName = void 0; + + // If child is a string, create component with options + if (typeof child === 'string') { + componentName = (0, _toTitleCase2['default'])(child); + + // Options can also be specified as a boolean, + // so convert to an empty object if false. + if (!options) { + options = {}; + } + + // Same as above, but true is deprecated so show a warning. + if (options === true) { + _log2['default'].warn('Initializing a child component with `true` is deprecated.' + 'Children should be defined in an array when possible, ' + 'but if necessary use an object instead of `true`.'); + options = {}; + } + + var componentClassName = options.componentClass || componentName; + + // Set name through options + options.name = componentName; + + // Create a new object & element for this controls set + // If there's no .player_, this is a player + var ComponentClass = Component.getComponent(componentClassName); + + if (!ComponentClass) { + throw new Error('Component ' + componentClassName + ' does not exist'); + } + + // data stored directly on the videojs object may be + // misidentified as a component to retain + // backwards-compatibility with 4.x. check to make sure the + // component class can be instantiated. + if (typeof ComponentClass !== 'function') { + return null; + } + + component = new ComponentClass(this.player_ || this, options); + + // child is a component instance + } else { + component = child; + } + + this.children_.splice(index, 0, component); + + if (typeof component.id === 'function') { + this.childIndex_[component.id()] = component; + } + + // If a name wasn't used to create the component, check if we can use the + // name function of the component + componentName = componentName || component.name && component.name(); + + if (componentName) { + this.childNameIndex_[componentName] = component; + } + + // Add the UI object's element to the container div (box) + // Having an element is not required + if (typeof component.el === 'function' && component.el()) { + var childNodes = this.contentEl().children; + var refNode = childNodes[index] || null; + + this.contentEl().insertBefore(component.el(), refNode); + } + + // Return so it can stored on parent object if desired. + return component; + }; + + /** + * Remove a child `Component` from this `Component`s list of children. Also removes + * the child `Component`s element from this `Component`s element. + * + * @param {Component} component + * The child `Component` to remove. + */ + + + Component.prototype.removeChild = function removeChild(component) { + if (typeof component === 'string') { + component = this.getChild(component); + } + + if (!component || !this.children_) { + return; + } + + var childFound = false; + + for (var i = this.children_.length - 1; i >= 0; i--) { + if (this.children_[i] === component) { + childFound = true; + this.children_.splice(i, 1); + break; + } + } + + if (!childFound) { + return; + } + + this.childIndex_[component.id()] = null; + this.childNameIndex_[component.name()] = null; + + var compEl = component.el(); + + if (compEl && compEl.parentNode === this.contentEl()) { + this.contentEl().removeChild(component.el()); + } + }; + + /** + * Add and initialize default child `Component`s based upon options. + */ + + + Component.prototype.initChildren = function initChildren() { + var _this = this; + + var children = this.options_.children; + + if (children) { + (function () { + // `this` is `parent` + var parentOptions = _this.options_; + + var handleAdd = function handleAdd(child) { + var name = child.name; + var opts = child.opts; + + // Allow options for children to be set at the parent options + // e.g. videojs(id, { controlBar: false }); + // instead of videojs(id, { children: { controlBar: false }); + if (parentOptions[name] !== undefined) { + opts = parentOptions[name]; + } + + // Allow for disabling default components + // e.g. options['children']['posterImage'] = false + if (opts === false) { + return; + } + + // Allow options to be passed as a simple boolean if no configuration + // is necessary. + if (opts === true) { + opts = {}; + } + + // We also want to pass the original player options + // to each component as well so they don't need to + // reach back into the player for options later. + opts.playerOptions = _this.options_.playerOptions; + + // Create and add the child component. + // Add a direct reference to the child by name on the parent instance. + // If two of the same component are used, different names should be supplied + // for each + var newChild = _this.addChild(name, opts); + + if (newChild) { + _this[name] = newChild; + } + }; + + // Allow for an array of children details to passed in the options + var workingChildren = void 0; + var Tech = Component.getComponent('Tech'); + + if (Array.isArray(children)) { + workingChildren = children; + } else { + workingChildren = Object.keys(children); + } + + workingChildren + // children that are in this.options_ but also in workingChildren would + // give us extra children we do not want. So, we want to filter them out. + .concat(Object.keys(_this.options_).filter(function (child) { + return !workingChildren.some(function (wchild) { + if (typeof wchild === 'string') { + return child === wchild; + } + return child === wchild.name; + }); + })).map(function (child) { + var name = void 0; + var opts = void 0; + + if (typeof child === 'string') { + name = child; + opts = children[name] || _this.options_[name] || {}; + } else { + name = child.name; + opts = child; + } + + return { name: name, opts: opts }; + }).filter(function (child) { + // we have to make sure that child.name isn't in the techOrder since + // techs are registerd as Components but can't aren't compatible + // See https://github.com/videojs/video.js/issues/2772 + var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name)); + + return c && !Tech.isTech(c); + }).forEach(handleAdd); + })(); + } + }; + + /** + * Builds the default DOM class name. Should be overriden by sub-components. + * + * @return {string} + * The DOM class name for this object. + * + * @abstract + */ + + + Component.prototype.buildCSSClass = function buildCSSClass() { + // Child classes can include a function that does: + // return 'CLASS NAME' + this._super(); + return ''; + }; + + /** + * Add an `event listener` to this `Component`s element. + * + * The benefit of using this over the following: + * - `VjsEvents.on(otherElement, 'eventName', myFunc)` + * - `otherComponent.on('eventName', myFunc)` + * + * 1. Is that the listeners will get cleaned up when either component gets disposed. + * 1. It will also bind `myComponent` as the context of `myFunc`. + * > NOTE: If you remove the element from the DOM that has used `on` you need to + * clean up references using: `myComponent.trigger(el, 'dispose')` + * This will also allow the browser to garbage collect it. In special + * cases such as with `window` and `document`, which are both permanent, + * this is not necessary. + * + * @param {string|Component|string[]} [first] + * The event name, and array of event names, or another `Component`. + * + * @param {EventTarget~EventListener|string|string[]} [second] + * The listener function, an event name, or an Array of events names. + * + * @param {EventTarget~EventListener} [third] + * The event handler if `first` is a `Component` and `second` is an event name + * or an Array of event names. + * + * @return {Component} + * Returns itself; method can be chained. + * + * @listens Component#dispose + */ + + + Component.prototype.on = function on(first, second, third) { + var _this2 = this; + + if (typeof first === 'string' || Array.isArray(first)) { + Events.on(this.el_, first, Fn.bind(this, second)); + + // Targeting another component or element + } else { + (function () { + var target = first; + var type = second; + var fn = Fn.bind(_this2, third); + + // When this component is disposed, remove the listener from the other component + var removeOnDispose = function removeOnDispose() { + return _this2.off(target, type, fn); + }; + + // Use the same function ID so we can remove it later it using the ID + // of the original listener + removeOnDispose.guid = fn.guid; + _this2.on('dispose', removeOnDispose); + + // If the other component is disposed first we need to clean the reference + // to the other component in this component's removeOnDispose listener + // Otherwise we create a memory leak. + var cleanRemover = function cleanRemover() { + return _this2.off('dispose', removeOnDispose); + }; + + // Add the same function ID so we can easily remove it later + cleanRemover.guid = fn.guid; + + // Check if this is a DOM node + if (first.nodeName) { + // Add the listener to the other element + Events.on(target, type, fn); + Events.on(target, 'dispose', cleanRemover); + + // Should be a component + // Not using `instanceof Component` because it makes mock players difficult + } else if (typeof first.on === 'function') { + // Add the listener to the other component + target.on(type, fn); + target.on('dispose', cleanRemover); + } + })(); + } + + return this; + }; + + /** + * Remove an event listener from this `Component`s element. If the second argument is + * exluded all listeners for the type passed in as the first argument will be removed. + * + * @param {string|Component|string[]} [first] + * The event name, and array of event names, or another `Component`. + * + * @param {EventTarget~EventListener|string|string[]} [second] + * The listener function, an event name, or an Array of events names. + * + * @param {EventTarget~EventListener} [third] + * The event handler if `first` is a `Component` and `second` is an event name + * or an Array of event names. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.off = function off(first, second, third) { + if (!first || typeof first === 'string' || Array.isArray(first)) { + Events.off(this.el_, first, second); + } else { + var target = first; + var type = second; + // Ensure there's at least a guid, even if the function hasn't been used + var fn = Fn.bind(this, third); + + // Remove the dispose listener on this component, + // which was given the same guid as the event listener + this.off('dispose', fn); + + if (first.nodeName) { + // Remove the listener + Events.off(target, type, fn); + // Remove the listener for cleaning the dispose listener + Events.off(target, 'dispose', fn); + } else { + target.off(type, fn); + target.off('dispose', fn); + } + } + + return this; + }; + + /** + * Add an event listener that gets triggered only once and then gets removed. + * + * @param {string|Component|string[]} [first] + * The event name, and array of event names, or another `Component`. + * + * @param {EventTarget~EventListener|string|string[]} [second] + * The listener function, an event name, or an Array of events names. + * + * @param {EventTarget~EventListener} [third] + * The event handler if `first` is a `Component` and `second` is an event name + * or an Array of event names. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.one = function one(first, second, third) { + var _this3 = this, + _arguments = arguments; + + if (typeof first === 'string' || Array.isArray(first)) { + Events.one(this.el_, first, Fn.bind(this, second)); + } else { + (function () { + var target = first; + var type = second; + var fn = Fn.bind(_this3, third); + + var newFunc = function newFunc() { + _this3.off(target, type, newFunc); + fn.apply(null, _arguments); + }; + + // Keep the same function ID so we can remove it later + newFunc.guid = fn.guid; + + _this3.on(target, type, newFunc); + })(); + } + + return this; + }; + + /** + * Trigger an event on an element. + * + * @param {EventTarget~Event|Object|string} event + * The event name, and Event, or an event-like object with a type attribute + * set to the event name. + * + * @param {Object} [hash] + * Data hash to pass along with the event + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.trigger = function trigger(event, hash) { + Events.trigger(this.el_, event, hash); + return this; + }; + + /** + * Bind a listener to the component's ready state. If the ready event has already + * happened it will trigger the function immediately. + * + * @param {Component~ReadyCallback} fn + * A function to call when ready is triggered. + * + * @param {boolean} [sync=false] + * Execute the listener synchronously if `Component` is ready. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.ready = function ready(fn) { + var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (fn) { + if (this.isReady_) { + if (sync) { + fn.call(this); + } else { + // Call the function asynchronously by default for consistency + this.setTimeout(fn, 1); + } + } else { + this.readyQueue_ = this.readyQueue_ || []; + this.readyQueue_.push(fn); + } + } + return this; + }; + + /** + * Trigger all the ready listeners for this `Component`. + * + * @fires Component#ready + */ + + + Component.prototype.triggerReady = function triggerReady() { + this.isReady_ = true; + + // Ensure ready is triggerd asynchronously + this.setTimeout(function () { + var readyQueue = this.readyQueue_; + + // Reset Ready Queue + this.readyQueue_ = []; + + if (readyQueue && readyQueue.length > 0) { + readyQueue.forEach(function (fn) { + fn.call(this); + }, this); + } + + // Allow for using event listeners also + /** + * Triggered when a `Component` is ready. + * + * @event Component#ready + * @type {EventTarget~Event} + */ + this.trigger('ready'); + }, 1); + }; + + /** + * Find a single DOM element matching a `selector`. This can be within the `Component`s + * `contentEl()` or another custom context. + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelector`. + * + * @param {Element|string} [context=this.contentEl()] + * A DOM element within which to query. Can also be a selector string in + * which case the first matching element will get used as context. If + * missing `this.contentEl()` gets used. If `this.contentEl()` returns + * nothing it falls back to `document`. + * + * @return {Element|null} + * the dom element that was found, or null + * + * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) + */ + + + Component.prototype.$ = function $(selector, context) { + return Dom.$(selector, context || this.contentEl()); + }; + + /** + * Finds all DOM element matching a `selector`. This can be within the `Component`s + * `contentEl()` or another custom context. + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelectorAll`. + * + * @param {Element|string} [context=this.contentEl()] + * A DOM element within which to query. Can also be a selector string in + * which case the first matching element will get used as context. If + * missing `this.contentEl()` gets used. If `this.contentEl()` returns + * nothing it falls back to `document`. + * + * @return {NodeList} + * a list of dom elements that were found + * + * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) + */ + + + Component.prototype.$$ = function $$(selector, context) { + return Dom.$$(selector, context || this.contentEl()); + }; + + /** + * Check if a component's element has a CSS class name. + * + * @param {string} classToCheck + * CSS class name to check. + * + * @return {boolean} + * - True if the `Component` has the class. + * - False if the `Component` does not have the class` + */ + + + Component.prototype.hasClass = function hasClass(classToCheck) { + return Dom.hasElClass(this.el_, classToCheck); + }; + + /** + * Add a CSS class name to the `Component`s element. + * + * @param {string} classToAdd + * CSS class name to add + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.addClass = function addClass(classToAdd) { + Dom.addElClass(this.el_, classToAdd); + return this; + }; + + /** + * Remove a CSS class name from the `Component`s element. + * + * @param {string} classToRemove + * CSS class name to remove + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.removeClass = function removeClass(classToRemove) { + Dom.removeElClass(this.el_, classToRemove); + return this; + }; + + /** + * Add or remove a CSS class name from the component's element. + * - `classToToggle` gets added when {@link Component#hasClass} would return false. + * - `classToToggle` gets removed when {@link Component#hasClass} would return true. + * + * @param {string} classToToggle + * The class to add or remove based on (@link Component#hasClass} + * + * @param {boolean|Dom~predicate} [predicate] + * An {@link Dom~predicate} function or a boolean + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) { + Dom.toggleElClass(this.el_, classToToggle, predicate); + return this; + }; + + /** + * Show the `Component`s element if it is hidden by removing the + * 'vjs-hidden' class name from it. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.show = function show() { + this.removeClass('vjs-hidden'); + return this; + }; + + /** + * Hide the `Component`s element if it is currently showing by adding the + * 'vjs-hidden` class name to it. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.hide = function hide() { + this.addClass('vjs-hidden'); + return this; + }; + + /** + * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' + * class name to it. Used during fadeIn/fadeOut. + * + * @return {Component} + * Returns itself; method can be chained. + * + * @private + */ + + + Component.prototype.lockShowing = function lockShowing() { + this.addClass('vjs-lock-showing'); + return this; + }; + + /** + * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' + * class name from it. Used during fadeIn/fadeOut. + * + * @return {Component} + * Returns itself; method can be chained. + * + * @private + */ + + + Component.prototype.unlockShowing = function unlockShowing() { + this.removeClass('vjs-lock-showing'); + return this; + }; + + /** + * Get the value of an attribute on the `Component`s element. + * + * @param {string} attribute + * Name of the attribute to get the value from. + * + * @return {string|null} + * - The value of the attribute that was asked for. + * - Can be an empty string on some browsers if the attribute does not exist + * or has no value + * - Most browsers will return null if the attibute does not exist or has + * no value. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} + */ + + + Component.prototype.getAttribute = function getAttribute(attribute) { + return Dom.getAttribute(this.el_, attribute); + }; + + /** + * Set the value of an attribute on the `Component`'s element + * + * @param {string} attribute + * Name of the attribute to set. + * + * @param {string} value + * Value to set the attribute to. + * + * @return {Component} + * Returns itself; method can be chained. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} + */ + + + Component.prototype.setAttribute = function setAttribute(attribute, value) { + Dom.setAttribute(this.el_, attribute, value); + return this; + }; + + /** + * Remove an attribute from the `Component`s element. + * + * @param {string} attribute + * Name of the attribute to remove. + * + * @return {Component} + * Returns itself; method can be chained. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} + */ + + + Component.prototype.removeAttribute = function removeAttribute(attribute) { + Dom.removeAttribute(this.el_, attribute); + return this; + }; + + /** + * Get or set the width of the component based upon the CSS styles. + * See {@link Component#dimension} for more detailed information. + * + * @param {number|string} [num] + * The width that you want to set postfixed with '%', 'px' or nothing. + * + * @param {boolean} [skipListeners] + * Skip the resize event trigger + * + * @return {Component|number|string} + * - The width when getting, zero if there is no width. Can be a string + * postpixed with '%' or 'px'. + * - Returns itself when setting; method can be chained. + */ + + + Component.prototype.width = function width(num, skipListeners) { + return this.dimension('width', num, skipListeners); + }; + + /** + * Get or set the height of the component based upon the CSS styles. + * See {@link Component#dimension} for more detailed information. + * + * @param {number|string} [num] + * The height that you want to set postfixed with '%', 'px' or nothing. + * + * @param {boolean} [skipListeners] + * Skip the resize event trigger + * + * @return {Component|number|string} + * - The width when getting, zero if there is no width. Can be a string + * postpixed with '%' or 'px'. + * - Returns itself when setting; method can be chained. + */ + + + Component.prototype.height = function height(num, skipListeners) { + return this.dimension('height', num, skipListeners); + }; + + /** + * Set both the width and height of the `Component` element at the same time. + * + * @param {number|string} width + * Width to set the `Component`s element to. + * + * @param {number|string} height + * Height to set the `Component`s element to. + * + * @return {Component} + * Returns itself; method can be chained. + */ + + + Component.prototype.dimensions = function dimensions(width, height) { + // Skip resize listeners on width for optimization + return this.width(width, true).height(height); + }; + + /** + * Get or set width or height of the `Component` element. This is the shared code + * for the {@link Component#width} and {@link Component#height}. + * + * Things to know: + * - If the width or height in an number this will return the number postfixed with 'px'. + * - If the width/height is a percent this will return the percent postfixed with '%' + * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function + * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. + * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/} + * for more information + * - If you want the computed style of the component, use {@link Component#currentWidth} + * and {@link {Component#currentHeight} + * + * @fires Component#resize + * + * @param {string} widthOrHeight + 8 'width' or 'height' + * + * @param {number|string} [num] + 8 New dimension + * + * @param {boolean} [skipListeners] + * Skip resize event trigger + * + * @return {Component} + * - the dimension when getting or 0 if unset + * - Returns itself when setting; method can be chained. + */ + + + Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { + if (num !== undefined) { + // Set to zero if null or literally NaN (NaN !== NaN) + if (num === null || num !== num) { + num = 0; + } + + // Check if using css width/height (% or px) and adjust + if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { + this.el_.style[widthOrHeight] = num; + } else if (num === 'auto') { + this.el_.style[widthOrHeight] = ''; + } else { + this.el_.style[widthOrHeight] = num + 'px'; + } + + // skipListeners allows us to avoid triggering the resize event when setting both width and height + if (!skipListeners) { + /** + * Triggered when a component is resized. + * + * @event Component#resize + * @type {EventTarget~Event} + */ + this.trigger('resize'); + } + + // Return component + return this; + } + + // Not setting a value, so getting it + // Make sure element exists + if (!this.el_) { + return 0; + } + + // Get dimension value from style + var val = this.el_.style[widthOrHeight]; + var pxIndex = val.indexOf('px'); + + if (pxIndex !== -1) { + // Return the pixel value with no 'px' + return parseInt(val.slice(0, pxIndex), 10); + } + + // No px so using % or no style was set, so falling back to offsetWidth/height + // If component has display:none, offset will return 0 + // TODO: handle display:none and no dimension style using px + return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10); + }; + + /** + * Get the width or the height of the `Component` elements computed style. Uses + * `window.getComputedStyle`. + * + * @param {string} widthOrHeight + * A string containing 'width' or 'height'. Whichever one you want to get. + * + * @return {number} + * The dimension that gets asked for or 0 if nothing was set + * for that dimension. + */ + + + Component.prototype.currentDimension = function currentDimension(widthOrHeight) { + var computedWidthOrHeight = 0; + + if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { + throw new Error('currentDimension only accepts width or height value'); + } + + if (typeof _window2['default'].getComputedStyle === 'function') { + var computedStyle = _window2['default'].getComputedStyle(this.el_); + + computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight]; + } + + // remove 'px' from variable and parse as integer + computedWidthOrHeight = parseFloat(computedWidthOrHeight); + + // if the computed value is still 0, it's possible that the browser is lying + // and we want to check the offset values. + // This code also runs on IE8 and wherever getComputedStyle doesn't exist. + if (computedWidthOrHeight === 0) { + var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight); + + computedWidthOrHeight = this.el_[rule]; + } + + return computedWidthOrHeight; + }; + + /** + * An object that contains width and height values of the `Component`s + * computed style. Uses `window.getComputedStyle`. + * + * @typedef {Object} Component~DimensionObject + * + * @property {number} width + * The width of the `Component`s computed style. + * + * @property {number} height + * The height of the `Component`s computed style. + */ + + /** + * Get an object that contains width and height values of the `Component`s + * computed style. + * + * @return {Component~DimensionObject} + * The dimensions of the components element + */ + + + Component.prototype.currentDimensions = function currentDimensions() { + return { + width: this.currentDimension('width'), + height: this.currentDimension('height') + }; + }; + + /** + * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`. + * + * @return {number} width + * The width of the `Component`s computed style. + */ + + + Component.prototype.currentWidth = function currentWidth() { + return this.currentDimension('width'); + }; + + /** + * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`. + * + * @return {number} height + * The height of the `Component`s computed style. + */ + + + Component.prototype.currentHeight = function currentHeight() { + return this.currentDimension('height'); + }; + + /** + * Emit a 'tap' events when touch event support gets detected. This gets used to + * support toggling the controls through a tap on the video. They get enabled + * because every sub-component would have extra overhead otherwise. + * + * @private + * @fires Component#tap + * @listens Component#touchstart + * @listens Component#touchmove + * @listens Component#touchleave + * @listens Component#touchcancel + * @listens Component#touchend + */ + + + Component.prototype.emitTapEvents = function emitTapEvents() { + // Track the start time so we can determine how long the touch lasted + var touchStart = 0; + var firstTouch = null; + + // Maximum movement allowed during a touch event to still be considered a tap + // Other popular libs use anywhere from 2 (hammer.js) to 15, + // so 10 seems like a nice, round number. + var tapMovementThreshold = 10; + + // The maximum length a touch can be while still being considered a tap + var touchTimeThreshold = 200; + + var couldBeTap = void 0; + + this.on('touchstart', function (event) { + // If more than one finger, don't consider treating this as a click + if (event.touches.length === 1) { + // Copy pageX/pageY from the object + firstTouch = { + pageX: event.touches[0].pageX, + pageY: event.touches[0].pageY + }; + // Record start time so we can detect a tap vs. "touch and hold" + touchStart = new Date().getTime(); + // Reset couldBeTap tracking + couldBeTap = true; + } + }); + + this.on('touchmove', function (event) { + // If more than one finger, don't consider treating this as a click + if (event.touches.length > 1) { + couldBeTap = false; + } else if (firstTouch) { + // Some devices will throw touchmoves for all but the slightest of taps. + // So, if we moved only a small distance, this could still be a tap + var xdiff = event.touches[0].pageX - firstTouch.pageX; + var ydiff = event.touches[0].pageY - firstTouch.pageY; + var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); + + if (touchDistance > tapMovementThreshold) { + couldBeTap = false; + } + } + }); + + var noTap = function noTap() { + couldBeTap = false; + }; + + // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s + this.on('touchleave', noTap); + this.on('touchcancel', noTap); + + // When the touch ends, measure how long it took and trigger the appropriate + // event + this.on('touchend', function (event) { + firstTouch = null; + // Proceed only if the touchmove/leave/cancel event didn't happen + if (couldBeTap === true) { + // Measure how long the touch lasted + var touchTime = new Date().getTime() - touchStart; + + // Make sure the touch was less than the threshold to be considered a tap + if (touchTime < touchTimeThreshold) { + // Don't let browser turn this into a click + event.preventDefault(); + /** + * Triggered when a `Component` is tapped. + * + * @event Component#tap + * @type {EventTarget~Event} + */ + this.trigger('tap'); + // It may be good to copy the touchend event object and change the + // type to tap, if the other event properties aren't exact after + // Events.fixEvent runs (e.g. event.target) + } + } + }); + }; + + /** + * This function reports user activity whenever touch events happen. This can get + * turned off by any sub-components that wants touch events to act another way. + * + * Report user touch activity when touch events occur. User activity gets used to + * determine when controls should show/hide. It is simple when it comes to mouse + * events, because any mouse event should show the controls. So we capture mouse + * events that bubble up to the player and report activity when that happens. + * With touch events it isn't as easy as `touchstart` and `touchend` toggle player + * controls. So touch events can't help us at the player level either. + * + * User activity gets checked asynchronously. So what could happen is a tap event + * on the video turns the controls off. Then the `touchend` event bubbles up to + * the player. Which, if it reported user activity, would turn the controls right + * back on. We also don't want to completely block touch events from bubbling up. + * Furthermore a `touchmove` event and anything other than a tap, should not turn + * controls back on. + * + * @listens Component#touchstart + * @listens Component#touchmove + * @listens Component#touchend + * @listens Component#touchcancel + */ + + + Component.prototype.enableTouchActivity = function enableTouchActivity() { + // Don't continue if the root player doesn't support reporting user activity + if (!this.player() || !this.player().reportUserActivity) { + return; + } + + // listener for reporting that the user is active + var report = Fn.bind(this.player(), this.player().reportUserActivity); + + var touchHolding = void 0; + + this.on('touchstart', function () { + report(); + // For as long as the they are touching the device or have their mouse down, + // we consider them active even if they're not moving their finger or mouse. + // So we want to continue to update that they are active + this.clearInterval(touchHolding); + // report at the same interval as activityCheck + touchHolding = this.setInterval(report, 250); + }); + + var touchEnd = function touchEnd(event) { + report(); + // stop the interval that maintains activity if the touch is holding + this.clearInterval(touchHolding); + }; + + this.on('touchmove', report); + this.on('touchend', touchEnd); + this.on('touchcancel', touchEnd); + }; + + /** + * A callback that has no parameters and is bound into `Component`s context. + * + * @callback Component~GenericCallback + * @this Component + */ + + /** + * Creates a function that runs after an `x` millisecond timeout. This function is a + * wrapper around `window.setTimeout`. There are a few reasons to use this one + * instead though: + * 1. It gets cleared via {@link Component#clearTimeout} when + * {@link Component#dispose} gets called. + * 2. The function callback will gets turned into a {@link Component~GenericCallback} + * + * > Note: You can use `window.clearTimeout` on the id returned by this function. This + * will cause its dispose listener not to get cleaned up! Please use + * {@link Component#clearTimeout} or {@link Component#dispose}. + * + * @param {Component~GenericCallback} fn + * The function that will be run after `timeout`. + * + * @param {number} timeout + * Timeout in milliseconds to delay before executing the specified function. + * + * @return {number} + * Returns a timeout ID that gets used to identify the timeout. It can also + * get used in {@link Component#clearTimeout} to clear the timeout that + * was set. + * + * @listens Component#dispose + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} + */ + + + Component.prototype.setTimeout = function setTimeout(fn, timeout) { + fn = Fn.bind(this, fn); + + var timeoutId = _window2['default'].setTimeout(fn, timeout); + var disposeFn = function disposeFn() { + this.clearTimeout(timeoutId); + }; + + disposeFn.guid = 'vjs-timeout-' + timeoutId; + + this.on('dispose', disposeFn); + + return timeoutId; + }; + + /** + * Clears a timeout that gets created via `window.setTimeout` or + * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} + * use this function instead of `window.clearTimout`. If you don't your dispose + * listener will not get cleaned up until {@link Component#dispose}! + * + * @param {number} timeoutId + * The id of the timeout to clear. The return value of + * {@link Component#setTimeout} or `window.setTimeout`. + * + * @return {number} + * Returns the timeout id that was cleared. + * + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} + */ + + + Component.prototype.clearTimeout = function clearTimeout(timeoutId) { + _window2['default'].clearTimeout(timeoutId); + + var disposeFn = function disposeFn() {}; + + disposeFn.guid = 'vjs-timeout-' + timeoutId; + + this.off('dispose', disposeFn); + + return timeoutId; + }; + + /** + * Creates a function that gets run every `x` milliseconds. This function is a wrapper + * around `window.setInterval`. There are a few reasons to use this one instead though. + * 1. It gets cleared via {@link Component#clearInterval} when + * {@link Component#dispose} gets called. + * 2. The function callback will be a {@link Component~GenericCallback} + * + * @param {Component~GenericCallback} fn + * The function to run every `x` seconds. + * + * @param {number} interval + * Execute the specified function every `x` milliseconds. + * + * @return {number} + * Returns an id that can be used to identify the interval. It can also be be used in + * {@link Component#clearInterval} to clear the interval. + * + * @listens Component#dispose + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} + */ + + + Component.prototype.setInterval = function setInterval(fn, interval) { + fn = Fn.bind(this, fn); + + var intervalId = _window2['default'].setInterval(fn, interval); + + var disposeFn = function disposeFn() { + this.clearInterval(intervalId); + }; + + disposeFn.guid = 'vjs-interval-' + intervalId; + + this.on('dispose', disposeFn); + + return intervalId; + }; + + /** + * Clears an interval that gets created via `window.setInterval` or + * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval} + * use this function instead of `window.clearInterval`. If you don't your dispose + * listener will not get cleaned up until {@link Component#dispose}! + * + * @param {number} intervalId + * The id of the interval to clear. The return value of + * {@link Component#setInterval} or `window.setInterval`. + * + * @return {number} + * Returns the interval id that was cleared. + * + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} + */ + + + Component.prototype.clearInterval = function clearInterval(intervalId) { + _window2['default'].clearInterval(intervalId); + + var disposeFn = function disposeFn() {}; + + disposeFn.guid = 'vjs-interval-' + intervalId; + + this.off('dispose', disposeFn); + + return intervalId; + }; + + /** + * Register a `Component` with `videojs` given the name and the component. + * + * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s + * should be registered using {@link Tech.registerTech} or + * {@link videojs:videojs.registerTech}. + * + * > NOTE: This function can also be seen on videojs as + * {@link videojs:videojs.registerComponent}. + * + * @param {string} name + * The name of the `Component` to register. + * + * @param {Component} comp + * The `Component` class to register. + * + * @return {Component} + * The `Component` that was registered. + */ + + + Component.registerComponent = function registerComponent(name, comp) { + if (!name) { + return; + } + + name = (0, _toTitleCase2['default'])(name); + + if (!Component.components_) { + Component.components_ = {}; + } + + if (name === 'Player' && Component.components_[name]) { + (function () { + var Player = Component.components_[name]; + + // If we have players that were disposed, then their name will still be + // in Players.players. So, we must loop through and verify that the value + // for each item is not null. This allows registration of the Player component + // after all players have been disposed or before any were created. + if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) { + return Player.players[playerName]; + }).every(Boolean)) { + throw new Error('Can not register Player component after player has been created'); + } + })(); + } + + Component.components_[name] = comp; + + return comp; + }; + + /** + * Get a `Component` based on the name it was registered with. + * + * @param {string} name + * The Name of the component to get. + * + * @return {Component} + * The `Component` that got registered under the given name. + * + * @deprecated In `videojs` 6 this will not return `Component`s that were not + * registered using {@link Component.registerComponent}. Currently we + * check the global `videojs` object for a `Component` name and + * return that if it exists. + */ + + + Component.getComponent = function getComponent(name) { + if (!name) { + return; + } + + name = (0, _toTitleCase2['default'])(name); + + if (Component.components_ && Component.components_[name]) { + return Component.components_[name]; + } + + if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { + _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)'); + + return _window2['default'].videojs[name]; + } + }; + + /** + * Sets up the constructor using the supplied init method or uses the init of the + * parent object. + * + * @param {Object} [props={}] + * An object of properties. + * + * @return {Object} + * the extended object. + * + * @deprecated since version 5 + */ + + + Component.extend = function extend(props) { + props = props || {}; + + _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead'); + + // Set up the constructor using the supplied init method + // or using the init of the parent object + // Make sure to check the unobfuscated version for external libs + var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {}; + // In Resig's simple class inheritance (previously used) the constructor + // is a function that calls `this.init.apply(arguments)` + // However that would prevent us from using `ParentObject.call(this);` + // in a Child constructor because the `this` in `this.init` + // would still refer to the Child and cause an infinite loop. + // We would instead have to do + // `ParentObject.prototype.init.apply(this, arguments);` + // Bleh. We're not creating a _super() function, so it's good to keep + // the parent constructor reference simple. + var subObj = function subObj() { + init.apply(this, arguments); + }; + + // Inherit from this object's prototype + subObj.prototype = Object.create(this.prototype); + // Reset the constructor property for subObj otherwise + // instances of subObj would have the constructor of the parent Object + subObj.prototype.constructor = subObj; + + // Make the class extendable + subObj.extend = Component.extend; + + // Extend subObj's prototype with functions and other properties from props + for (var name in props) { + if (props.hasOwnProperty(name)) { + subObj.prototype[name] = props[name]; + } + } + + return subObj; + }; + + return Component; +}(); + +Component.registerComponent('Component', Component); +exports['default'] = Component; + +},{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackButton = _dereq_(36); + +var _trackButton2 = _interopRequireDefault(_trackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _audioTrackMenuItem = _dereq_(7); + +var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file audio-track-button.js + */ + + +/** + * The base class for buttons that toggle specific {@link AudioTrack} types. + * + * @extends TrackButton + */ +var AudioTrackButton = function (_TrackButton) { + _inherits(AudioTrackButton, _TrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + */ + function AudioTrackButton(player) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, AudioTrackButton); + + options.tracks = player.audioTracks && player.audioTracks(); + + var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); + + _this.el_.setAttribute('aria-label', 'Audio Menu'); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this); + }; + + /** + * Create a menu item for each audio track + * + * @param {AudioTrackMenuItem[]} [items=[]] + * An array of existing menu items to use. + * + * @return {AudioTrackMenuItem[]} + * An array of menu items + */ + + + AudioTrackButton.prototype.createItems = function createItems() { + var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + var tracks = this.player_.audioTracks && this.player_.audioTracks(); + + if (!tracks) { + return items; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + items.push(new _audioTrackMenuItem2['default'](this.player_, { + track: track, + // MenuItem is selectable + selectable: true + })); + } + + return items; + }; + + return AudioTrackButton; +}(_trackButton2['default']); + +/** + * The text that should display over the `AudioTrackButton`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +AudioTrackButton.prototype.controlText_ = 'Audio Track'; +_component2['default'].registerComponent('AudioTrackButton', AudioTrackButton); +exports['default'] = AudioTrackButton; + +},{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _menuItem = _dereq_(48); + +var _menuItem2 = _interopRequireDefault(_menuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file audio-track-menu-item.js + */ + + +/** + * An {@link AudioTrack} {@link MenuItem} + * + * @extends MenuItem + */ +var AudioTrackMenuItem = function (_MenuItem) { + _inherits(AudioTrackMenuItem, _MenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function AudioTrackMenuItem(player, options) { + _classCallCheck(this, AudioTrackMenuItem); + + var track = options.track; + var tracks = player.audioTracks(); + + // Modify options for parent MenuItem class's init. + options.label = track.label || track.language || 'Unknown'; + options.selected = track.enabled; + + var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); + + _this.track = track; + + if (tracks) { + (function () { + var changeHandler = Fn.bind(_this, _this.handleTracksChange); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + })(); + } + return _this; + } + + /** + * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent} + * for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + AudioTrackMenuItem.prototype.handleClick = function handleClick(event) { + var tracks = this.player_.audioTracks(); + + _MenuItem.prototype.handleClick.call(this, event); + + if (!tracks) { + return; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + track.enabled = track === this.track; + } + }; + + /** + * Handle any {@link AudioTrack} change. + * + * @param {EventTarget~Event} [event] + * The {@link AudioTrackList#change} event that caused this to run. + * + * @listens AudioTrackList#change + */ + + + AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { + this.selected(this.track.enabled); + }; + + return AudioTrackMenuItem; +}(_menuItem2['default']); + +_component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem); +exports['default'] = AudioTrackMenuItem; + +},{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +_dereq_(12); + +_dereq_(32); + +_dereq_(33); + +_dereq_(35); + +_dereq_(34); + +_dereq_(10); + +_dereq_(18); + +_dereq_(9); + +_dereq_(38); + +_dereq_(40); + +_dereq_(11); + +_dereq_(25); + +_dereq_(27); + +_dereq_(29); + +_dereq_(24); + +_dereq_(6); + +_dereq_(13); + +_dereq_(21); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file control-bar.js + */ + + +// Required children + + +/** + * Container of main controls. + * + * @extends Component + */ +var ControlBar = function (_Component) { + _inherits(ControlBar, _Component); + + function ControlBar() { + _classCallCheck(this, ControlBar); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + ControlBar.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-control-bar', + dir: 'ltr' + }, { + // The control bar is a group, so it can contain menuitems + role: 'group' + }); + }; + + return ControlBar; +}(_component2['default']); + +/** + * Default options for `ControlBar` + * + * @type {Object} + * @private + */ + + +ControlBar.prototype.options_ = { + children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle'] +}; + +_component2['default'].registerComponent('ControlBar', ControlBar); +exports['default'] = ControlBar; + +},{"10":10,"11":11,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"32":32,"33":33,"34":34,"35":35,"38":38,"40":40,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _button = _dereq_(2); + +var _button2 = _interopRequireDefault(_button); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file fullscreen-toggle.js + */ + + +/** + * Toggle fullscreen video + * + * @extends Button + */ +var FullscreenToggle = function (_Button) { + _inherits(FullscreenToggle, _Button); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function FullscreenToggle(player, options) { + _classCallCheck(this, FullscreenToggle); + + var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); + + _this.on(player, 'fullscreenchange', _this.handleFullscreenChange); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this); + }; + + /** + * Handles fullscreenchange on the player and change control text accordingly. + * + * @param {EventTarget~Event} [event] + * The {@link Player#fullscreenchange} event that caused this function to be + * called. + * + * @listens Player#fullscreenchange + */ + + + FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) { + if (this.player_.isFullscreen()) { + this.controlText('Non-Fullscreen'); + } else { + this.controlText('Fullscreen'); + } + }; + + /** + * This gets called when an `FullscreenToggle` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + FullscreenToggle.prototype.handleClick = function handleClick(event) { + if (!this.player_.isFullscreen()) { + this.player_.requestFullscreen(); + } else { + this.player_.exitFullscreen(); + } + }; + + return FullscreenToggle; +}(_button2['default']); + +/** + * The text that should display over the `FullscreenToggle`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +FullscreenToggle.prototype.controlText_ = 'Fullscreen'; + +_component2['default'].registerComponent('FullscreenToggle', FullscreenToggle); +exports['default'] = FullscreenToggle; + +},{"2":2,"5":5}],10:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file live-display.js + */ + + +// TODO - Future make it click to snap to live + +/** + * Displays the live indicator when duration is Infinity. + * + * @extends Component + */ +var LiveDisplay = function (_Component) { + _inherits(LiveDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function LiveDisplay(player, options) { + _classCallCheck(this, LiveDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.updateShowing(); + _this.on(_this.player(), 'durationchange', _this.updateShowing); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + LiveDisplay.prototype.createEl = function createEl() { + var el = _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-live-control vjs-control' + }); + + this.contentEl_ = Dom.createEl('div', { + className: 'vjs-live-display', + innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE') + }, { + 'aria-live': 'off' + }); + + el.appendChild(this.contentEl_); + return el; + }; + + /** + * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide + * it accordingly + * + * @param {EventTarget~Event} [event] + * The {@link Player#durationchange} event that caused this function to run. + * + * @listens Player#durationchange + */ + + + LiveDisplay.prototype.updateShowing = function updateShowing(event) { + if (this.player().duration() === Infinity) { + this.show(); + } else { + this.hide(); + } + }; + + return LiveDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('LiveDisplay', LiveDisplay); +exports['default'] = LiveDisplay; + +},{"5":5,"81":81}],11:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _button = _dereq_(2); + +var _button2 = _interopRequireDefault(_button); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file mute-toggle.js + */ + + +/** + * A button component for muting the audio. + * + * @extends Button + */ +var MuteToggle = function (_Button) { + _inherits(MuteToggle, _Button); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function MuteToggle(player, options) { + _classCallCheck(this, MuteToggle); + + var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); + + _this.on(player, 'volumechange', _this.update); + + // hide mute toggle if the current tech doesn't support volume control + if (player.tech_ && player.tech_.featuresVolumeControl === false) { + _this.addClass('vjs-hidden'); + } + + _this.on(player, 'loadstart', function () { + // We need to update the button to account for a default muted state. + this.update(); + + if (player.tech_.featuresVolumeControl === false) { + this.addClass('vjs-hidden'); + } else { + this.removeClass('vjs-hidden'); + } + }); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + MuteToggle.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this); + }; + + /** + * This gets called when an `MuteToggle` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + MuteToggle.prototype.handleClick = function handleClick(event) { + this.player_.muted(this.player_.muted() ? false : true); + }; + + /** + * Update the state of volume. + * + * @param {EventTarget~Event} [event] + * The {@link Player#loadstart} event if this function was called through an + * event. + * + * @listens Player#loadstart + */ + + + MuteToggle.prototype.update = function update(event) { + var vol = this.player_.volume(); + var level = 3; + + if (vol === 0 || this.player_.muted()) { + level = 0; + } else if (vol < 0.33) { + level = 1; + } else if (vol < 0.67) { + level = 2; + } + + // Don't rewrite the button text if the actual text doesn't change. + // This causes unnecessary and confusing information for screen reader users. + // This check is needed because this function gets called every time the volume level is changed. + var toMute = this.player_.muted() ? 'Unmute' : 'Mute'; + + if (this.controlText() !== toMute) { + this.controlText(toMute); + } + + // TODO improve muted icon classes + for (var i = 0; i < 4; i++) { + Dom.removeElClass(this.el_, 'vjs-vol-' + i); + } + Dom.addElClass(this.el_, 'vjs-vol-' + level); + }; + + return MuteToggle; +}(_button2['default']); + +/** + * The text that should display over the `MuteToggle`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +MuteToggle.prototype.controlText_ = 'Mute'; + +_component2['default'].registerComponent('MuteToggle', MuteToggle); +exports['default'] = MuteToggle; + +},{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _button = _dereq_(2); + +var _button2 = _interopRequireDefault(_button); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file play-toggle.js + */ + + +/** + * Button to toggle between play and pause. + * + * @extends Button + */ +var PlayToggle = function (_Button) { + _inherits(PlayToggle, _Button); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PlayToggle(player, options) { + _classCallCheck(this, PlayToggle); + + var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); + + _this.on(player, 'play', _this.handlePlay); + _this.on(player, 'pause', _this.handlePause); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + PlayToggle.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this); + }; + + /** + * This gets called when an `PlayToggle` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + PlayToggle.prototype.handleClick = function handleClick(event) { + if (this.player_.paused()) { + this.player_.play(); + } else { + this.player_.pause(); + } + }; + + /** + * Add the vjs-playing class to the element so it can change appearance. + * + * @param {EventTarget~Event} [event] + * The event that caused this function to run. + * + * @listens Player#play + */ + + + PlayToggle.prototype.handlePlay = function handlePlay(event) { + this.removeClass('vjs-paused'); + this.addClass('vjs-playing'); + // change the button text to "Pause" + this.controlText('Pause'); + }; + + /** + * Add the vjs-paused class to the element so it can change appearance. + * + * @param {EventTarget~Event} [event] + * The event that caused this function to run. + * + * @listens Player#pause + */ + + + PlayToggle.prototype.handlePause = function handlePause(event) { + this.removeClass('vjs-playing'); + this.addClass('vjs-paused'); + // change the button text to "Play" + this.controlText('Play'); + }; + + return PlayToggle; +}(_button2['default']); + +/** + * The text that should display over the `PlayToggle`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +PlayToggle.prototype.controlText_ = 'Play'; + +_component2['default'].registerComponent('PlayToggle', PlayToggle); +exports['default'] = PlayToggle; + +},{"2":2,"5":5}],13:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _menuButton = _dereq_(47); + +var _menuButton2 = _interopRequireDefault(_menuButton); + +var _menu = _dereq_(49); + +var _menu2 = _interopRequireDefault(_menu); + +var _playbackRateMenuItem = _dereq_(14); + +var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file playback-rate-menu-button.js + */ + + +/** + * The component for controlling the playback rate. + * + * @extends MenuButton + */ +var PlaybackRateMenuButton = function (_MenuButton) { + _inherits(PlaybackRateMenuButton, _MenuButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PlaybackRateMenuButton(player, options) { + _classCallCheck(this, PlaybackRateMenuButton); + + var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); + + _this.updateVisibility(); + _this.updateLabel(); + + _this.on(player, 'loadstart', _this.updateVisibility); + _this.on(player, 'ratechange', _this.updateLabel); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + PlaybackRateMenuButton.prototype.createEl = function createEl() { + var el = _MenuButton.prototype.createEl.call(this); + + this.labelEl_ = Dom.createEl('div', { + className: 'vjs-playback-rate-value', + innerHTML: 1.0 + }); + + el.appendChild(this.labelEl_); + + return el; + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this); + }; + + /** + * Create the playback rate menu + * + * @return {Menu} + * Menu object populated with {@link PlaybackRateMenuItem}s + */ + + + PlaybackRateMenuButton.prototype.createMenu = function createMenu() { + var menu = new _menu2['default'](this.player()); + var rates = this.playbackRates(); + + if (rates) { + for (var i = rates.length - 1; i >= 0; i--) { + menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' })); + } + } + + return menu; + }; + + /** + * Updates ARIA accessibility attributes + */ + + + PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() { + // Current playback rate + this.el().setAttribute('aria-valuenow', this.player().playbackRate()); + }; + + /** + * This gets called when an `PlaybackRateMenuButton` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) { + // select next rate option + var currentRate = this.player().playbackRate(); + var rates = this.playbackRates(); + + // this will select first one if the last one currently selected + var newRate = rates[0]; + + for (var i = 0; i < rates.length; i++) { + if (rates[i] > currentRate) { + newRate = rates[i]; + break; + } + } + this.player().playbackRate(newRate); + }; + + /** + * Get possible playback rates + * + * @return {Array} + * All possible playback rates + */ + + + PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() { + return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates; + }; + + /** + * Get whether playback rates is supported by the tech + * and an array of playback rates exists + * + * @return {boolean} + * Whether changing playback rate is supported + */ + + + PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() { + return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0; + }; + + /** + * Hide playback rate controls when they're no playback rate options to select + * + * @param {EventTarget~Event} [event] + * The event that caused this function to run. + * + * @listens Player#loadstart + */ + + + PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) { + if (this.playbackRateSupported()) { + this.removeClass('vjs-hidden'); + } else { + this.addClass('vjs-hidden'); + } + }; + + /** + * Update button label when rate changed + * + * @param {EventTarget~Event} [event] + * The event that caused this function to run. + * + * @listens Player#ratechange + */ + + + PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) { + if (this.playbackRateSupported()) { + this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; + } + }; + + return PlaybackRateMenuButton; +}(_menuButton2['default']); + +/** + * The text that should display over the `FullscreenToggle`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate'; + +_component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); +exports['default'] = PlaybackRateMenuButton; + +},{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _menuItem = _dereq_(48); + +var _menuItem2 = _interopRequireDefault(_menuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file playback-rate-menu-item.js + */ + + +/** + * The specific menu item type for selecting a playback rate. + * + * @extends MenuItem + */ +var PlaybackRateMenuItem = function (_MenuItem) { + _inherits(PlaybackRateMenuItem, _MenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PlaybackRateMenuItem(player, options) { + _classCallCheck(this, PlaybackRateMenuItem); + + var label = options.rate; + var rate = parseFloat(label, 10); + + // Modify options for parent MenuItem class's init. + options.label = label; + options.selected = rate === 1; + + var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); + + _this.label = label; + _this.rate = rate; + + _this.on(player, 'ratechange', _this.update); + return _this; + } + + /** + * This gets called when an `PlaybackRateMenuItem` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) { + _MenuItem.prototype.handleClick.call(this); + this.player().playbackRate(this.rate); + }; + + /** + * Update the PlaybackRateMenuItem when the playbackrate changes. + * + * @param {EventTarget~Event} [event] + * The `ratechange` event that caused this function to run. + * + * @listens Player#ratechange + */ + + + PlaybackRateMenuItem.prototype.update = function update(event) { + this.selected(this.player().playbackRate() === this.rate); + }; + + return PlaybackRateMenuItem; +}(_menuItem2['default']); + +/** + * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization. + * + * @type {string} + * @private + */ + + +PlaybackRateMenuItem.prototype.contentElType = 'button'; + +_component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem); +exports['default'] = PlaybackRateMenuItem; + +},{"48":48,"5":5}],15:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file load-progress-bar.js + */ + + +/** + * Shows loading progress + * + * @extends Component + */ +var LoadProgressBar = function (_Component) { + _inherits(LoadProgressBar, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function LoadProgressBar(player, options) { + _classCallCheck(this, LoadProgressBar); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.partEls_ = []; + _this.on(player, 'progress', _this.update); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + LoadProgressBar.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-load-progress', + innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>' + }); + }; + + /** + * Update progress bar + * + * @param {EventTarget~Event} [event] + * The `progress` event that caused this function to run. + * + * @listens Player#progress + */ + + + LoadProgressBar.prototype.update = function update(event) { + var buffered = this.player_.buffered(); + var duration = this.player_.duration(); + var bufferedEnd = this.player_.bufferedEnd(); + var children = this.partEls_; + + // get the percent width of a time compared to the total end + var percentify = function percentify(time, end) { + // no NaN + var percent = time / end || 0; + + return (percent >= 1 ? 1 : percent) * 100 + '%'; + }; + + // update the width of the progress bar + this.el_.style.width = percentify(bufferedEnd, duration); + + // add child elements to represent the individual buffered time ranges + for (var i = 0; i < buffered.length; i++) { + var start = buffered.start(i); + var end = buffered.end(i); + var part = children[i]; + + if (!part) { + part = this.el_.appendChild(Dom.createEl()); + children[i] = part; + } + + // set the percent based on the width of the progress bar (bufferedEnd) + part.style.left = percentify(start, bufferedEnd); + part.style.width = percentify(end - start, bufferedEnd); + } + + // remove unused buffered range elements + for (var _i = children.length; _i > buffered.length; _i--) { + this.el_.removeChild(children[_i - 1]); + } + children.length = buffered.length; + }; + + return LoadProgressBar; +}(_component2['default']); + +_component2['default'].registerComponent('LoadProgressBar', LoadProgressBar); +exports['default'] = LoadProgressBar; + +},{"5":5,"81":81}],16:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +var _computedStyle = _dereq_(80); + +var _computedStyle2 = _interopRequireDefault(_computedStyle); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file mouse-time-display.js + */ + + +/** + * The Mouse Time Display component shows the time you will seek to + * when hovering over the progress bar + * + * @extends Component + */ +var MouseTimeDisplay = function (_Component) { + _inherits(MouseTimeDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function MouseTimeDisplay(player, options) { + _classCallCheck(this, MouseTimeDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { + _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; + } + + if (_this.keepTooltipsInside) { + _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' }); + _this.el().appendChild(_this.tooltip); + _this.addClass('vjs-keep-tooltips-inside'); + } + + _this.update(0, 0); + + player.on('ready', function () { + _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25)); + }); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + MouseTimeDisplay.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-mouse-display' + }); + }; + + /** + * Handle the mouse move event on the `MouseTimeDisplay`. + * + * @param {EventTarget~Event} event + * The `mousemove` event that caused this to event to run. + * + * @listen mousemove + */ + + + MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) { + var duration = this.player_.duration(); + var newTime = this.calculateDistance(event) * duration; + var position = event.pageX - Dom.findElPosition(this.el().parentNode).left; + + this.update(newTime, position); + }; + + /** + * Update the time and posistion of the `MouseTimeDisplay`. + * + * @param {number} newTime + * Time to change the `MouseTimeDisplay` to. + * + * @param {nubmer} position + * Postion from the left of the in pixels. + */ + + + MouseTimeDisplay.prototype.update = function update(newTime, position) { + var time = (0, _formatTime2['default'])(newTime, this.player_.duration()); + + this.el().style.left = position + 'px'; + this.el().setAttribute('data-current-time', time); + + if (this.keepTooltipsInside) { + var clampedPosition = this.clampPosition_(position); + var difference = position - clampedPosition + 1; + var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); + var tooltipWidthHalf = tooltipWidth / 2; + + this.tooltip.innerHTML = time; + this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px'; + } + }; + + /** + * Get the mouse pointers x coordinate in pixels. + * + * @param {EventTarget~Event} [event] + * The `mousemove` event that was passed to this function by + * {@link MouseTimeDisplay#handleMouseMove} + * + * @return {number} + * THe x position in pixels of the mouse pointer. + */ + + + MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) { + return Dom.getPointerPosition(this.el().parentNode, event).x; + }; + + /** + * This takes in a horizontal position for the bar and returns a clamped position. + * Clamped position means that it will keep the position greater than half the width + * of the tooltip and smaller than the player width minus half the width o the tooltip. + * It will only clamp the position if `keepTooltipsInside` option is set. + * + * @param {number} position + * The position the bar wants to be + * + * @return {number} + * The (potentially) new clamped position. + * + * @private + */ + + + MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) { + if (!this.keepTooltipsInside) { + return position; + } + + var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); + var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width')); + var tooltipWidthHalf = tooltipWidth / 2; + var actualPosition = position; + + if (position < tooltipWidthHalf) { + actualPosition = Math.ceil(tooltipWidthHalf); + } else if (position > playerWidth - tooltipWidthHalf) { + actualPosition = Math.floor(playerWidth - tooltipWidthHalf); + } + + return actualPosition; + }; + + return MouseTimeDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay); +exports['default'] = MouseTimeDisplay; + +},{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file play-progress-bar.js + */ + + +/** + * Shows play progress + * + * @extends Component + */ +var PlayProgressBar = function (_Component) { + _inherits(PlayProgressBar, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PlayProgressBar(player, options) { + _classCallCheck(this, PlayProgressBar); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.updateDataAttr(); + _this.on(player, 'timeupdate', _this.updateDataAttr); + player.ready(Fn.bind(_this, _this.updateDataAttr)); + + if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { + _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; + } + + if (_this.keepTooltipsInside) { + _this.addClass('vjs-keep-tooltips-inside'); + } + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + PlayProgressBar.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-play-progress vjs-slider-bar', + innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' + }); + }; + + /** + * Update the data-current-time attribute on the `PlayProgressBar`. + * + * @param {EventTarget~Event} [event] + * The `timeupdate` event that caused this to run. + * + * @listens Player#timeupdate + */ + + + PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { + var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); + + this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration())); + }; + + return PlayProgressBar; +}(_component2['default']); + +_component2['default'].registerComponent('PlayProgressBar', PlayProgressBar); +exports['default'] = PlayProgressBar; + +},{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +_dereq_(19); + +_dereq_(16); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file progress-control.js + */ + + +/** + * The Progress Control component contains the seek bar, load progress, + * and play progress. + * + * @extends Component + */ +var ProgressControl = function (_Component) { + _inherits(ProgressControl, _Component); + + function ProgressControl() { + _classCallCheck(this, ProgressControl); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + ProgressControl.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-progress-control vjs-control' + }); + }; + + return ProgressControl; +}(_component2['default']); + +/** + * Default options for `ProgressControl` + * + * @type {Object} + * @private + */ + + +ProgressControl.prototype.options_ = { + children: ['seekBar'] +}; + +_component2['default'].registerComponent('ProgressControl', ProgressControl); +exports['default'] = ProgressControl; + +},{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _slider = _dereq_(57); + +var _slider2 = _interopRequireDefault(_slider); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +var _computedStyle = _dereq_(80); + +var _computedStyle2 = _interopRequireDefault(_computedStyle); + +_dereq_(15); + +_dereq_(17); + +_dereq_(20); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file seek-bar.js + */ + + +/** + * Seek Bar and holder for the progress bars + * + * @extends Slider + */ +var SeekBar = function (_Slider) { + _inherits(SeekBar, _Slider); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function SeekBar(player, options) { + _classCallCheck(this, SeekBar); + + var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); + + _this.on(player, 'timeupdate', _this.updateProgress); + _this.on(player, 'ended', _this.updateProgress); + player.ready(Fn.bind(_this, _this.updateProgress)); + + if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) { + _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside; + } + + if (_this.keepTooltipsInside) { + _this.tooltipProgressBar = _this.addChild('TooltipProgressBar'); + } + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + SeekBar.prototype.createEl = function createEl() { + return _Slider.prototype.createEl.call(this, 'div', { + className: 'vjs-progress-holder' + }, { + 'aria-label': 'progress bar' + }); + }; + + /** + * Update the seek bars tooltip and width. + * + * @param {EventTarget~Event} [event] + * The `timeupdate` or `ended` event that caused this to run. + * + * @listens Player#timeupdate + * @listens Player#ended + */ + + + SeekBar.prototype.updateProgress = function updateProgress(event) { + this.updateAriaAttributes(this.el_); + + if (this.keepTooltipsInside) { + this.updateAriaAttributes(this.tooltipProgressBar.el_); + this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width; + + var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width')); + var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width')); + var tooltipStyle = this.tooltipProgressBar.el().style; + + tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px'; + tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px'; + tooltipStyle.right = '-' + tooltipWidth / 2 + 'px'; + } + }; + + /** + * Update ARIA accessibility attributes + * + * @param {Element} el + * The element to update with aria accessibility attributes. + */ + + + SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) { + // Allows for smooth scrubbing, when player can't keep up. + var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); + + // machine readable value of progress bar (percentage complete) + el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); + // human readable value of progress bar (time complete) + el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration())); + }; + + /** + * Get percentage of video played + * + * @return {number} + * The percentage played + */ + + + SeekBar.prototype.getPercent = function getPercent() { + var percent = this.player_.currentTime() / this.player_.duration(); + + return percent >= 1 ? 1 : percent; + }; + + /** + * Handle mouse down on seek bar + * + * @param {EventTarget~Event} event + * The `mousedown` event that caused this to run. + * + * @listens mousedown + */ + + + SeekBar.prototype.handleMouseDown = function handleMouseDown(event) { + _Slider.prototype.handleMouseDown.call(this, event); + + this.player_.scrubbing(true); + + this.videoWasPlaying = !this.player_.paused(); + + this.pauseTimer_ = this.setTimeout(function () { + this.player_.pause(); + }, 100); + }; + + /** + * Handle mouse move on seek bar + * + * @param {EventTarget~Event} event + * The `mousemove` event that caused this to run. + * + * @listens mousemove + */ + + + SeekBar.prototype.handleMouseMove = function handleMouseMove(event) { + var newTime = this.calculateDistance(event) * this.player_.duration(); + + // Don't let video end while scrubbing. + if (newTime === this.player_.duration()) { + newTime = newTime - 0.1; + } + + // Set new time (tell player to seek to new time) + this.player_.currentTime(newTime); + + if (event.type === 'mousemove') { + this.clearTimeout(this.pauseTimer_); + this.player_.pause(); + } + }; + + /** + * Handle mouse up on seek bar + * + * @param {EventTarget~Event} event + * The `mouseup` event that caused this to run. + * + * @listens mouseup + */ + + + SeekBar.prototype.handleMouseUp = function handleMouseUp(event) { + _Slider.prototype.handleMouseUp.call(this, event); + + this.clearTimeout(this.pauseTimer_); + + this.player_.scrubbing(false); + if (this.videoWasPlaying) { + this.player_.play(); + } + }; + + /** + * Move more quickly fast forward for keyboard-only users + */ + + + SeekBar.prototype.stepForward = function stepForward() { + // more quickly fast forward for keyboard-only users + this.player_.currentTime(this.player_.currentTime() + 5); + }; + + /** + * Move more quickly rewind for keyboard-only users + */ + + + SeekBar.prototype.stepBack = function stepBack() { + // more quickly rewind for keyboard-only users + this.player_.currentTime(this.player_.currentTime() - 5); + }; + + return SeekBar; +}(_slider2['default']); + +/** + * Default options for the `SeekBar` + * + * @type {Object} + * @private + */ + + +SeekBar.prototype.options_ = { + children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'], + barName: 'playProgressBar' +}; + +/** + * Call the update event for this Slider when this event happens on the player. + * + * @type {string} + */ +SeekBar.prototype.playerEvent = 'timeupdate'; + +_component2['default'].registerComponent('SeekBar', SeekBar); +exports['default'] = SeekBar; + +},{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file play-progress-bar.js + */ + + +/** + * Shows play progress + * + * @extends Component + */ +var TooltipProgressBar = function (_Component) { + _inherits(TooltipProgressBar, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function TooltipProgressBar(player, options) { + _classCallCheck(this, TooltipProgressBar); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.updateDataAttr(); + _this.on(player, 'timeupdate', _this.updateDataAttr); + player.ready(Fn.bind(_this, _this.updateDataAttr)); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + TooltipProgressBar.prototype.createEl = function createEl() { + var el = _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-tooltip-progress-bar vjs-slider-bar', + innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>' + }); + + this.tooltip = el.querySelector('.vjs-time-tooltip'); + + return el; + }; + + /** + * Updatet the data-current-time attribute for TooltipProgressBar + * + * @param {EventTarget~Event} [event] + * The `timeupdate` event that caused this function to run. + * + * @listens Player#timeupdate + */ + + + TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) { + var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); + var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); + + this.el_.setAttribute('data-current-time', formattedTime); + this.tooltip.innerHTML = formattedTime; + }; + + return TooltipProgressBar; +}(_component2['default']); + +_component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar); +exports['default'] = TooltipProgressBar; + +},{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _spacer = _dereq_(22); + +var _spacer2 = _interopRequireDefault(_spacer); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file custom-control-spacer.js + */ + + +/** + * Spacer specifically meant to be used as an insertion point for new plugins, etc. + * + * @extends Spacer + */ +var CustomControlSpacer = function (_Spacer) { + _inherits(CustomControlSpacer, _Spacer); + + function CustomControlSpacer() { + _classCallCheck(this, CustomControlSpacer); + + return _possibleConstructorReturn(this, _Spacer.apply(this, arguments)); + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this); + }; + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + CustomControlSpacer.prototype.createEl = function createEl() { + var el = _Spacer.prototype.createEl.call(this, { + className: this.buildCSSClass() + }); + + // No-flex/table-cell mode requires there be some content + // in the cell to fill the remaining space of the table. + el.innerHTML = ' '; + return el; + }; + + return CustomControlSpacer; +}(_spacer2['default']); + +_component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer); +exports['default'] = CustomControlSpacer; + +},{"22":22,"5":5}],22:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file spacer.js + */ + + +/** + * Just an empty spacer element that can be used as an append point for plugins, etc. + * Also can be used to create space between elements when necessary. + * + * @extends Component + */ +var Spacer = function (_Component) { + _inherits(Spacer, _Component); + + function Spacer() { + _classCallCheck(this, Spacer); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + Spacer.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this); + }; + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + Spacer.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: this.buildCSSClass() + }); + }; + + return Spacer; +}(_component2['default']); + +_component2['default'].registerComponent('Spacer', Spacer); + +exports['default'] = Spacer; + +},{"5":5}],23:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackMenuItem = _dereq_(31); + +var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file caption-settings-menu-item.js + */ + + +/** + * The menu item for caption track settings menu + * + * @extends TextTrackMenuItem + */ +var CaptionSettingsMenuItem = function (_TextTrackMenuItem) { + _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function CaptionSettingsMenuItem(player, options) { + _classCallCheck(this, CaptionSettingsMenuItem); + + options.track = { + player: player, + kind: options.kind, + label: options.kind + ' settings', + selectable: false, + 'default': false, + mode: 'disabled' + }; + + // CaptionSettingsMenuItem has no concept of 'selected' + options.selectable = false; + + var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); + + _this.addClass('vjs-texttrack-settings'); + _this.controlText(', opens ' + options.kind + ' settings dialog'); + return _this; + } + + /** + * This gets called when an `CaptionSettingsMenuItem` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) { + this.player().getChild('textTrackSettings').show(); + this.player().getChild('textTrackSettings').el_.focus(); + }; + + return CaptionSettingsMenuItem; +}(_textTrackMenuItem2['default']); + +_component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem); +exports['default'] = CaptionSettingsMenuItem; + +},{"31":31,"5":5}],24:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackButton = _dereq_(30); + +var _textTrackButton2 = _interopRequireDefault(_textTrackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _captionSettingsMenuItem = _dereq_(23); + +var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file captions-button.js + */ + + +/** + * The button component for toggling and selecting captions + * + * @extends TextTrackButton + */ +var CaptionsButton = function (_TextTrackButton) { + _inherits(CaptionsButton, _TextTrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when this component is ready. + */ + function CaptionsButton(player, options, ready) { + _classCallCheck(this, CaptionsButton); + + var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); + + _this.el_.setAttribute('aria-label', 'Captions Menu'); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + CaptionsButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); + }; + + /** + * Update caption menu items + * + * @param {EventTarget~Event} [event] + * The `addtrack` or `removetrack` event that caused this function to be + * called. + * + * @listens TextTrackList#addtrack + * @listens TextTrackList#removetrack + */ + + + CaptionsButton.prototype.update = function update(event) { + var threshold = 2; + + _TextTrackButton.prototype.update.call(this); + + // if native, then threshold is 1 because no settings button + if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) { + threshold = 1; + } + + if (this.items && this.items.length > threshold) { + this.show(); + } else { + this.hide(); + } + }; + + /** + * Create caption menu items + * + * @return {CaptionSettingsMenuItem[]} + * The array of current menu items. + */ + + + CaptionsButton.prototype.createItems = function createItems() { + var items = []; + + if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) { + items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ })); + } + + return _TextTrackButton.prototype.createItems.call(this, items); + }; + + return CaptionsButton; +}(_textTrackButton2['default']); + +/** + * `kind` of TextTrack to look for to associate it with this menu. + * + * @type {string} + * @private + */ + + +CaptionsButton.prototype.kind_ = 'captions'; + +/** + * The text that should display over the `CaptionsButton`s controls. Added for localization. + * + * @type {string} + * @private + */ +CaptionsButton.prototype.controlText_ = 'Captions'; + +_component2['default'].registerComponent('CaptionsButton', CaptionsButton); +exports['default'] = CaptionsButton; + +},{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackButton = _dereq_(30); + +var _textTrackButton2 = _interopRequireDefault(_textTrackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _chaptersTrackMenuItem = _dereq_(26); + +var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file chapters-button.js + */ + + +/** + * The button component for toggling and selecting chapters + * Chapters act much differently than other text tracks + * Cues are navigation vs. other tracks of alternative languages + * + * @extends TextTrackButton + */ +var ChaptersButton = function (_TextTrackButton) { + _inherits(ChaptersButton, _TextTrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when this function is ready. + */ + function ChaptersButton(player, options, ready) { + _classCallCheck(this, ChaptersButton); + + var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); + + _this.el_.setAttribute('aria-label', 'Chapters Menu'); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + ChaptersButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); + }; + + /** + * Update the menu based on the current state of its items. + * + * @param {EventTarget~Event} [event] + * An event that triggered this function to run. + * + * @listens TextTrackList#addtrack + * @listens TextTrackList#removetrack + * @listens TextTrackList#change + */ + + + ChaptersButton.prototype.update = function update(event) { + if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) { + this.setTrack(this.findChaptersTrack()); + } + _TextTrackButton.prototype.update.call(this); + }; + + /** + * Set the currently selected track for the chapters button. + * + * @param {TextTrack} track + * The new track to select. Nothing will change if this is the currently selected + * track. + */ + + + ChaptersButton.prototype.setTrack = function setTrack(track) { + if (this.track_ === track) { + return; + } + + if (!this.updateHandler_) { + this.updateHandler_ = this.update.bind(this); + } + + // here this.track_ refers to the old track instance + if (this.track_) { + var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); + + if (remoteTextTrackEl) { + remoteTextTrackEl.removeEventListener('load', this.updateHandler_); + } + + this.track_ = null; + } + + this.track_ = track; + + // here this.track_ refers to the new track instance + if (this.track_) { + this.track_.mode = 'hidden'; + + var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_); + + if (_remoteTextTrackEl) { + _remoteTextTrackEl.addEventListener('load', this.updateHandler_); + } + } + }; + + /** + * Find the track object that is currently in use by this ChaptersButton + * + * @return {TextTrack|undefined} + * The current track or undefined if none was found. + */ + + + ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() { + var tracks = this.player_.textTracks() || []; + + for (var i = tracks.length - 1; i >= 0; i--) { + // We will always choose the last track as our chaptersTrack + var track = tracks[i]; + + if (track.kind === this.kind_) { + return track; + } + } + }; + + /** + * Get the caption for the ChaptersButton based on the track label. This will also + * use the current tracks localized kind as a fallback if a label does not exist. + * + * @return {string} + * The tracks current label or the localized track kind. + */ + + + ChaptersButton.prototype.getMenuCaption = function getMenuCaption() { + if (this.track_ && this.track_.label) { + return this.track_.label; + } + return this.localize((0, _toTitleCase2['default'])(this.kind_)); + }; + + /** + * Create menu from chapter track + * + * @return {Menu} + * New menu for the chapter buttons + */ + + + ChaptersButton.prototype.createMenu = function createMenu() { + this.options_.title = this.getMenuCaption(); + return _TextTrackButton.prototype.createMenu.call(this); + }; + + /** + * Create a menu item for each text track + * + * @return {TextTrackMenuItem[]} + * Array of menu items + */ + + + ChaptersButton.prototype.createItems = function createItems() { + var items = []; + + if (!this.track_) { + return items; + } + + var cues = this.track_.cues; + + if (!cues) { + return items; + } + + for (var i = 0, l = cues.length; i < l; i++) { + var cue = cues[i]; + var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue }); + + items.push(mi); + } + + return items; + }; + + return ChaptersButton; +}(_textTrackButton2['default']); + +/** + * `kind` of TextTrack to look for to associate it with this menu. + * + * @type {string} + * @private + */ + + +ChaptersButton.prototype.kind_ = 'chapters'; + +/** + * The text that should display over the `ChaptersButton`s controls. Added for localization. + * + * @type {string} + * @private + */ +ChaptersButton.prototype.controlText_ = 'Chapters'; + +_component2['default'].registerComponent('ChaptersButton', ChaptersButton); +exports['default'] = ChaptersButton; + +},{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _menuItem = _dereq_(48); + +var _menuItem2 = _interopRequireDefault(_menuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file chapters-track-menu-item.js + */ + + +/** + * The chapter track menu item + * + * @extends MenuItem + */ +var ChaptersTrackMenuItem = function (_MenuItem) { + _inherits(ChaptersTrackMenuItem, _MenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function ChaptersTrackMenuItem(player, options) { + _classCallCheck(this, ChaptersTrackMenuItem); + + var track = options.track; + var cue = options.cue; + var currentTime = player.currentTime(); + + // Modify options for parent MenuItem class's init. + options.selectable = true; + options.label = cue.text; + options.selected = cue.startTime <= currentTime && currentTime < cue.endTime; + + var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); + + _this.track = track; + _this.cue = cue; + track.addEventListener('cuechange', Fn.bind(_this, _this.update)); + return _this; + } + + /** + * This gets called when an `ChaptersTrackMenuItem` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) { + _MenuItem.prototype.handleClick.call(this); + this.player_.currentTime(this.cue.startTime); + this.update(this.cue.startTime); + }; + + /** + * Update chapter menu item + * + * @param {EventTarget~Event} [event] + * The `cuechange` event that caused this function to run. + * + * @listens TextTrack#cuechange + */ + + + ChaptersTrackMenuItem.prototype.update = function update(event) { + var cue = this.cue; + var currentTime = this.player_.currentTime(); + + // vjs.log(currentTime, cue.startTime); + this.selected(cue.startTime <= currentTime && currentTime < cue.endTime); + }; + + return ChaptersTrackMenuItem; +}(_menuItem2['default']); + +_component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem); +exports['default'] = ChaptersTrackMenuItem; + +},{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackButton = _dereq_(30); + +var _textTrackButton2 = _interopRequireDefault(_textTrackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file descriptions-button.js + */ + + +/** + * The button component for toggling and selecting descriptions + * + * @extends TextTrackButton + */ +var DescriptionsButton = function (_TextTrackButton) { + _inherits(DescriptionsButton, _TextTrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when this component is ready. + */ + function DescriptionsButton(player, options, ready) { + _classCallCheck(this, DescriptionsButton); + + var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); + + _this.el_.setAttribute('aria-label', 'Descriptions Menu'); + + var tracks = player.textTracks(); + + if (tracks) { + (function () { + var changeHandler = Fn.bind(_this, _this.handleTracksChange); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + })(); + } + return _this; + } + + /** + * Handle text track change + * + * @param {EventTarget~Event} event + * The event that caused this function to run + * + * @listens TextTrackList#change + */ + + + DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) { + var tracks = this.player().textTracks(); + var disabled = false; + + // Check whether a track of a different kind is showing + for (var i = 0, l = tracks.length; i < l; i++) { + var track = tracks[i]; + + if (track.kind !== this.kind_ && track.mode === 'showing') { + disabled = true; + break; + } + } + + // If another track is showing, disable this menu button + if (disabled) { + this.disable(); + } else { + this.enable(); + } + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); + }; + + return DescriptionsButton; +}(_textTrackButton2['default']); + +/** + * `kind` of TextTrack to look for to associate it with this menu. + * + * @type {string} + * @private + */ + + +DescriptionsButton.prototype.kind_ = 'descriptions'; + +/** + * The text that should display over the `DescriptionsButton`s controls. Added for localization. + * + * @type {string} + * @private + */ +DescriptionsButton.prototype.controlText_ = 'Descriptions'; + +_component2['default'].registerComponent('DescriptionsButton', DescriptionsButton); +exports['default'] = DescriptionsButton; + +},{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackMenuItem = _dereq_(31); + +var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file off-text-track-menu-item.js + */ + + +/** + * A special menu item for turning of a specific type of text track + * + * @extends TextTrackMenuItem + */ +var OffTextTrackMenuItem = function (_TextTrackMenuItem) { + _inherits(OffTextTrackMenuItem, _TextTrackMenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function OffTextTrackMenuItem(player, options) { + _classCallCheck(this, OffTextTrackMenuItem); + + // Create pseudo track info + // Requires options['kind'] + options.track = { + player: player, + kind: options.kind, + label: options.kind + ' off', + 'default': false, + mode: 'disabled' + }; + + // MenuItem is selectable + options.selectable = true; + + var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options)); + + _this.selected(true); + return _this; + } + + /** + * Handle text track change + * + * @param {EventTarget~Event} event + * The event that caused this function to run + */ + + + OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { + var tracks = this.player().textTracks(); + var selected = true; + + for (var i = 0, l = tracks.length; i < l; i++) { + var track = tracks[i]; + + if (track.kind === this.track.kind && track.mode === 'showing') { + selected = false; + break; + } + } + + this.selected(selected); + }; + + return OffTextTrackMenuItem; +}(_textTrackMenuItem2['default']); + +_component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem); +exports['default'] = OffTextTrackMenuItem; + +},{"31":31,"5":5}],29:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackButton = _dereq_(30); + +var _textTrackButton2 = _interopRequireDefault(_textTrackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file subtitles-button.js + */ + + +/** + * The button component for toggling and selecting subtitles + * + * @extends TextTrackButton + */ +var SubtitlesButton = function (_TextTrackButton) { + _inherits(SubtitlesButton, _TextTrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when this component is ready. + */ + function SubtitlesButton(player, options, ready) { + _classCallCheck(this, SubtitlesButton); + + var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready)); + + _this.el_.setAttribute('aria-label', 'Subtitles Menu'); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this); + }; + + return SubtitlesButton; +}(_textTrackButton2['default']); + +/** + * `kind` of TextTrack to look for to associate it with this menu. + * + * @type {string} + * @private + */ + + +SubtitlesButton.prototype.kind_ = 'subtitles'; + +/** + * The text that should display over the `SubtitlesButton`s controls. Added for localization. + * + * @type {string} + * @private + */ +SubtitlesButton.prototype.controlText_ = 'Subtitles'; + +_component2['default'].registerComponent('SubtitlesButton', SubtitlesButton); +exports['default'] = SubtitlesButton; + +},{"30":30,"5":5}],30:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackButton = _dereq_(36); + +var _trackButton2 = _interopRequireDefault(_trackButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _textTrackMenuItem = _dereq_(31); + +var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem); + +var _offTextTrackMenuItem = _dereq_(28); + +var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track-button.js + */ + + +/** + * The base class for buttons that toggle specific text track types (e.g. subtitles) + * + * @extends MenuButton + */ +var TextTrackButton = function (_TrackButton) { + _inherits(TextTrackButton, _TrackButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + */ + function TextTrackButton(player) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, TextTrackButton); + + options.tracks = player.textTracks(); + + return _possibleConstructorReturn(this, _TrackButton.call(this, player, options)); + } + + /** + * Create a menu item for each text track + * + * @param {TextTrackMenuItem[]} [items=[]] + * Existing array of items to use during creation + * + * @return {TextTrackMenuItem[]} + * Array of menu items that were created + */ + + + TextTrackButton.prototype.createItems = function createItems() { + var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + // Add an OFF menu item to turn all tracks off + items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ })); + + var tracks = this.player_.textTracks(); + + if (!tracks) { + return items; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + // only add tracks that are of the appropriate kind and have a label + if (track.kind === this.kind_) { + items.push(new _textTrackMenuItem2['default'](this.player_, { + track: track, + // MenuItem is selectable + selectable: true + })); + } + } + + return items; + }; + + return TextTrackButton; +}(_trackButton2['default']); + +_component2['default'].registerComponent('TextTrackButton', TextTrackButton); +exports['default'] = TextTrackButton; + +},{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _menuItem = _dereq_(48); + +var _menuItem2 = _interopRequireDefault(_menuItem); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track-menu-item.js + */ + + +/** + * The specific menu item type for selecting a language within a text track kind + * + * @extends MenuItem + */ +var TextTrackMenuItem = function (_MenuItem) { + _inherits(TextTrackMenuItem, _MenuItem); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function TextTrackMenuItem(player, options) { + _classCallCheck(this, TextTrackMenuItem); + + var track = options.track; + var tracks = player.textTracks(); + + // Modify options for parent MenuItem class's init. + options.label = track.label || track.language || 'Unknown'; + options.selected = track['default'] || track.mode === 'showing'; + + var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options)); + + _this.track = track; + + if (tracks) { + (function () { + var changeHandler = Fn.bind(_this, _this.handleTracksChange); + + tracks.addEventListener('change', changeHandler); + _this.on('dispose', function () { + tracks.removeEventListener('change', changeHandler); + }); + })(); + } + + // iOS7 doesn't dispatch change events to TextTrackLists when an + // associated track's mode changes. Without something like + // Object.observe() (also not present on iOS7), it's not + // possible to detect changes to the mode attribute and polyfill + // the change event. As a poor substitute, we manually dispatch + // change events whenever the controls modify the mode. + if (tracks && tracks.onchange === undefined) { + (function () { + var event = void 0; + + _this.on(['tap', 'click'], function () { + if (_typeof(_window2['default'].Event) !== 'object') { + // Android 2.3 throws an Illegal Constructor error for window.Event + try { + event = new _window2['default'].Event('change'); + } catch (err) { + // continue regardless of error + } + } + + if (!event) { + event = _document2['default'].createEvent('Event'); + event.initEvent('change', true, true); + } + + tracks.dispatchEvent(event); + }); + })(); + } + return _this; + } + + /** + * This gets called when an `TextTrackMenuItem` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + TextTrackMenuItem.prototype.handleClick = function handleClick(event) { + var kind = this.track.kind; + var tracks = this.player_.textTracks(); + + _MenuItem.prototype.handleClick.call(this, event); + + if (!tracks) { + return; + } + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + if (track.kind !== kind) { + continue; + } + + if (track === this.track) { + track.mode = 'showing'; + } else { + track.mode = 'disabled'; + } + } + }; + + /** + * Handle text track list change + * + * @param {EventTarget~Event} event + * The `change` event that caused this function to be called. + * + * @listens TextTrackList#change + */ + + + TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) { + this.selected(this.track.mode === 'showing'); + }; + + return TextTrackMenuItem; +}(_menuItem2['default']); + +_component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem); +exports['default'] = TextTrackMenuItem; + +},{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file current-time-display.js + */ + + +/** + * Displays the current time + * + * @extends Component + */ +var CurrentTimeDisplay = function (_Component) { + _inherits(CurrentTimeDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function CurrentTimeDisplay(player, options) { + _classCallCheck(this, CurrentTimeDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.on(player, 'timeupdate', _this.updateContent); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + CurrentTimeDisplay.prototype.createEl = function createEl() { + var el = _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-current-time vjs-time-control vjs-control' + }); + + this.contentEl_ = Dom.createEl('div', { + className: 'vjs-current-time-display', + // label the current time for screen reader users + innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00' + }, { + // tell screen readers not to automatically read the time as it changes + 'aria-live': 'off' + }); + + el.appendChild(this.contentEl_); + return el; + }; + + /** + * Update current time display + * + * @param {EventTarget~Event} [event] + * The `timeupdate` event that caused this function to run. + * + * @listens Player#timeupdate + */ + + + CurrentTimeDisplay.prototype.updateContent = function updateContent(event) { + // Allows for smooth scrubbing, when player can't keep up. + var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime(); + var localizedText = this.localize('Current Time'); + var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration()); + + if (formattedTime !== this.formattedTime_) { + this.formattedTime_ = formattedTime; + this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; + } + }; + + return CurrentTimeDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay); +exports['default'] = CurrentTimeDisplay; + +},{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file duration-display.js + */ + + +/** + * Displays the duration + * + * @extends Component + */ +var DurationDisplay = function (_Component) { + _inherits(DurationDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function DurationDisplay(player, options) { + _classCallCheck(this, DurationDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.on(player, 'durationchange', _this.updateContent); + + // Also listen for timeupdate and loadedmetadata because removing those + // listeners could have broken dependent applications/libraries. These + // can likely be removed for 6.0. + _this.on(player, 'timeupdate', _this.updateContent); + _this.on(player, 'loadedmetadata', _this.updateContent); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + DurationDisplay.prototype.createEl = function createEl() { + var el = _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-duration vjs-time-control vjs-control' + }); + + this.contentEl_ = Dom.createEl('div', { + className: 'vjs-duration-display', + // label the duration time for screen reader users + innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00' + }, { + // tell screen readers not to automatically read the time as it changes + 'aria-live': 'off' + }); + + el.appendChild(this.contentEl_); + return el; + }; + + /** + * Update duration time display. + * + * @param {EventTarget~Event} [event] + * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused + * this function to be called. + * + * @listens Player#durationchange + * @listens Player#timeupdate + * @listens Player#loadedmetadata + */ + + + DurationDisplay.prototype.updateContent = function updateContent(event) { + var duration = this.player_.duration(); + + if (duration && this.duration_ !== duration) { + this.duration_ = duration; + var localizedText = this.localize('Duration Time'); + var formattedTime = (0, _formatTime2['default'])(duration); + + // label the duration time for screen reader users + this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; + } + }; + + return DurationDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('DurationDisplay', DurationDisplay); +exports['default'] = DurationDisplay; + +},{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file remaining-time-display.js + */ + + +/** + * Displays the time left in the video + * + * @extends Component + */ +var RemainingTimeDisplay = function (_Component) { + _inherits(RemainingTimeDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function RemainingTimeDisplay(player, options) { + _classCallCheck(this, RemainingTimeDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.on(player, 'timeupdate', _this.updateContent); + _this.on(player, 'durationchange', _this.updateContent); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + RemainingTimeDisplay.prototype.createEl = function createEl() { + var el = _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-remaining-time vjs-time-control vjs-control' + }); + + this.contentEl_ = Dom.createEl('div', { + className: 'vjs-remaining-time-display', + // label the remaining time for screen reader users + innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00' + }, { + // tell screen readers not to automatically read the time as it changes + 'aria-live': 'off' + }); + + el.appendChild(this.contentEl_); + return el; + }; + + /** + * Update remaining time display. + * + * @param {EventTarget~Event} [event] + * The `timeupdate` or `durationchange` event that caused this to run. + * + * @listens Player#timeupdate + * @listens Player#durationchange + */ + + + RemainingTimeDisplay.prototype.updateContent = function updateContent(event) { + if (this.player_.duration()) { + var localizedText = this.localize('Remaining Time'); + var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime()); + + if (formattedTime !== this.formattedTime_) { + this.formattedTime_ = formattedTime; + this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime; + } + } + + // Allows for smooth scrubbing, when player can't keep up. + // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); + // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); + }; + + return RemainingTimeDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay); +exports['default'] = RemainingTimeDisplay; + +},{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file time-divider.js + */ + + +/** + * The separator between the current time and duration. + * Can be hidden if it's not needed in the design. + * + * @extends Component + */ +var TimeDivider = function (_Component) { + _inherits(TimeDivider, _Component); + + function TimeDivider() { + _classCallCheck(this, TimeDivider); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Create the component's DOM element + * + * @return {Element} + * The element that was created. + */ + TimeDivider.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-time-control vjs-time-divider', + innerHTML: '<div><span>/</span></div>' + }); + }; + + return TimeDivider; +}(_component2['default']); + +_component2['default'].registerComponent('TimeDivider', TimeDivider); +exports['default'] = TimeDivider; + +},{"5":5}],36:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _menuButton = _dereq_(47); + +var _menuButton2 = _interopRequireDefault(_menuButton); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file track-button.js + */ + + +/** + * The base class for buttons that toggle specific track types (e.g. subtitles). + * + * @extends MenuButton + */ +var TrackButton = function (_MenuButton) { + _inherits(TrackButton, _MenuButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function TrackButton(player, options) { + _classCallCheck(this, TrackButton); + + var tracks = options.tracks; + + var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options)); + + if (_this.items.length <= 1) { + _this.hide(); + } + + if (!tracks) { + return _possibleConstructorReturn(_this); + } + + var updateHandler = Fn.bind(_this, _this.update); + + tracks.addEventListener('removetrack', updateHandler); + tracks.addEventListener('addtrack', updateHandler); + + _this.player_.on('dispose', function () { + tracks.removeEventListener('removetrack', updateHandler); + tracks.removeEventListener('addtrack', updateHandler); + }); + return _this; + } + + return TrackButton; +}(_menuButton2['default']); + +_component2['default'].registerComponent('TrackButton', TrackButton); +exports['default'] = TrackButton; + +},{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _slider = _dereq_(57); + +var _slider2 = _interopRequireDefault(_slider); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +_dereq_(39); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file volume-bar.js + */ + + +// Required children + + +/** + * The bar that contains the volume level and can be clicked on to adjust the level + * + * @extends Slider + */ +var VolumeBar = function (_Slider) { + _inherits(VolumeBar, _Slider); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function VolumeBar(player, options) { + _classCallCheck(this, VolumeBar); + + var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options)); + + _this.on(player, 'volumechange', _this.updateARIAAttributes); + player.ready(Fn.bind(_this, _this.updateARIAAttributes)); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + VolumeBar.prototype.createEl = function createEl() { + return _Slider.prototype.createEl.call(this, 'div', { + className: 'vjs-volume-bar vjs-slider-bar' + }, { + 'aria-label': 'volume level' + }); + }; + + /** + * Handle movement events on the {@link VolumeMenuButton}. + * + * @param {EventTarget~Event} event + * The event that caused this function to run. + * + * @listens mousemove + */ + + + VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) { + this.checkMuted(); + this.player_.volume(this.calculateDistance(event)); + }; + + /** + * If the player is muted unmute it. + */ + + + VolumeBar.prototype.checkMuted = function checkMuted() { + if (this.player_.muted()) { + this.player_.muted(false); + } + }; + + /** + * Get percent of volume level + * + * @return {number} + * Volume level percent as a decimal number. + */ + + + VolumeBar.prototype.getPercent = function getPercent() { + if (this.player_.muted()) { + return 0; + } + return this.player_.volume(); + }; + + /** + * Increase volume level for keyboard users + */ + + + VolumeBar.prototype.stepForward = function stepForward() { + this.checkMuted(); + this.player_.volume(this.player_.volume() + 0.1); + }; + + /** + * Decrease volume level for keyboard users + */ + + + VolumeBar.prototype.stepBack = function stepBack() { + this.checkMuted(); + this.player_.volume(this.player_.volume() - 0.1); + }; + + /** + * Update ARIA accessibility attributes + * + * @param {EventTarget~Event} [event] + * The `volumechange` event that caused this function to run. + * + * @listens Player#volumechange + */ + + + VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) { + // Current value of volume bar as a percentage + var volume = (this.player_.volume() * 100).toFixed(2); + + this.el_.setAttribute('aria-valuenow', volume); + this.el_.setAttribute('aria-valuetext', volume + '%'); + }; + + return VolumeBar; +}(_slider2['default']); + +/** + * Default options for the `VolumeBar` + * + * @type {Object} + * @private + */ + + +VolumeBar.prototype.options_ = { + children: ['volumeLevel'], + barName: 'volumeLevel' +}; + +/** + * Call the update event for this Slider when this event happens on the player. + * + * @type {string} + */ +VolumeBar.prototype.playerEvent = 'volumechange'; + +_component2['default'].registerComponent('VolumeBar', VolumeBar); +exports['default'] = VolumeBar; + +},{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +_dereq_(37); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file volume-control.js + */ + + +// Required children + + +/** + * The component for controlling the volume level + * + * @extends Component + */ +var VolumeControl = function (_Component) { + _inherits(VolumeControl, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + */ + function VolumeControl(player, options) { + _classCallCheck(this, VolumeControl); + + // hide volume controls when they're not supported by the current tech + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + if (player.tech_ && player.tech_.featuresVolumeControl === false) { + _this.addClass('vjs-hidden'); + } + _this.on(player, 'loadstart', function () { + if (player.tech_.featuresVolumeControl === false) { + this.addClass('vjs-hidden'); + } else { + this.removeClass('vjs-hidden'); + } + }); + return _this; + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + + + VolumeControl.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-volume-control vjs-control' + }); + }; + + return VolumeControl; +}(_component2['default']); + +/** + * Default options for the `VolumeControl` + * + * @type {Object} + * @private + */ + + +VolumeControl.prototype.options_ = { + children: ['volumeBar'] +}; + +_component2['default'].registerComponent('VolumeControl', VolumeControl); +exports['default'] = VolumeControl; + +},{"37":37,"5":5}],39:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file volume-level.js + */ + + +/** + * Shows volume level + * + * @extends Component + */ +var VolumeLevel = function (_Component) { + _inherits(VolumeLevel, _Component); + + function VolumeLevel() { + _classCallCheck(this, VolumeLevel); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + VolumeLevel.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-volume-level', + innerHTML: '<span class="vjs-control-text"></span>' + }); + }; + + return VolumeLevel; +}(_component2['default']); + +_component2['default'].registerComponent('VolumeLevel', VolumeLevel); +exports['default'] = VolumeLevel; + +},{"5":5}],40:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _popup = _dereq_(54); + +var _popup2 = _interopRequireDefault(_popup); + +var _popupButton = _dereq_(53); + +var _popupButton2 = _interopRequireDefault(_popupButton); + +var _muteToggle = _dereq_(11); + +var _muteToggle2 = _interopRequireDefault(_muteToggle); + +var _volumeBar = _dereq_(37); + +var _volumeBar2 = _interopRequireDefault(_volumeBar); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file volume-menu-button.js + */ + + +/** + * Button for volume popup + * + * @extends PopupButton + */ +var VolumeMenuButton = function (_PopupButton) { + _inherits(VolumeMenuButton, _PopupButton); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + */ + function VolumeMenuButton(player) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, VolumeMenuButton); + + // Default to inline + if (options.inline === undefined) { + options.inline = true; + } + + // If the vertical option isn't passed at all, default to true. + if (options.vertical === undefined) { + // If an inline volumeMenuButton is used, we should default to using + // a horizontal slider for obvious reasons. + if (options.inline) { + options.vertical = false; + } else { + options.vertical = true; + } + } + + // The vertical option needs to be set on the volumeBar as well, + // since that will need to be passed along to the VolumeBar constructor + options.volumeBar = options.volumeBar || {}; + options.volumeBar.vertical = !!options.vertical; + + // Same listeners as MuteToggle + var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options)); + + _this.on(player, 'volumechange', _this.volumeUpdate); + _this.on(player, 'loadstart', _this.volumeUpdate); + + // hide mute toggle if the current tech doesn't support volume control + function updateVisibility() { + if (player.tech_ && player.tech_.featuresVolumeControl === false) { + this.addClass('vjs-hidden'); + } else { + this.removeClass('vjs-hidden'); + } + } + + updateVisibility.call(_this); + _this.on(player, 'loadstart', updateVisibility); + + _this.on(_this.volumeBar, ['slideractive', 'focus'], function () { + this.addClass('vjs-slider-active'); + }); + + _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () { + this.removeClass('vjs-slider-active'); + }); + + _this.on(_this.volumeBar, ['focus'], function () { + this.addClass('vjs-lock-showing'); + }); + + _this.on(_this.volumeBar, ['blur'], function () { + this.removeClass('vjs-lock-showing'); + }); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() { + var orientationClass = ''; + + if (this.options_.vertical) { + orientationClass = 'vjs-volume-menu-button-vertical'; + } else { + orientationClass = 'vjs-volume-menu-button-horizontal'; + } + + return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass; + }; + + /** + * Create the VolumeMenuButton popup + * + * @return {Popup} + * The popup that was created + */ + + + VolumeMenuButton.prototype.createPopup = function createPopup() { + var popup = new _popup2['default'](this.player_, { + contentElType: 'div' + }); + + var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar); + + popup.addChild(vb); + + this.menuContent = popup; + this.volumeBar = vb; + + this.attachVolumeBarEvents(); + + return popup; + }; + + /** + * This gets called when an `VolumeMenuButton` is "clicked". See + * {@link ClickableComponent} for more detailed information on what a click can be. + * + * @param {EventTarget~Event} [event] + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + VolumeMenuButton.prototype.handleClick = function handleClick(event) { + _muteToggle2['default'].prototype.handleClick.call(this); + _PopupButton.prototype.handleClick.call(this); + }; + + /** + * Add events listeners to the created `VolumeBar`. + */ + + + VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() { + this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown)); + }; + + /** + * Handle the `mousedown` and `touchdown` events on the `VolumeBar` + * + * @param {EventTarget~Event} [event] + * The `mousedown` or `touchdown` event that caused this to run. + * + * @listens mousedown + * @listens touchdown + */ + + + VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) { + this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); + this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp); + }; + + /** + * Handle the `mouseup` and `touchend` events on the `VolumeBar` + * + * @param {EventTarget~Event} [event] + * The `mouseup` or `touchend` event that caused this to run. + * + * @listens mouseup + * @listens touchend + */ + + + VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) { + this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove)); + }; + + return VolumeMenuButton; +}(_popupButton2['default']); + +/** + * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate + */ + + +VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update; + +/** + * The text that should display over the `VolumeMenuButton`s controls. Added for localization. + * + * @type {string} + * @private + */ +VolumeMenuButton.prototype.controlText_ = 'Mute'; + +_component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton); +exports['default'] = VolumeMenuButton; + +},{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _modalDialog = _dereq_(50); + +var _modalDialog2 = _interopRequireDefault(_modalDialog); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file error-display.js + */ + + +/** + * A display that indicates an error has occurred. This means that the video + * is unplayable. + * + * @extends ModalDialog + */ +var ErrorDisplay = function (_ModalDialog) { + _inherits(ErrorDisplay, _ModalDialog); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function ErrorDisplay(player, options) { + _classCallCheck(this, ErrorDisplay); + + var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options)); + + _this.on(player, 'error', _this.open); + return _this; + } + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + * + * @deprecated Since version 5. + */ + + + ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() { + return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this); + }; + + /** + * Gets the localized error message based on the `Player`s error. + * + * @return {string} + * The `Player`s error message localized or an empty string. + */ + + + ErrorDisplay.prototype.content = function content() { + var error = this.player().error(); + + return error ? this.localize(error.message) : ''; + }; + + return ErrorDisplay; +}(_modalDialog2['default']); + +/** + * The default options for an `ErrorDisplay`. + * + * @private + */ + + +ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, { + fillAlways: true, + temporary: false, + uncloseable: true +}); + +_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay); +exports['default'] = ErrorDisplay; + +},{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +/** + * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It + * adds shorthand functions that wrap around lengthy functions. For example: + * the `on` function is a wrapper around `addEventListener`. + * + * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget} + * @class EventTarget + */ +var EventTarget = function EventTarget() {}; + +/** + * A Custom DOM event. + * + * @typedef {Object} EventTarget~Event + * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent} + */ + +/** + * All event listeners should follow the following format. + * + * @callback EventTarget~EventListener + * @this {EventTarget} + * + * @param {EventTarget~Event} event + * the event that triggered this function + * + * @param {Object} [hash] + * hash of data sent during the event + */ + +/** + * An object containing event names as keys and booleans as values. + * + * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger} + * will have extra functionality. See that function for more information. + * + * @property EventTarget.prototype.allowedEvents_ + * @private + */ +/** + * @file src/js/event-target.js + */ +EventTarget.prototype.allowedEvents_ = {}; + +/** + * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a + * function that will get called when an event with a certain name gets triggered. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to call with `EventTarget`s + */ +EventTarget.prototype.on = function (type, fn) { + // Remove the addEventListener alias before calling Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + Events.on(this, type, fn); + this.addEventListener = ael; +}; + +/** + * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#on} + */ +EventTarget.prototype.addEventListener = EventTarget.prototype.on; + +/** + * Removes an `event listener` for a specific event from an instance of `EventTarget`. + * This makes it so that the `event listener` will no longer get called when the + * named event happens. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to remove. + */ +EventTarget.prototype.off = function (type, fn) { + Events.off(this, type, fn); +}; + +/** + * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#off} + */ +EventTarget.prototype.removeEventListener = EventTarget.prototype.off; + +/** + * This function will add an `event listener` that gets triggered only once. After the + * first trigger it will get removed. This is like adding an `event listener` + * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to be called once for each event name. + */ +EventTarget.prototype.one = function (type, fn) { + // Remove the addEventListener alialing Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + Events.one(this, type, fn); + this.addEventListener = ael; +}; + +/** + * This function causes an event to happen. This will then cause any `event listeners` + * that are waiting for that event, to get called. If there are no `event listeners` + * for an event then nothing will happen. + * + * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. + * Trigger will also call the `on` + `uppercaseEventName` function. + * + * Example: + * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call + * `onClick` if it exists. + * + * @param {string|EventTarget~Event|Object} event + * The name of the event, an `Event`, or an object with a key of type set to + * an event name. + */ +EventTarget.prototype.trigger = function (event) { + var type = event.type || event; + + if (typeof event === 'string') { + event = { type: type }; + } + event = Events.fixEvent(event); + + if (this.allowedEvents_[type] && this['on' + type]) { + this['on' + type](event); + } + + Events.trigger(this, event); +}; + +/** + * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#trigger} + */ +EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; + +exports['default'] = EventTarget; + +},{"82":82}],43:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _obj = _dereq_(88); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * @file extend.js + * @module extend + */ + +/** + * A combination of node inherits and babel's inherits (after transpile). + * Both work the same but node adds `super_` to the subClass + * and Bable adds the superClass as __proto__. Both seem useful. + * + * @param {Object} subClass + * The class to inherit to + * + * @param {Object} superClass + * The class to inherit from + * + * @private + */ +var _inherits = function _inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + + if (superClass) { + // node + subClass.super_ = superClass; + } +}; + +/** + * Function for subclassing using the same inheritance that + * videojs uses internally + * + * @param {Object} superClass + * The class to inherit from + * + * @param {Object} [subClassMethods={}] + * The class to inherit to + * + * @return {Object} + * The new object with subClassMethods that inherited superClass. + */ +var extendFn = function extendFn(superClass) { + var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var subClass = function subClass() { + superClass.apply(this, arguments); + }; + + var methods = {}; + + if ((0, _obj.isObject)(subClassMethods)) { + if (typeof subClassMethods.init === 'function') { + _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.'); + subClassMethods.constructor = subClassMethods.init; + } + if (subClassMethods.constructor !== Object.prototype.constructor) { + subClass = subClassMethods.constructor; + } + methods = subClassMethods; + } else if (typeof subClassMethods === 'function') { + subClass = subClassMethods; + } + + _inherits(subClass, superClass); + + // Extend subObj's prototype with functions and other properties from props + for (var name in methods) { + if (methods.hasOwnProperty(name)) { + subClass.prototype[name] = methods[name]; + } + } + + return subClass; +}; + +exports['default'] = extendFn; + +},{"86":86,"88":88}],44:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * Store the browser-specific methods for the fullscreen API. + * + * @type {Object} + * @see [Specification]{@link https://fullscreen.spec.whatwg.org} + * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js} + */ +var FullscreenApi = {}; + +// browser API methods +/** + * @file fullscreen-api.js + * @module fullscreen-api + * @private + */ +var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], +// WebKit +['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], +// Old WebKit (Safari 5.1) +['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], +// Mozilla +['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], +// Microsoft +['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; + +var specApi = apiMap[0]; +var browserApi = void 0; + +// determine the supported set of functions +for (var i = 0; i < apiMap.length; i++) { + // check for exitFullscreen function + if (apiMap[i][1] in _document2['default']) { + browserApi = apiMap[i]; + break; + } +} + +// map the browser API names to the spec API names +if (browserApi) { + for (var _i = 0; _i < browserApi.length; _i++) { + FullscreenApi[specApi[_i]] = browserApi[_i]; + } +} + +exports['default'] = FullscreenApi; + +},{"94":94}],45:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file loading-spinner.js + */ + + +/** + * A loading spinner for use during waiting/loading events. + * + * @extends Component + */ +var LoadingSpinner = function (_Component) { + _inherits(LoadingSpinner, _Component); + + function LoadingSpinner() { + _classCallCheck(this, LoadingSpinner); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Create the `LoadingSpinner`s DOM element. + * + * @return {Element} + * The dom element that gets created. + */ + LoadingSpinner.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-loading-spinner', + dir: 'ltr' + }); + }; + + return LoadingSpinner; +}(_component2['default']); + +_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner); +exports['default'] = LoadingSpinner; + +},{"5":5}],46:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _obj = _dereq_(88); + +/** + * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. + * + * @param {number|string|Object|MediaError} value + * This can be of multiple types: + * - number: should be a standard error code + * - string: an error message (the code will be 0) + * - Object: arbitrary properties + * - `MediaError` (native): used to populate a video.js `MediaError` object + * - `MediaError` (video.js): will return itself if it's already a + * video.js `MediaError` object. + * + * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror} + * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes} + * + * @class MediaError + */ +function MediaError(value) { + + // Allow redundant calls to this constructor to avoid having `instanceof` + // checks peppered around the code. + if (value instanceof MediaError) { + return value; + } + + if (typeof value === 'number') { + this.code = value; + } else if (typeof value === 'string') { + // default code is zero, so this is a custom error + this.message = value; + } else if ((0, _obj.isObject)(value)) { + + // We assign the `code` property manually because native `MediaError` objects + // do not expose it as an own/enumerable property of the object. + if (typeof value.code === 'number') { + this.code = value.code; + } + + (0, _obj.assign)(this, value); + } + + if (!this.message) { + this.message = MediaError.defaultMessages[this.code] || ''; + } +} + +/** + * The error code that refers two one of the defined `MediaError` types + * + * @type {Number} + */ +/** + * @file media-error.js + */ +MediaError.prototype.code = 0; + +/** + * An optional message that to show with the error. Message is not part of the HTML5 + * video spec but allows for more informative custom errors. + * + * @type {String} + */ +MediaError.prototype.message = ''; + +/** + * An optional status code that can be set by plugins to allow even more detail about + * the error. For example a plugin might provide a specific HTTP status code and an + * error message for that code. Then when the plugin gets that error this class will + * know how to display an error message for it. This allows a custom message to show + * up on the `Player` error overlay. + * + * @type {Array} + */ +MediaError.prototype.status = null; + +/** + * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the + * specification listed under {@link MediaError} for more information. + * + * @enum {array} + * @readonly + * @property {string} 0 - MEDIA_ERR_CUSTOM + * @property {string} 1 - MEDIA_ERR_CUSTOM + * @property {string} 2 - MEDIA_ERR_ABORTED + * @property {string} 3 - MEDIA_ERR_NETWORK + * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED + * @property {string} 5 - MEDIA_ERR_ENCRYPTED + */ +MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; + +/** + * The default `MediaError` messages based on the {@link MediaError.errorTypes}. + * + * @type {Array} + * @constant + */ +MediaError.defaultMessages = { + 1: 'You aborted the media playback', + 2: 'A network error caused the media download to fail part-way.', + 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', + 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', + 5: 'The media is encrypted and we do not have the keys to decrypt it.' +}; + +// Add types as properties on MediaError +// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; +for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { + MediaError[MediaError.errorTypes[errNum]] = errNum; + // values should be accessible on both the class and instance + MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; +} + +// jsdocs for instance/static members added above +// instance methods use `#` and static methods use `.` +/** + * W3C error code for any custom error. + * + * @member MediaError#MEDIA_ERR_CUSTOM + * @constant {number} + * @default 0 + */ +/** + * W3C error code for any custom error. + * + * @member MediaError.MEDIA_ERR_CUSTOM + * @constant {number} + * @default 0 + */ + +/** + * W3C error code for media error aborted. + * + * @member MediaError#MEDIA_ERR_ABORTED + * @constant {number} + * @default 1 + */ +/** + * W3C error code for media error aborted. + * + * @member MediaError.MEDIA_ERR_ABORTED + * @constant {number} + * @default 1 + */ + +/** + * W3C error code for any network error. + * + * @member MediaError#MEDIA_ERR_NETWORK + * @constant {number} + * @default 2 + */ +/** + * W3C error code for any network error. + * + * @member MediaError.MEDIA_ERR_NETWORK + * @constant {number} + * @default 2 + */ + +/** + * W3C error code for any decoding error. + * + * @member MediaError#MEDIA_ERR_DECODE + * @constant {number} + * @default 3 + */ +/** + * W3C error code for any decoding error. + * + * @member MediaError.MEDIA_ERR_DECODE + * @constant {number} + * @default 3 + */ + +/** + * W3C error code for any time that a source is not supported. + * + * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED + * @constant {number} + * @default 4 + */ +/** + * W3C error code for any time that a source is not supported. + * + * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED + * @constant {number} + * @default 4 + */ + +/** + * W3C error code for any time that a source is encrypted. + * + * @member MediaError#MEDIA_ERR_ENCRYPTED + * @constant {number} + * @default 5 + */ +/** + * W3C error code for any time that a source is encrypted. + * + * @member MediaError.MEDIA_ERR_ENCRYPTED + * @constant {number} + * @default 5 + */ + +exports['default'] = MediaError; + +},{"88":88}],47:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _clickableComponent = _dereq_(3); + +var _clickableComponent2 = _interopRequireDefault(_clickableComponent); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _menu = _dereq_(49); + +var _menu2 = _interopRequireDefault(_menu); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file menu-button.js + */ + + +/** + * A `MenuButton` class for any popup {@link Menu}. + * + * @extends ClickableComponent + */ +var MenuButton = function (_ClickableComponent) { + _inherits(MenuButton, _ClickableComponent); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + */ + function MenuButton(player) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, MenuButton); + + var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); + + _this.update(); + + _this.enabled_ = true; + + _this.el_.setAttribute('aria-haspopup', 'true'); + _this.el_.setAttribute('role', 'menuitem'); + _this.on('keydown', _this.handleSubmenuKeyPress); + return _this; + } + + /** + * Update the menu based on the current state of its items. + */ + + + MenuButton.prototype.update = function update() { + var menu = this.createMenu(); + + if (this.menu) { + this.removeChild(this.menu); + } + + this.menu = menu; + this.addChild(menu); + + /** + * Track the state of the menu button + * + * @type {Boolean} + * @private + */ + this.buttonPressed_ = false; + this.el_.setAttribute('aria-expanded', 'false'); + + if (this.items && this.items.length === 0) { + this.hide(); + } else if (this.items && this.items.length > 1) { + this.show(); + } + }; + + /** + * Create the menu and add all items to it. + * + * @return {Menu} + * The constructed menu + */ + + + MenuButton.prototype.createMenu = function createMenu() { + var menu = new _menu2['default'](this.player_); + + // Add a title list item to the top + if (this.options_.title) { + var title = Dom.createEl('li', { + className: 'vjs-menu-title', + innerHTML: (0, _toTitleCase2['default'])(this.options_.title), + tabIndex: -1 + }); + + menu.children_.unshift(title); + Dom.insertElFirst(title, menu.contentEl()); + } + + this.items = this.createItems(); + + if (this.items) { + // Add menu items to the menu + for (var i = 0; i < this.items.length; i++) { + menu.addItem(this.items[i]); + } + } + + return menu; + }; + + /** + * Create the list of menu items. Specific to each subclass. + * + * @abstract + */ + + + MenuButton.prototype.createItems = function createItems() {}; + + /** + * Create the `MenuButtons`s DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + MenuButton.prototype.createEl = function createEl() { + return _ClickableComponent.prototype.createEl.call(this, 'div', { + className: this.buildCSSClass() + }); + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + MenuButton.prototype.buildCSSClass = function buildCSSClass() { + var menuButtonClass = 'vjs-menu-button'; + + // If the inline option is passed, we want to use different styles altogether. + if (this.options_.inline === true) { + menuButtonClass += '-inline'; + } else { + menuButtonClass += '-popup'; + } + + return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); + }; + + /** + * Handle a click on a `MenuButton`. + * See {@link ClickableComponent#handleClick} for instances where this is called. + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + MenuButton.prototype.handleClick = function handleClick(event) { + // When you click the button it adds focus, which will show the menu. + // So we'll remove focus when the mouse leaves the button. Focus is needed + // for tab navigation. + + this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) { + this.unpressButton(); + this.el_.blur(); + })); + if (this.buttonPressed_) { + this.unpressButton(); + } else { + this.pressButton(); + } + }; + + /** + * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See + * {@link ClickableComponent#handleKeyPress} for instances where this is called. + * + * @param {EventTarget~Event} event + * The `keydown` event that caused this function to be called. + * + * @listens keydown + */ + + + MenuButton.prototype.handleKeyPress = function handleKeyPress(event) { + + // Escape (27) key or Tab (9) key unpress the 'button' + if (event.which === 27 || event.which === 9) { + if (this.buttonPressed_) { + this.unpressButton(); + } + // Don't preventDefault for Tab key - we still want to lose focus + if (event.which !== 9) { + event.preventDefault(); + } + // Up (38) key or Down (40) key press the 'button' + } else if (event.which === 38 || event.which === 40) { + if (!this.buttonPressed_) { + this.pressButton(); + event.preventDefault(); + } + } else { + _ClickableComponent.prototype.handleKeyPress.call(this, event); + } + }; + + /** + * Handle a `keydown` event on a sub-menu. The listener for this is added in + * the constructor. + * + * @param {EventTarget~Event} event + * Key press event + * + * @listens keydown + */ + + + MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) { + + // Escape (27) key or Tab (9) key unpress the 'button' + if (event.which === 27 || event.which === 9) { + if (this.buttonPressed_) { + this.unpressButton(); + } + // Don't preventDefault for Tab key - we still want to lose focus + if (event.which !== 9) { + event.preventDefault(); + } + } + }; + + /** + * Put the current `MenuButton` into a pressed state. + */ + + + MenuButton.prototype.pressButton = function pressButton() { + if (this.enabled_) { + this.buttonPressed_ = true; + this.menu.lockShowing(); + this.el_.setAttribute('aria-expanded', 'true'); + // set the focus into the submenu + this.menu.focus(); + } + }; + + /** + * Take the current `MenuButton` out of a pressed state. + */ + + + MenuButton.prototype.unpressButton = function unpressButton() { + if (this.enabled_) { + this.buttonPressed_ = false; + this.menu.unlockShowing(); + this.el_.setAttribute('aria-expanded', 'false'); + // Set focus back to this menu button + this.el_.focus(); + } + }; + + /** + * Disable the `MenuButton`. Don't allow it to be clicked. + * + * @return {MenuButton} + * Returns itself; method can be chained. + */ + + + MenuButton.prototype.disable = function disable() { + // Unpress, but don't force focus on this button + this.buttonPressed_ = false; + this.menu.unlockShowing(); + this.el_.setAttribute('aria-expanded', 'false'); + + this.enabled_ = false; + + return _ClickableComponent.prototype.disable.call(this); + }; + + /** + * Enable the `MenuButton`. Allow it to be clicked. + * + * @return {MenuButton} + * Returns itself; method can be chained. + */ + + + MenuButton.prototype.enable = function enable() { + this.enabled_ = true; + + return _ClickableComponent.prototype.enable.call(this); + }; + + return MenuButton; +}(_clickableComponent2['default']); + +_component2['default'].registerComponent('MenuButton', MenuButton); +exports['default'] = MenuButton; + +},{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _clickableComponent = _dereq_(3); + +var _clickableComponent2 = _interopRequireDefault(_clickableComponent); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _obj = _dereq_(88); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file menu-item.js + */ + + +/** + * The component for a menu item. `<li>` + * + * @extends ClickableComponent + */ +var MenuItem = function (_ClickableComponent) { + _inherits(MenuItem, _ClickableComponent); + + /** + * Creates an instance of the this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options={}] + * The key/value store of player options. + * + */ + function MenuItem(player, options) { + _classCallCheck(this, MenuItem); + + var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); + + _this.selectable = options.selectable; + + _this.selected(options.selected); + + if (_this.selectable) { + // TODO: May need to be either menuitemcheckbox or menuitemradio, + // and may need logical grouping of menu items. + _this.el_.setAttribute('role', 'menuitemcheckbox'); + } else { + _this.el_.setAttribute('role', 'menuitem'); + } + return _this; + } + + /** + * Create the `MenuItem's DOM element + * + * @param {string} [type=li] + * Element's node type, not actually used, always set to `li`. + * + * @param {Object} [props={}] + * An object of properties that should be set on the element + * + * @param {Object} [attrs={}] + * An object of attributes that should be set on the element + * + * @return {Element} + * The element that gets created. + */ + + + MenuItem.prototype.createEl = function createEl(type, props, attrs) { + return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({ + className: 'vjs-menu-item', + innerHTML: this.localize(this.options_.label), + tabIndex: -1 + }, props), attrs); + }; + + /** + * Any click on a `MenuItem` puts int into the selected state. + * See {@link ClickableComponent#handleClick} for instances where this is called. + * + * @param {EventTarget~Event} event + * The `keydown`, `tap`, or `click` event that caused this function to be + * called. + * + * @listens tap + * @listens click + */ + + + MenuItem.prototype.handleClick = function handleClick(event) { + this.selected(true); + }; + + /** + * Set the state for this menu item as selected or not. + * + * @param {boolean} selected + * if the menu item is selected or not + */ + + + MenuItem.prototype.selected = function selected(_selected) { + if (this.selectable) { + if (_selected) { + this.addClass('vjs-selected'); + this.el_.setAttribute('aria-checked', 'true'); + // aria-checked isn't fully supported by browsers/screen readers, + // so indicate selected state to screen reader in the control text. + this.controlText(', selected'); + } else { + this.removeClass('vjs-selected'); + this.el_.setAttribute('aria-checked', 'false'); + // Indicate un-selected state to screen reader + // Note that a space clears out the selected state text + this.controlText(' '); + } + } + }; + + return MenuItem; +}(_clickableComponent2['default']); + +_component2['default'].registerComponent('MenuItem', MenuItem); +exports['default'] = MenuItem; + +},{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file menu.js + */ + + +/** + * The Menu component is used to build popup menus, including subtitle and + * captions selection menus. + * + * @extends Component + */ +var Menu = function (_Component) { + _inherits(Menu, _Component); + + /** + * Create an instance of this class. + * + * @param {Player} player + * the player that this component should attach to + * + * @param {Object} [options] + * Object of option names and values + * + */ + function Menu(player, options) { + _classCallCheck(this, Menu); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.focusedChild_ = -1; + + _this.on('keydown', _this.handleKeyPress); + return _this; + } + + /** + * Add a {@link MenuItem} to the menu. + * + * @param {Object|string} component + * The name or instance of the `MenuItem` to add. + * + */ + + + Menu.prototype.addItem = function addItem(component) { + this.addChild(component); + component.on('click', Fn.bind(this, function (event) { + this.unlockShowing(); + // TODO: Need to set keyboard focus back to the menuButton + })); + }; + + /** + * Create the `Menu`s DOM element. + * + * @return {Element} + * the element that was created + */ + + + Menu.prototype.createEl = function createEl() { + var contentElType = this.options_.contentElType || 'ul'; + + this.contentEl_ = Dom.createEl(contentElType, { + className: 'vjs-menu-content' + }); + + this.contentEl_.setAttribute('role', 'menu'); + + var el = _Component.prototype.createEl.call(this, 'div', { + append: this.contentEl_, + className: 'vjs-menu' + }); + + el.setAttribute('role', 'presentation'); + el.appendChild(this.contentEl_); + + // Prevent clicks from bubbling up. Needed for Menu Buttons, + // where a click on the parent is significant + Events.on(el, 'click', function (event) { + event.preventDefault(); + event.stopImmediatePropagation(); + }); + + return el; + }; + + /** + * Handle a `keydown` event on this menu. This listener is added in the constructor. + * + * @param {EventTarget~Event} event + * A `keydown` event that happened on the menu. + * + * @listens keydown + */ + + + Menu.prototype.handleKeyPress = function handleKeyPress(event) { + // Left and Down Arrows + if (event.which === 37 || event.which === 40) { + event.preventDefault(); + this.stepForward(); + + // Up and Right Arrows + } else if (event.which === 38 || event.which === 39) { + event.preventDefault(); + this.stepBack(); + } + }; + + /** + * Move to next (lower) menu item for keyboard users. + */ + + + Menu.prototype.stepForward = function stepForward() { + var stepChild = 0; + + if (this.focusedChild_ !== undefined) { + stepChild = this.focusedChild_ + 1; + } + this.focus(stepChild); + }; + + /** + * Move to previous (higher) menu item for keyboard users. + */ + + + Menu.prototype.stepBack = function stepBack() { + var stepChild = 0; + + if (this.focusedChild_ !== undefined) { + stepChild = this.focusedChild_ - 1; + } + this.focus(stepChild); + }; + + /** + * Set focus on a {@link MenuItem} in the `Menu`. + * + * @param {Object|string} [item=0] + * Index of child item set focus on. + */ + + + Menu.prototype.focus = function focus() { + var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + + var children = this.children().slice(); + var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className); + + if (haveTitle) { + children.shift(); + } + + if (children.length > 0) { + if (item < 0) { + item = 0; + } else if (item >= children.length) { + item = children.length - 1; + } + + this.focusedChild_ = item; + + children[item].el_.focus(); + } + }; + + return Menu; +}(_component2['default']); + +_component2['default'].registerComponent('Menu', Menu); +exports['default'] = Menu; + +},{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file modal-dialog.js + */ + + +var MODAL_CLASS_NAME = 'vjs-modal-dialog'; +var ESC = 27; + +/** + * The `ModalDialog` displays over the video and its controls, which blocks + * interaction with the player until it is closed. + * + * Modal dialogs include a "Close" button and will close when that button + * is activated - or when ESC is pressed anywhere. + * + * @extends Component + */ + +var ModalDialog = function (_Component) { + _inherits(ModalDialog, _Component); + + /** + * Create an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Mixed} [options.content=undefined] + * Provide customized content for this modal. + * + * @param {string} [options.description] + * A text description for the modal, primarily for accessibility. + * + * @param {boolean} [options.fillAlways=false] + * Normally, modals are automatically filled only the first time + * they open. This tells the modal to refresh its content + * every time it opens. + * + * @param {string} [options.label] + * A text label for the modal, primarily for accessibility. + * + * @param {boolean} [options.temporary=true] + * If `true`, the modal can only be opened once; it will be + * disposed as soon as it's closed. + * + * @param {boolean} [options.uncloseable=false] + * If `true`, the user will not be able to close the modal + * through the UI in the normal ways. Programmatic closing is + * still possible. + */ + function ModalDialog(player, options) { + _classCallCheck(this, ModalDialog); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false; + + _this.closeable(!_this.options_.uncloseable); + _this.content(_this.options_.content); + + // Make sure the contentEl is defined AFTER any children are initialized + // because we only want the contents of the modal in the contentEl + // (not the UI elements like the close button). + _this.contentEl_ = Dom.createEl('div', { + className: MODAL_CLASS_NAME + '-content' + }, { + role: 'document' + }); + + _this.descEl_ = Dom.createEl('p', { + className: MODAL_CLASS_NAME + '-description vjs-offscreen', + id: _this.el().getAttribute('aria-describedby') + }); + + Dom.textContent(_this.descEl_, _this.description()); + _this.el_.appendChild(_this.descEl_); + _this.el_.appendChild(_this.contentEl_); + return _this; + } + + /** + * Create the `ModalDialog`'s DOM element + * + * @return {Element} + * The DOM element that gets created. + */ + + + ModalDialog.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: this.buildCSSClass(), + tabIndex: -1 + }, { + 'aria-describedby': this.id() + '_description', + 'aria-hidden': 'true', + 'aria-label': this.label(), + 'role': 'dialog' + }); + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + ModalDialog.prototype.buildCSSClass = function buildCSSClass() { + return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); + }; + + /** + * Handles `keydown` events on the document, looking for ESC, which closes + * the modal. + * + * @param {EventTarget~Event} e + * The keypress that triggered this event. + * + * @listens keydown + */ + + + ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { + if (e.which === ESC && this.closeable()) { + this.close(); + } + }; + + /** + * Returns the label string for this modal. Primarily used for accessibility. + * + * @return {string} + * the localized or raw label of this modal. + */ + + + ModalDialog.prototype.label = function label() { + return this.options_.label || this.localize('Modal Window'); + }; + + /** + * Returns the description string for this modal. Primarily used for + * accessibility. + * + * @return {string} + * The localized or raw description of this modal. + */ + + + ModalDialog.prototype.description = function description() { + var desc = this.options_.description || this.localize('This is a modal window.'); + + // Append a universal closeability message if the modal is closeable. + if (this.closeable()) { + desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); + } + + return desc; + }; + + /** + * Opens the modal. + * + * @fires ModalDialog#beforemodalopen + * @fires ModalDialog#modalopen + * + * @return {ModalDialog} + * Returns itself; method can be chained. + */ + + + ModalDialog.prototype.open = function open() { + if (!this.opened_) { + var player = this.player(); + + /** + * Fired just before a `ModalDialog` is opened. + * + * @event ModalDialog#beforemodalopen + * @type {EventTarget~Event} + */ + this.trigger('beforemodalopen'); + this.opened_ = true; + + // Fill content if the modal has never opened before and + // never been filled. + if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { + this.fill(); + } + + // If the player was playing, pause it and take note of its previously + // playing state. + this.wasPlaying_ = !player.paused(); + + if (this.wasPlaying_) { + player.pause(); + } + + if (this.closeable()) { + this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); + } + + player.controls(false); + this.show(); + this.el().setAttribute('aria-hidden', 'false'); + + /** + * Fired just after a `ModalDialog` is opened. + * + * @event ModalDialog#modalopen + * @type {EventTarget~Event} + */ + this.trigger('modalopen'); + this.hasBeenOpened_ = true; + } + return this; + }; + + /** + * If the `ModalDialog` is currently open or closed. + * + * @param {boolean} [value] + * If given, it will open (`true`) or close (`false`) the modal. + * + * @return {boolean} + * the current open state of the modaldialog + */ + + + ModalDialog.prototype.opened = function opened(value) { + if (typeof value === 'boolean') { + this[value ? 'open' : 'close'](); + } + return this.opened_; + }; + + /** + * Closes the modal, does nothing if the `ModalDialog` is + * not open. + * + * @fires ModalDialog#beforemodalclose + * @fires ModalDialog#modalclose + * + * @return {ModalDialog} + * Returns itself; method can be chained. + */ + + + ModalDialog.prototype.close = function close() { + if (this.opened_) { + var player = this.player(); + + /** + * Fired just before a `ModalDialog` is closed. + * + * @event ModalDialog#beforemodalclose + * @type {EventTarget~Event} + */ + this.trigger('beforemodalclose'); + this.opened_ = false; + + if (this.wasPlaying_) { + player.play(); + } + + if (this.closeable()) { + this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress)); + } + + player.controls(true); + this.hide(); + this.el().setAttribute('aria-hidden', 'true'); + + /** + * Fired just after a `ModalDialog` is closed. + * + * @event ModalDialog#modalclose + * @type {EventTarget~Event} + */ + this.trigger('modalclose'); + + if (this.options_.temporary) { + this.dispose(); + } + } + return this; + }; + + /** + * Check to see if the `ModalDialog` is closeable via the UI. + * + * @param {boolean} [value] + * If given as a boolean, it will set the `closeable` option. + * + * @return {boolean} + * Returns the final value of the closable option. + */ + + + ModalDialog.prototype.closeable = function closeable(value) { + if (typeof value === 'boolean') { + var closeable = this.closeable_ = !!value; + var close = this.getChild('closeButton'); + + // If this is being made closeable and has no close button, add one. + if (closeable && !close) { + + // The close button should be a child of the modal - not its + // content element, so temporarily change the content element. + var temp = this.contentEl_; + + this.contentEl_ = this.el_; + close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' }); + this.contentEl_ = temp; + this.on(close, 'close', this.close); + } + + // If this is being made uncloseable and has a close button, remove it. + if (!closeable && close) { + this.off(close, 'close', this.close); + this.removeChild(close); + close.dispose(); + } + } + return this.closeable_; + }; + + /** + * Fill the modal's content element with the modal's "content" option. + * The content element will be emptied before this change takes place. + * + * @return {ModalDialog} + * Returns itself; method can be chained. + */ + + + ModalDialog.prototype.fill = function fill() { + return this.fillWith(this.content()); + }; + + /** + * Fill the modal's content element with arbitrary content. + * The content element will be emptied before this change takes place. + * + * @fires ModalDialog#beforemodalfill + * @fires ModalDialog#modalfill + * + * @param {Mixed} [content] + * The same rules apply to this as apply to the `content` option. + * + * @return {ModalDialog} + * Returns itself; method can be chained. + */ + + + ModalDialog.prototype.fillWith = function fillWith(content) { + var contentEl = this.contentEl(); + var parentEl = contentEl.parentNode; + var nextSiblingEl = contentEl.nextSibling; + + /** + * Fired just before a `ModalDialog` is filled with content. + * + * @event ModalDialog#beforemodalfill + * @type {EventTarget~Event} + */ + this.trigger('beforemodalfill'); + this.hasBeenFilled_ = true; + + // Detach the content element from the DOM before performing + // manipulation to avoid modifying the live DOM multiple times. + parentEl.removeChild(contentEl); + this.empty(); + Dom.insertContent(contentEl, content); + /** + * Fired just after a `ModalDialog` is filled with content. + * + * @event ModalDialog#modalfill + * @type {EventTarget~Event} + */ + this.trigger('modalfill'); + + // Re-inject the re-filled content element. + if (nextSiblingEl) { + parentEl.insertBefore(contentEl, nextSiblingEl); + } else { + parentEl.appendChild(contentEl); + } + + return this; + }; + + /** + * Empties the content element. This happens anytime the modal is filled. + * + * @fires ModalDialog#beforemodalempty + * @fires ModalDialog#modalempty + * + * @return {ModalDialog} + * Returns itself; method can be chained. + */ + + + ModalDialog.prototype.empty = function empty() { + /** + * Fired just before a `ModalDialog` is emptied. + * + * @event ModalDialog#beforemodalempty + * @type {EventTarget~Event} + */ + this.trigger('beforemodalempty'); + Dom.emptyEl(this.contentEl()); + + /** + * Fired just after a `ModalDialog` is emptied. + * + * @event ModalDialog#modalempty + * @type {EventTarget~Event} + */ + this.trigger('modalempty'); + return this; + }; + + /** + * Gets or sets the modal content, which gets normalized before being + * rendered into the DOM. + * + * This does not update the DOM or fill the modal, but it is called during + * that process. + * + * @param {Mixed} [value] + * If defined, sets the internal content value to be used on the + * next call(s) to `fill`. This value is normalized before being + * inserted. To "clear" the internal content value, pass `null`. + * + * @return {Mixed} + * The current content of the modal dialog + */ + + + ModalDialog.prototype.content = function content(value) { + if (typeof value !== 'undefined') { + this.content_ = value; + } + return this.content_; + }; + + return ModalDialog; +}(_component2['default']); + +/** + * Default options for `ModalDialog` default options. + * + * @type {Object} + * @private + */ + + +ModalDialog.prototype.options_ = { + temporary: true +}; + +_component2['default'].registerComponent('ModalDialog', ModalDialog); +exports['default'] = ModalDialog; + +},{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _guid = _dereq_(85); + +var Guid = _interopRequireWildcard(_guid); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +var _timeRanges = _dereq_(90); + +var _buffer = _dereq_(79); + +var _stylesheet = _dereq_(89); + +var stylesheet = _interopRequireWildcard(_stylesheet); + +var _fullscreenApi = _dereq_(44); + +var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi); + +var _mediaError = _dereq_(46); + +var _mediaError2 = _interopRequireDefault(_mediaError); + +var _tuple = _dereq_(97); + +var _tuple2 = _interopRequireDefault(_tuple); + +var _obj = _dereq_(88); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _textTrackListConverter = _dereq_(69); + +var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter); + +var _modalDialog = _dereq_(50); + +var _modalDialog2 = _interopRequireDefault(_modalDialog); + +var _tech = _dereq_(62); + +var _tech2 = _interopRequireDefault(_tech); + +var _audioTrackList = _dereq_(63); + +var _audioTrackList2 = _interopRequireDefault(_audioTrackList); + +var _videoTrackList = _dereq_(76); + +var _videoTrackList2 = _interopRequireDefault(_videoTrackList); + +_dereq_(61); + +_dereq_(59); + +_dereq_(55); + +_dereq_(68); + +_dereq_(45); + +_dereq_(1); + +_dereq_(4); + +_dereq_(8); + +_dereq_(41); + +_dereq_(71); + +_dereq_(60); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file player.js + */ +// Subclasses Component + + +// The following imports are used only to ensure that the corresponding modules +// are always included in the video.js package. Importing the modules will +// execute them and they will register themselves with video.js. + + +// Import Html5 tech, at least for disposing the original video tag. + + +// The following tech events are simply re-triggered +// on the player when they happen +var TECH_EVENTS_RETRIGGER = [ +/** + * Fired while the user agent is downloading media data. + * + * @event Player#progress + * @type {EventTarget~Event} + */ +/** + * Retrigger the `progress` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechProgress_ + * @fires Player#progress + * @listens Tech#progress + */ +'progress', + +/** + * Fires when the loading of an audio/video is aborted. + * + * @event Player#abort + * @type {EventTarget~Event} + */ +/** + * Retrigger the `abort` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechAbort_ + * @fires Player#abort + * @listens Tech#abort + */ +'abort', + +/** + * Fires when the browser is intentionally not getting media data. + * + * @event Player#suspend + * @type {EventTarget~Event} + */ +/** + * Retrigger the `suspend` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechSuspend_ + * @fires Player#suspend + * @listens Tech#suspend + */ +'suspend', + +/** + * Fires when the current playlist is empty. + * + * @event Player#emptied + * @type {EventTarget~Event} + */ +/** + * Retrigger the `emptied` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechEmptied_ + * @fires Player#emptied + * @listens Tech#emptied + */ +'emptied', +/** + * Fires when the browser is trying to get media data, but data is not available. + * + * @event Player#stalled + * @type {EventTarget~Event} + */ +/** + * Retrigger the `stalled` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechStalled_ + * @fires Player#stalled + * @listens Tech#stalled + */ +'stalled', + +/** + * Fires when the browser has loaded meta data for the audio/video. + * + * @event Player#loadedmetadata + * @type {EventTarget~Event} + */ +/** + * Retrigger the `stalled` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechLoadedmetadata_ + * @fires Player#loadedmetadata + * @listens Tech#loadedmetadata + */ +'loadedmetadata', + +/** + * Fires when the browser has loaded the current frame of the audio/video. + * + * @event player#loadeddata + * @type {event} + */ +/** + * Retrigger the `loadeddata` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechLoaddeddata_ + * @fires Player#loadeddata + * @listens Tech#loadeddata + */ +'loadeddata', + +/** + * Fires when the current playback position has changed. + * + * @event player#timeupdate + * @type {event} + */ +/** + * Retrigger the `timeupdate` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechTimeUpdate_ + * @fires Player#timeupdate + * @listens Tech#timeupdate + */ +'timeupdate', + +/** + * Fires when the playing speed of the audio/video is changed + * + * @event player#ratechange + * @type {event} + */ +/** + * Retrigger the `ratechange` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechRatechange_ + * @fires Player#ratechange + * @listens Tech#ratechange + */ +'ratechange', + +/** + * Fires when the volume has been changed + * + * @event player#volumechange + * @type {event} + */ +/** + * Retrigger the `volumechange` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechVolumechange_ + * @fires Player#volumechange + * @listens Tech#volumechange + */ +'volumechange', + +/** + * Fires when the text track has been changed + * + * @event player#texttrackchange + * @type {event} + */ +/** + * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}. + * + * @private + * @method Player#handleTechTexttrackchange_ + * @fires Player#texttrackchange + * @listens Tech#texttrackchange + */ +'texttrackchange']; + +/** + * An instance of the `Player` class is created when any of the Video.js setup methods + * are used to initialize a video. + * + * After an instance has been created it can be accessed globally in two ways: + * 1. By calling `videojs('example_video_1');` + * 2. By using it directly via `videojs.players.example_video_1;` + * + * @extends Component + */ + +var Player = function (_Component) { + _inherits(Player, _Component); + + /** + * Create an instance of this class. + * + * @param {Element} tag + * The original video DOM element used for configuring options. + * + * @param {Object} [options] + * Object of option names and values. + * + * @param {Component~ReadyCallback} [ready] + * Ready callback function. + */ + function Player(tag, options, ready) { + _classCallCheck(this, Player); + + // Make sure tag ID exists + tag.id = tag.id || 'vjs_video_' + Guid.newGUID(); + + // Set Options + // The options argument overrides options set in the video tag + // which overrides globally set options. + // This latter part coincides with the load order + // (tag must exist before Player) + options = (0, _obj.assign)(Player.getTagSettings(tag), options); + + // Delay the initialization of children because we need to set up + // player properties first, and can't use `this` before `super()` + options.initChildren = false; + + // Same with creating the element + options.createEl = false; + + // we don't want the player to report touch activity on itself + // see enableTouchActivity in Component + options.reportTouchActivity = false; + + // If language is not set, get the closest lang attribute + if (!options.language) { + if (typeof tag.closest === 'function') { + var closest = tag.closest('[lang]'); + + if (closest) { + options.language = closest.getAttribute('lang'); + } + } else { + var element = tag; + + while (element && element.nodeType === 1) { + if (Dom.getElAttributes(element).hasOwnProperty('lang')) { + options.language = element.getAttribute('lang'); + break; + } + element = element.parentNode; + } + } + } + + // Run base component initializing with new options + + // if the global option object was accidentally blown away by + // someone, bail early with an informative error + var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); + + if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) { + throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?'); + } + + // Store the original tag used to set options + _this.tag = tag; + + // Store the tag attributes used to restore html5 element + _this.tagAttributes = tag && Dom.getElAttributes(tag); + + // Update current language + _this.language(_this.options_.language); + + // Update Supported Languages + if (options.languages) { + (function () { + // Normalise player option languages to lowercase + var languagesToLower = {}; + + Object.getOwnPropertyNames(options.languages).forEach(function (name) { + languagesToLower[name.toLowerCase()] = options.languages[name]; + }); + _this.languages_ = languagesToLower; + })(); + } else { + _this.languages_ = Player.prototype.options_.languages; + } + + // Cache for video property values. + _this.cache_ = {}; + + // Set poster + _this.poster_ = options.poster || ''; + + // Set controls + _this.controls_ = !!options.controls; + + // Original tag settings stored in options + // now remove immediately so native controls don't flash. + // May be turned back on by HTML5 tech if nativeControlsForTouch is true + tag.controls = false; + + /* + * Store the internal state of scrubbing + * + * @private + * @return {Boolean} True if the user is scrubbing + */ + _this.scrubbing_ = false; + + _this.el_ = _this.createEl(); + + // We also want to pass the original player options to each component and plugin + // as well so they don't need to reach back into the player for options later. + // We also need to do another copy of this.options_ so we don't end up with + // an infinite loop. + var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_); + + // Load plugins + if (options.plugins) { + (function () { + var plugins = options.plugins; + + Object.getOwnPropertyNames(plugins).forEach(function (name) { + if (typeof this[name] === 'function') { + this[name](plugins[name]); + } else { + _log2['default'].error('Unable to find plugin:', name); + } + }, _this); + })(); + } + + _this.options_.playerOptions = playerOptionsCopy; + + _this.initChildren(); + + // Set isAudio based on whether or not an audio tag was used + _this.isAudio(tag.nodeName.toLowerCase() === 'audio'); + + // Update controls className. Can't do this when the controls are initially + // set because the element doesn't exist yet. + if (_this.controls()) { + _this.addClass('vjs-controls-enabled'); + } else { + _this.addClass('vjs-controls-disabled'); + } + + // Set ARIA label and region role depending on player type + _this.el_.setAttribute('role', 'region'); + if (_this.isAudio()) { + _this.el_.setAttribute('aria-label', 'audio player'); + } else { + _this.el_.setAttribute('aria-label', 'video player'); + } + + if (_this.isAudio()) { + _this.addClass('vjs-audio'); + } + + if (_this.flexNotSupported_()) { + _this.addClass('vjs-no-flex'); + } + + // TODO: Make this smarter. Toggle user state between touching/mousing + // using events, since devices can have both touch and mouse events. + // if (browser.TOUCH_ENABLED) { + // this.addClass('vjs-touch-enabled'); + // } + + // iOS Safari has broken hover handling + if (!browser.IS_IOS) { + _this.addClass('vjs-workinghover'); + } + + // Make player easily findable by ID + Player.players[_this.id_] = _this; + + // When the player is first initialized, trigger activity so components + // like the control bar show themselves if needed + _this.userActive(true); + _this.reportUserActivity(); + _this.listenForUserActivity_(); + + _this.on('fullscreenchange', _this.handleFullscreenChange_); + _this.on('stageclick', _this.handleStageClick_); + return _this; + } + + /** + * Destroys the video player and does any necessary cleanup. + * + * This is especially helpful if you are dynamically adding and removing videos + * to/from the DOM. + * + * @fires Player#dispose + */ + + + Player.prototype.dispose = function dispose() { + /** + * Called when the player is being disposed of. + * + * @event Player#dispose + * @type {EventTarget~Event} + */ + this.trigger('dispose'); + // prevent dispose from being called twice + this.off('dispose'); + + if (this.styleEl_ && this.styleEl_.parentNode) { + this.styleEl_.parentNode.removeChild(this.styleEl_); + } + + // Kill reference to this player + Player.players[this.id_] = null; + + if (this.tag && this.tag.player) { + this.tag.player = null; + } + + if (this.el_ && this.el_.player) { + this.el_.player = null; + } + + if (this.tech_) { + this.tech_.dispose(); + } + + _Component.prototype.dispose.call(this); + }; + + /** + * Create the `Player`'s DOM element. + * + * @return {Element} + * The DOM element that gets created. + */ + + + Player.prototype.createEl = function createEl() { + var tag = this.tag; + var el = void 0; + var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute('data-vjs-player'); + + if (playerElIngest) { + el = this.el_ = tag.parentNode; + } else { + el = this.el_ = _Component.prototype.createEl.call(this, 'div'); + } + + // Remove width/height attrs from tag so CSS can make it 100% width/height + tag.removeAttribute('width'); + tag.removeAttribute('height'); + + // Copy over all the attributes from the tag, including ID and class + // ID will now reference player box, not the video tag + var attrs = Dom.getElAttributes(tag); + + Object.getOwnPropertyNames(attrs).forEach(function (attr) { + // workaround so we don't totally break IE7 + // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7 + if (attr === 'class') { + el.className += ' ' + attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + }); + + // Update tag id/class for use as HTML5 playback tech + // Might think we should do this after embedding in container so .vjs-tech class + // doesn't flash 100% width/height, but class only applies with .video-js parent + tag.playerId = tag.id; + tag.id += '_html5_api'; + tag.className = 'vjs-tech'; + + // Make player findable on elements + tag.player = el.player = this; + // Default state of video is paused + this.addClass('vjs-paused'); + + // Add a style element in the player that we'll use to set the width/height + // of the player in a way that's still overrideable by CSS, just like the + // video element + if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) { + this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions'); + var defaultsStyleEl = Dom.$('.vjs-styles-defaults'); + var head = Dom.$('head'); + + head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild); + } + + // Pass in the width/height/aspectRatio options which will update the style el + this.width(this.options_.width); + this.height(this.options_.height); + this.fluid(this.options_.fluid); + this.aspectRatio(this.options_.aspectRatio); + + // Hide any links within the video/audio tag, because IE doesn't hide them completely. + var links = tag.getElementsByTagName('a'); + + for (var i = 0; i < links.length; i++) { + var linkEl = links.item(i); + + Dom.addElClass(linkEl, 'vjs-hidden'); + linkEl.setAttribute('hidden', 'hidden'); + } + + // insertElFirst seems to cause the networkState to flicker from 3 to 2, so + // keep track of the original for later so we can know if the source originally failed + tag.initNetworkState_ = tag.networkState; + + // Wrap video tag in div (el/box) container + if (tag.parentNode && !playerElIngest) { + tag.parentNode.insertBefore(el, tag); + } + + // insert the tag as the first child of the player element + // then manually add it to the children array so that this.addChild + // will work properly for other components + // + // Breaks iPhone, fixed in HTML5 setup. + Dom.insertElFirst(tag, el); + this.children_.unshift(tag); + + this.el_ = el; + + return el; + }; + + /** + * A getter/setter for the `Player`'s width. + * + * @param {number} [value] + * The value to set the `Player's width to. + * + * @return {number} + * The current width of the `Player`. + */ + + + Player.prototype.width = function width(value) { + return this.dimension('width', value); + }; + + /** + * A getter/setter for the `Player`'s height. + * + * @param {number} [value] + * The value to set the `Player's heigth to. + * + * @return {number} + * The current heigth of the `Player`. + */ + + + Player.prototype.height = function height(value) { + return this.dimension('height', value); + }; + + /** + * A getter/setter for the `Player`'s width & height. + * + * @param {string} dimension + * This string can be: + * - 'width' + * - 'height' + * + * @param {number} [value] + * Value for dimension specified in the first argument. + * + * @return {Player|number} + * - Returns itself when setting; method can be chained. + * - The dimension arguments value when getting (width/height). + */ + + + Player.prototype.dimension = function dimension(_dimension, value) { + var privDimension = _dimension + '_'; + + if (value === undefined) { + return this[privDimension] || 0; + } + + if (value === '') { + // If an empty string is given, reset the dimension to be automatic + this[privDimension] = undefined; + } else { + var parsedVal = parseFloat(value); + + if (isNaN(parsedVal)) { + _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension); + return this; + } + + this[privDimension] = parsedVal; + } + + this.updateStyleEl_(); + return this; + }; + + /** + * A getter/setter/toggler for the vjs-fluid `className` on the `Player`. + * + * @param {boolean} [bool] + * - A value of true adds the class. + * - A value of false removes the class. + * - No value will toggle the fluid class. + * + * @return {boolean|undefined} + * - The value of fluid when getting. + * - `undefined` when setting. + */ + + + Player.prototype.fluid = function fluid(bool) { + if (bool === undefined) { + return !!this.fluid_; + } + + this.fluid_ = !!bool; + + if (bool) { + this.addClass('vjs-fluid'); + } else { + this.removeClass('vjs-fluid'); + } + + this.updateStyleEl_(); + }; + + /** + * Get/Set the aspect ratio + * + * @param {string} [ratio] + * Aspect ratio for player + * + * @return {string|undefined} + * returns the current aspect ratio when getting + */ + + /** + * A getter/setter for the `Player`'s aspect ratio. + * + * @param {string} [ratio] + * The value to set the `Player's aspect ratio to. + * + * @return {string|undefined} + * - The current aspect ratio of the `Player` when getting. + * - undefined when setting + */ + + + Player.prototype.aspectRatio = function aspectRatio(ratio) { + if (ratio === undefined) { + return this.aspectRatio_; + } + + // Check for width:height format + if (!/^\d+\:\d+$/.test(ratio)) { + throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); + } + this.aspectRatio_ = ratio; + + // We're assuming if you set an aspect ratio you want fluid mode, + // because in fixed mode you could calculate width and height yourself. + this.fluid(true); + + this.updateStyleEl_(); + }; + + /** + * Update styles of the `Player` element (height, width and aspect ratio). + * + * @private + * @listens Tech#loadedmetadata + */ + + + Player.prototype.updateStyleEl_ = function updateStyleEl_() { + if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) { + var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width; + var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height; + var techEl = this.tech_ && this.tech_.el(); + + if (techEl) { + if (_width >= 0) { + techEl.width = _width; + } + if (_height >= 0) { + techEl.height = _height; + } + } + + return; + } + + var width = void 0; + var height = void 0; + var aspectRatio = void 0; + var idClass = void 0; + + // The aspect ratio is either used directly or to calculate width and height. + if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') { + // Use any aspectRatio that's been specifically set + aspectRatio = this.aspectRatio_; + } else if (this.videoWidth() > 0) { + // Otherwise try to get the aspect ratio from the video metadata + aspectRatio = this.videoWidth() + ':' + this.videoHeight(); + } else { + // Or use a default. The video element's is 2:1, but 16:9 is more common. + aspectRatio = '16:9'; + } + + // Get the ratio as a decimal we can use to calculate dimensions + var ratioParts = aspectRatio.split(':'); + var ratioMultiplier = ratioParts[1] / ratioParts[0]; + + if (this.width_ !== undefined) { + // Use any width that's been specifically set + width = this.width_; + } else if (this.height_ !== undefined) { + // Or calulate the width from the aspect ratio if a height has been set + width = this.height_ / ratioMultiplier; + } else { + // Or use the video's metadata, or use the video el's default of 300 + width = this.videoWidth() || 300; + } + + if (this.height_ !== undefined) { + // Use any height that's been specifically set + height = this.height_; + } else { + // Otherwise calculate the height from the ratio and the width + height = width * ratioMultiplier; + } + + // Ensure the CSS class is valid by starting with an alpha character + if (/^[^a-zA-Z]/.test(this.id())) { + idClass = 'dimensions-' + this.id(); + } else { + idClass = this.id() + '-dimensions'; + } + + // Ensure the right class is still on the player for the style element + this.addClass(idClass); + + stylesheet.setTextContent(this.styleEl_, '\n .' + idClass + ' {\n width: ' + width + 'px;\n height: ' + height + 'px;\n }\n\n .' + idClass + '.vjs-fluid {\n padding-top: ' + ratioMultiplier * 100 + '%;\n }\n '); + }; + + /** + * Load/Create an instance of playback {@link Tech} including element + * and API methods. Then append the `Tech` element in `Player` as a child. + * + * @param {string} techName + * name of the playback technology + * + * @param {string} source + * video source + * + * @private + */ + + + Player.prototype.loadTech_ = function loadTech_(techName, source) { + var _this2 = this; + + // Pause and remove current playback technology + if (this.tech_) { + this.unloadTech_(); + } + + // get rid of the HTML5 video tag as soon as we are using another tech + if (techName !== 'Html5' && this.tag) { + _tech2['default'].getTech('Html5').disposeMediaElement(this.tag); + this.tag.player = null; + this.tag = null; + } + + this.techName_ = techName; + + // Turn off API access because we're loading a new tech that might load asynchronously + this.isReady_ = false; + + // Grab tech-specific options from player options and add source and parent element to use. + var techOptions = (0, _obj.assign)({ + source: source, + 'nativeControlsForTouch': this.options_.nativeControlsForTouch, + 'playerId': this.id(), + 'techId': this.id() + '_' + techName + '_api', + 'videoTracks': this.videoTracks_, + 'textTracks': this.textTracks_, + 'audioTracks': this.audioTracks_, + 'autoplay': this.options_.autoplay, + 'preload': this.options_.preload, + 'loop': this.options_.loop, + 'muted': this.options_.muted, + 'poster': this.poster(), + 'language': this.language(), + 'playerElIngest': this.playerElIngest_ || false, + 'vtt.js': this.options_['vtt.js'] + }, this.options_[techName.toLowerCase()]); + + if (this.tag) { + techOptions.tag = this.tag; + } + + if (source) { + this.currentType_ = source.type; + + if (source.src === this.cache_.src && this.cache_.currentTime > 0) { + techOptions.startTime = this.cache_.currentTime; + } + + this.cache_.sources = null; + this.cache_.source = source; + this.cache_.src = source.src; + } + + // Initialize tech instance + var TechComponent = _tech2['default'].getTech(techName); + + // Support old behavior of techs being registered as components. + // Remove once that deprecated behavior is removed. + if (!TechComponent) { + TechComponent = _component2['default'].getComponent(techName); + } + this.tech_ = new TechComponent(techOptions); + + // player.triggerReady is always async, so don't need this to be async + this.tech_.ready(Fn.bind(this, this.handleTechReady_), true); + + _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_); + + // Listen to all HTML5-defined events and trigger them on the player + TECH_EVENTS_RETRIGGER.forEach(function (event) { + _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']); + }); + this.on(this.tech_, 'loadstart', this.handleTechLoadStart_); + this.on(this.tech_, 'waiting', this.handleTechWaiting_); + this.on(this.tech_, 'canplay', this.handleTechCanPlay_); + this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_); + this.on(this.tech_, 'playing', this.handleTechPlaying_); + this.on(this.tech_, 'ended', this.handleTechEnded_); + this.on(this.tech_, 'seeking', this.handleTechSeeking_); + this.on(this.tech_, 'seeked', this.handleTechSeeked_); + this.on(this.tech_, 'play', this.handleTechPlay_); + this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_); + this.on(this.tech_, 'pause', this.handleTechPause_); + this.on(this.tech_, 'durationchange', this.handleTechDurationChange_); + this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_); + this.on(this.tech_, 'error', this.handleTechError_); + this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_); + this.on(this.tech_, 'posterchange', this.handleTechPosterChange_); + this.on(this.tech_, 'textdata', this.handleTechTextData_); + + this.usingNativeControls(this.techGet_('controls')); + + if (this.controls() && !this.usingNativeControls()) { + this.addTechControlsListeners_(); + } + + // Add the tech element in the DOM if it was not already there + // Make sure to not insert the original video element if using Html5 + if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) { + Dom.insertElFirst(this.tech_.el(), this.el()); + } + + // Get rid of the original video tag reference after the first tech is loaded + if (this.tag) { + this.tag.player = null; + this.tag = null; + } + }; + + /** + * Unload and dispose of the current playback {@link Tech}. + * + * @private + */ + + + Player.prototype.unloadTech_ = function unloadTech_() { + // Save the current text tracks so that we can reuse the same text tracks with the next tech + this.videoTracks_ = this.videoTracks(); + this.textTracks_ = this.textTracks(); + this.audioTracks_ = this.audioTracks(); + this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_); + + this.isReady_ = false; + + this.tech_.dispose(); + + this.tech_ = false; + }; + + /** + * Return a reference to the current {@link Tech}, but only if given an object with the + * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse + * of techs by plugins. + * + * @param {Object} safety + * An object that must contain `{IWillNotUseThisInPlugins: true}` + * + * @param {boolean} safety.IWillNotUseThisInPlugins + * Must be set to true or else this function will throw an error. + * + * @return {Tech} + * The Tech + */ + + + Player.prototype.tech = function tech(safety) { + if (safety && safety.IWillNotUseThisInPlugins) { + return this.tech_; + } + var errorText = '\n Please make sure that you are not using this inside of a plugin.\n To disable this alert and error, please pass in an object with\n `IWillNotUseThisInPlugins` to the `tech` method. See\n https://github.com/videojs/video.js/issues/2617 for more info.\n '; + + _window2['default'].alert(errorText); + throw new Error(errorText); + }; + + /** + * Set up click and touch listeners for the playback element + * + * - On desktops: a click on the video itself will toggle playback + * - On mobile devices: a click on the video toggles controls + * which is done by toggling the user state between active and + * inactive + * - A tap can signal that a user has become active or has become inactive + * e.g. a quick tap on an iPhone movie should reveal the controls. Another + * quick tap should hide them again (signaling the user is in an inactive + * viewing state) + * - In addition to this, we still want the user to be considered inactive after + * a few seconds of inactivity. + * + * > Note: the only part of iOS interaction we can't mimic with this setup + * is a touch and hold on the video element counting as activity in order to + * keep the controls showing, but that shouldn't be an issue. A touch and hold + * on any controls will still keep the user active + * + * @private + */ + + + Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() { + // Make sure to remove all the previous listeners in case we are called multiple times. + this.removeTechControlsListeners_(); + + // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do + // trigger mousedown/up. + // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object + // Any touch events are set to block the mousedown event from happening + this.on(this.tech_, 'mousedown', this.handleTechClick_); + + // If the controls were hidden we don't want that to change without a tap event + // so we'll check if the controls were already showing before reporting user + // activity + this.on(this.tech_, 'touchstart', this.handleTechTouchStart_); + this.on(this.tech_, 'touchmove', this.handleTechTouchMove_); + this.on(this.tech_, 'touchend', this.handleTechTouchEnd_); + + // The tap listener needs to come after the touchend listener because the tap + // listener cancels out any reportedUserActivity when setting userActive(false) + this.on(this.tech_, 'tap', this.handleTechTap_); + }; + + /** + * Remove the listeners used for click and tap controls. This is needed for + * toggling to controls disabled, where a tap/touch should do nothing. + * + * @private + */ + + + Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() { + // We don't want to just use `this.off()` because there might be other needed + // listeners added by techs that extend this. + this.off(this.tech_, 'tap', this.handleTechTap_); + this.off(this.tech_, 'touchstart', this.handleTechTouchStart_); + this.off(this.tech_, 'touchmove', this.handleTechTouchMove_); + this.off(this.tech_, 'touchend', this.handleTechTouchEnd_); + this.off(this.tech_, 'mousedown', this.handleTechClick_); + }; + + /** + * Player waits for the tech to be ready + * + * @private + */ + + + Player.prototype.handleTechReady_ = function handleTechReady_() { + this.triggerReady(); + + // Keep the same volume as before + if (this.cache_.volume) { + this.techCall_('setVolume', this.cache_.volume); + } + + // Look if the tech found a higher resolution poster while loading + this.handleTechPosterChange_(); + + // Update the duration if available + this.handleTechDurationChange_(); + + // Chrome and Safari both have issues with autoplay. + // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. + // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) + // This fixes both issues. Need to wait for API, so it updates displays correctly + if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) { + try { + // Chrome Fix. Fixed in Chrome v16. + delete this.tag.poster; + } catch (e) { + (0, _log2['default'])('deleting tag.poster throws in some browsers', e); + } + this.play(); + } + }; + + /** + * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This + * function will also trigger {@link Player#firstplay} if it is the first loadstart + * for a video. + * + * @fires Player#loadstart + * @fires Player#firstplay + * @listens Tech#loadstart + * @private + */ + + + Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() { + // TODO: Update to use `emptied` event instead. See #1277. + + this.removeClass('vjs-ended'); + this.removeClass('vjs-seeking'); + + // reset the error state + this.error(null); + + // If it's already playing we want to trigger a firstplay event now. + // The firstplay event relies on both the play and loadstart events + // which can happen in any order for a new source + if (!this.paused()) { + /** + * Fired when the user agent begins looking for media data + * + * @event Player#loadstart + * @type {EventTarget~Event} + */ + this.trigger('loadstart'); + this.trigger('firstplay'); + } else { + // reset the hasStarted state + this.hasStarted(false); + this.trigger('loadstart'); + } + }; + + /** + * Add/remove the vjs-has-started class + * + * @fires Player#firstplay + * + * @param {boolean} hasStarted + * - true: adds the class + * - false: remove the class + * + * @return {boolean} + * the boolean value of hasStarted + */ + + + Player.prototype.hasStarted = function hasStarted(_hasStarted) { + if (_hasStarted !== undefined) { + // only update if this is a new value + if (this.hasStarted_ !== _hasStarted) { + this.hasStarted_ = _hasStarted; + if (_hasStarted) { + this.addClass('vjs-has-started'); + // trigger the firstplay event if this newly has played + this.trigger('firstplay'); + } else { + this.removeClass('vjs-has-started'); + } + } + return this; + } + return !!this.hasStarted_; + }; + + /** + * Fired whenever the media begins or resumes playback + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play} + * @fires Player#play + * @listens Tech#play + * @private + */ + + + Player.prototype.handleTechPlay_ = function handleTechPlay_() { + this.removeClass('vjs-ended'); + this.removeClass('vjs-paused'); + this.addClass('vjs-playing'); + + // hide the poster when the user hits play + this.hasStarted(true); + /** + * Triggered whenever an {@link Tech#play} event happens. Indicates that + * playback has started or resumed. + * + * @event Player#play + * @type {EventTarget~Event} + */ + this.trigger('play'); + }; + + /** + * Retrigger the `waiting` event that was triggered by the {@link Tech}. + * + * @fires Player#waiting + * @listens Tech#waiting + * @private + */ + + + Player.prototype.handleTechWaiting_ = function handleTechWaiting_() { + var _this3 = this; + + this.addClass('vjs-waiting'); + /** + * A readyState change on the DOM element has caused playback to stop. + * + * @event Player#waiting + * @type {EventTarget~Event} + */ + this.trigger('waiting'); + this.one('timeupdate', function () { + return _this3.removeClass('vjs-waiting'); + }); + }; + + /** + * Retrigger the `canplay` event that was triggered by the {@link Tech}. + * > Note: This is not consistent between browsers. See #1351 + * + * @fires Player#canplay + * @listens Tech#canplay + * @private + */ + + + Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() { + this.removeClass('vjs-waiting'); + /** + * The media has a readyState of HAVE_FUTURE_DATA or greater. + * + * @event Player#canplay + * @type {EventTarget~Event} + */ + this.trigger('canplay'); + }; + + /** + * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}. + * + * @fires Player#canplaythrough + * @listens Tech#canplaythrough + * @private + */ + + + Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() { + this.removeClass('vjs-waiting'); + /** + * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the + * entire media file can be played without buffering. + * + * @event Player#canplaythrough + * @type {EventTarget~Event} + */ + this.trigger('canplaythrough'); + }; + + /** + * Retrigger the `playing` event that was triggered by the {@link Tech}. + * + * @fires Player#playing + * @listens Tech#playing + * @private + */ + + + Player.prototype.handleTechPlaying_ = function handleTechPlaying_() { + this.removeClass('vjs-waiting'); + /** + * The media is no longer blocked from playback, and has started playing. + * + * @event Player#playing + * @type {EventTarget~Event} + */ + this.trigger('playing'); + }; + + /** + * Retrigger the `seeking` event that was triggered by the {@link Tech}. + * + * @fires Player#seeking + * @listens Tech#seeking + * @private + */ + + + Player.prototype.handleTechSeeking_ = function handleTechSeeking_() { + this.addClass('vjs-seeking'); + /** + * Fired whenever the player is jumping to a new time + * + * @event Player#seeking + * @type {EventTarget~Event} + */ + this.trigger('seeking'); + }; + + /** + * Retrigger the `seeked` event that was triggered by the {@link Tech}. + * + * @fires Player#seeked + * @listens Tech#seeked + * @private + */ + + + Player.prototype.handleTechSeeked_ = function handleTechSeeked_() { + this.removeClass('vjs-seeking'); + /** + * Fired when the player has finished jumping to a new time + * + * @event Player#seeked + * @type {EventTarget~Event} + */ + this.trigger('seeked'); + }; + + /** + * Retrigger the `firstplay` event that was triggered by the {@link Tech}. + * + * @fires Player#firstplay + * @listens Tech#firstplay + * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated + * @private + */ + + + Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() { + // If the first starttime attribute is specified + // then we will start at the given offset in seconds + if (this.options_.starttime) { + _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0'); + this.currentTime(this.options_.starttime); + } + + this.addClass('vjs-has-started'); + /** + * Fired the first time a video is played. Not part of the HLS spec, and this is + * probably not the best implementation yet, so use sparingly. If you don't have a + * reason to prevent playback, use `myPlayer.one('play');` instead. + * + * @event Player#firstplay + * @type {EventTarget~Event} + */ + this.trigger('firstplay'); + }; + + /** + * Retrigger the `pause` event that was triggered by the {@link Tech}. + * + * @fires Player#pause + * @listens Tech#pause + * @private + */ + + + Player.prototype.handleTechPause_ = function handleTechPause_() { + this.removeClass('vjs-playing'); + this.addClass('vjs-paused'); + /** + * Fired whenever the media has been paused + * + * @event Player#pause + * @type {EventTarget~Event} + */ + this.trigger('pause'); + }; + + /** + * Retrigger the `ended` event that was triggered by the {@link Tech}. + * + * @fires Player#ended + * @listens Tech#ended + * @private + */ + + + Player.prototype.handleTechEnded_ = function handleTechEnded_() { + this.addClass('vjs-ended'); + if (this.options_.loop) { + this.currentTime(0); + this.play(); + } else if (!this.paused()) { + this.pause(); + } + + /** + * Fired when the end of the media resource is reached (currentTime == duration) + * + * @event Player#ended + * @type {EventTarget~Event} + */ + this.trigger('ended'); + }; + + /** + * Fired when the duration of the media resource is first known or changed + * + * @listens Tech#durationchange + * @private + */ + + + Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() { + this.duration(this.techGet_('duration')); + }; + + /** + * Handle a click on the media element to play/pause + * + * @param {EventTarget~Event} event + * the event that caused this function to trigger + * + * @listens Tech#mousedown + * @private + */ + + + Player.prototype.handleTechClick_ = function handleTechClick_(event) { + // We're using mousedown to detect clicks thanks to Flash, but mousedown + // will also be triggered with right-clicks, so we need to prevent that + if (event.button !== 0) { + return; + } + + // When controls are disabled a click should not toggle playback because + // the click is considered a control + if (this.controls()) { + if (this.paused()) { + this.play(); + } else { + this.pause(); + } + } + }; + + /** + * Handle a tap on the media element. It will toggle the user + * activity state, which hides and shows the controls. + * + * @listens Tech#tap + * @private + */ + + + Player.prototype.handleTechTap_ = function handleTechTap_() { + this.userActive(!this.userActive()); + }; + + /** + * Handle touch to start + * + * @listens Tech#touchstart + * @private + */ + + + Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() { + this.userWasActive = this.userActive(); + }; + + /** + * Handle touch to move + * + * @listens Tech#touchmove + * @private + */ + + + Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() { + if (this.userWasActive) { + this.reportUserActivity(); + } + }; + + /** + * Handle touch to end + * + * @param {EventTarget~Event} event + * the touchend event that triggered + * this function + * + * @listens Tech#touchend + * @private + */ + + + Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) { + // Stop the mouse events from also happening + event.preventDefault(); + }; + + /** + * Fired when the player switches in or out of fullscreen mode + * + * @private + * @listens Player#fullscreenchange + */ + + + Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() { + if (this.isFullscreen()) { + this.addClass('vjs-fullscreen'); + } else { + this.removeClass('vjs-fullscreen'); + } + }; + + /** + * native click events on the SWF aren't triggered on IE11, Win8.1RT + * use stageclick events triggered from inside the SWF instead + * + * @private + * @listens stageclick + */ + + + Player.prototype.handleStageClick_ = function handleStageClick_() { + this.reportUserActivity(); + }; + + /** + * Handle Tech Fullscreen Change + * + * @param {EventTarget~Event} event + * the fullscreenchange event that triggered this function + * + * @param {Object} data + * the data that was sent with the event + * + * @private + * @listens Tech#fullscreenchange + * @fires Player#fullscreenchange + */ + + + Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) { + if (data) { + this.isFullscreen(data.isFullscreen); + } + /** + * Fired when going in and out of fullscreen. + * + * @event Player#fullscreenchange + * @type {EventTarget~Event} + */ + this.trigger('fullscreenchange'); + }; + + /** + * Fires when an error occurred during the loading of an audio/video. + * + * @private + * @listens Tech#error + */ + + + Player.prototype.handleTechError_ = function handleTechError_() { + var error = this.tech_.error(); + + this.error(error); + }; + + /** + * Retrigger the `textdata` event that was triggered by the {@link Tech}. + * + * @fires Player#textdata + * @listens Tech#textdata + * @private + */ + + + Player.prototype.handleTechTextData_ = function handleTechTextData_() { + var data = null; + + if (arguments.length > 1) { + data = arguments[1]; + } + + /** + * Fires when we get a textdata event from tech + * + * @event Player#textdata + * @type {EventTarget~Event} + */ + this.trigger('textdata', data); + }; + + /** + * Get object for cached values. + * + * @return {Object} + * get the current object cache + */ + + + Player.prototype.getCache = function getCache() { + return this.cache_; + }; + + /** + * Pass values to the playback tech + * + * @param {string} [method] + * the method to call + * + * @param {Object} arg + * the argument to pass + * + * @private + */ + + + Player.prototype.techCall_ = function techCall_(method, arg) { + // If it's not ready yet, call method when it is + if (this.tech_ && !this.tech_.isReady_) { + this.tech_.ready(function () { + this[method](arg); + }, true); + + // Otherwise call method now + } else { + try { + if (this.tech_) { + this.tech_[method](arg); + } + } catch (e) { + (0, _log2['default'])(e); + throw e; + } + } + }; + + /** + * Get calls can't wait for the tech, and sometimes don't need to. + * + * @param {string} method + * Tech method + * + * @return {Function|undefined} + * the method or undefined + * + * @private + */ + + + Player.prototype.techGet_ = function techGet_(method) { + if (this.tech_ && this.tech_.isReady_) { + + // Flash likes to die and reload when you hide or reposition it. + // In these cases the object methods go away and we get errors. + // When that happens we'll catch the errors and inform tech that it's not ready any more. + try { + return this.tech_[method](); + } catch (e) { + // When building additional tech libs, an expected method may not be defined yet + if (this.tech_[method] === undefined) { + (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e); + + // When a method isn't available on the object it throws a TypeError + } else if (e.name === 'TypeError') { + (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e); + this.tech_.isReady_ = false; + } else { + (0, _log2['default'])(e); + } + throw e; + } + } + + return; + }; + + /** + * start media playback + * + * @return {Player} + * A reference to the player object this function was called on + */ + + + Player.prototype.play = function play() { + // Only calls the tech's play if we already have a src loaded + if (this.src() || this.currentSrc()) { + this.techCall_('play'); + } else { + this.tech_.one('loadstart', function () { + this.play(); + }); + } + + return this; + }; + + /** + * Pause the video playback + * + * @return {Player} + * A reference to the player object this function was called on + */ + + + Player.prototype.pause = function pause() { + this.techCall_('pause'); + return this; + }; + + /** + * Check if the player is paused or has yet to play + * + * @return {boolean} + * - false: if the media is currently playing + * - true: if media is not currently playing + */ + + + Player.prototype.paused = function paused() { + // The initial state of paused should be true (in Safari it's actually false) + return this.techGet_('paused') === false ? false : true; + }; + + /** + * Returns whether or not the user is "scrubbing". Scrubbing is + * when the user has clicked the progress bar handle and is + * dragging it along the progress bar. + * + * @param {boolean} [isScrubbing] + * wether the user is or is not scrubbing + * + * @return {boolean|Player} + * A instance of the player that called this function when setting, + * and the value of scrubbing when getting + */ + + + Player.prototype.scrubbing = function scrubbing(isScrubbing) { + if (isScrubbing !== undefined) { + this.scrubbing_ = !!isScrubbing; + + if (isScrubbing) { + this.addClass('vjs-scrubbing'); + } else { + this.removeClass('vjs-scrubbing'); + } + + return this; + } + + return this.scrubbing_; + }; + + /** + * Get or set the current time (in seconds) + * + * @param {number|string} [seconds] + * The time to seek to in seconds + * + * @return {Player|number} + * - the current time in seconds when getting + * - a reference to the current player object when + * getting + */ + + + Player.prototype.currentTime = function currentTime(seconds) { + if (seconds !== undefined) { + + this.techCall_('setCurrentTime', seconds); + + return this; + } + + // cache last currentTime and return. default to 0 seconds + // + // Caching the currentTime is meant to prevent a massive amount of reads on the tech's + // currentTime when scrubbing, but may not provide much performance benefit afterall. + // Should be tested. Also something has to read the actual current time or the cache will + // never get updated. + this.cache_.currentTime = this.techGet_('currentTime') || 0; + return this.cache_.currentTime; + }; + + /** + * Normally gets the length in time of the video in seconds; + * in all but the rarest use cases an argument will NOT be passed to the method + * + * > **NOTE**: The video must have started loading before the duration can be + * known, and in the case of Flash, may not be known until the video starts + * playing. + * + * @fires Player#durationchange + * + * @param {number} [seconds] + * The duration of the video to set in seconds + * + * @return {number|Player} + * - The duration of the video in seconds when getting + * - A reference to the player that called this function + * when setting + */ + + + Player.prototype.duration = function duration(seconds) { + if (seconds === undefined) { + return this.cache_.duration || 0; + } + + seconds = parseFloat(seconds) || 0; + + // Standardize on Inifity for signaling video is live + if (seconds < 0) { + seconds = Infinity; + } + + if (seconds !== this.cache_.duration) { + // Cache the last set value for optimized scrubbing (esp. Flash) + this.cache_.duration = seconds; + + if (seconds === Infinity) { + this.addClass('vjs-live'); + } else { + this.removeClass('vjs-live'); + } + /** + * @event Player#durationchange + * @type {EventTarget~Event} + */ + this.trigger('durationchange'); + } + + return this; + }; + + /** + * Calculates how much time is left in the video. Not part + * of the native video API. + * + * @return {number} + * The time remaining in seconds + */ + + + Player.prototype.remainingTime = function remainingTime() { + return this.duration() - this.currentTime(); + }; + + // + // Kind of like an array of portions of the video that have been downloaded. + + /** + * Get a TimeRange object with an array of the times of the video + * that have been downloaded. If you just want the percent of the + * video that's been downloaded, use bufferedPercent. + * + * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered} + * + * @return {TimeRange} + * A mock TimeRange object (following HTML spec) + */ + + + Player.prototype.buffered = function buffered() { + var buffered = this.techGet_('buffered'); + + if (!buffered || !buffered.length) { + buffered = (0, _timeRanges.createTimeRange)(0, 0); + } + + return buffered; + }; + + /** + * Get the percent (as a decimal) of the video that's been downloaded. + * This method is not a part of the native HTML video API. + * + * @return {number} + * A decimal between 0 and 1 representing the percent + * that is bufferred 0 being 0% and 1 being 100% + */ + + + Player.prototype.bufferedPercent = function bufferedPercent() { + return (0, _buffer.bufferedPercent)(this.buffered(), this.duration()); + }; + + /** + * Get the ending time of the last buffered time range + * This is used in the progress bar to encapsulate all time ranges. + * + * @return {number} + * The end of the last buffered time range + */ + + + Player.prototype.bufferedEnd = function bufferedEnd() { + var buffered = this.buffered(); + var duration = this.duration(); + var end = buffered.end(buffered.length - 1); + + if (end > duration) { + end = duration; + } + + return end; + }; + + /** + * Get or set the current volume of the media + * + * @param {number} [percentAsDecimal] + * The new volume as a decimal percent: + * - 0 is muted/0%/off + * - 1.0 is 100%/full + * - 0.5 is half volume or 50% + * + * @return {Player|number} + * a reference to the calling player when setting and the + * current volume as a percent when getting + */ + + + Player.prototype.volume = function volume(percentAsDecimal) { + var vol = void 0; + + if (percentAsDecimal !== undefined) { + // Force value to between 0 and 1 + vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); + this.cache_.volume = vol; + this.techCall_('setVolume', vol); + + return this; + } + + // Default to 1 when returning current volume. + vol = parseFloat(this.techGet_('volume')); + return isNaN(vol) ? 1 : vol; + }; + + /** + * Get the current muted state, or turn mute on or off + * + * @param {boolean} [muted] + * - true to mute + * - false to unmute + * + * @return {boolean|Player} + * - true if mute is on and getting + * - false if mute is off and getting + * - A reference to the current player when setting + */ + + + Player.prototype.muted = function muted(_muted) { + if (_muted !== undefined) { + this.techCall_('setMuted', _muted); + return this; + } + return this.techGet_('muted') || false; + }; + + /** + * Check if current tech can support native fullscreen + * (e.g. with built in controls like iOS, so not our flash swf) + * + * @return {boolean} + * if native fullscreen is supported + */ + + + Player.prototype.supportsFullScreen = function supportsFullScreen() { + return this.techGet_('supportsFullScreen') || false; + }; + + /** + * Check if the player is in fullscreen mode or tell the player that it + * is or is not in fullscreen mode. + * + * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official + * property and instead document.fullscreenElement is used. But isFullscreen is + * still a valuable property for internal player workings. + * + * @param {boolean} [isFS] + * Set the players current fullscreen state + * + * @return {boolean|Player} + * - true if fullscreen is on and getting + * - false if fullscreen is off and getting + * - A reference to the current player when setting + */ + + + Player.prototype.isFullscreen = function isFullscreen(isFS) { + if (isFS !== undefined) { + this.isFullscreen_ = !!isFS; + return this; + } + return !!this.isFullscreen_; + }; + + /** + * Increase the size of the video to full screen + * In some browsers, full screen is not supported natively, so it enters + * "full window mode", where the video fills the browser window. + * In browsers and devices that support native full screen, sometimes the + * browser's default controls will be shown, and not the Video.js custom skin. + * This includes most mobile devices (iOS, Android) and older versions of + * Safari. + * + * @fires Player#fullscreenchange + * @return {Player} + * A reference to the current player + */ + + + Player.prototype.requestFullscreen = function requestFullscreen() { + var fsApi = _fullscreenApi2['default']; + + this.isFullscreen(true); + + if (fsApi.requestFullscreen) { + // the browser supports going fullscreen at the element level so we can + // take the controls fullscreen as well as the video + + // Trigger fullscreenchange event after change + // We have to specifically add this each time, and remove + // when canceling fullscreen. Otherwise if there's multiple + // players on a page, they would all be reacting to the same fullscreen + // events + Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) { + this.isFullscreen(_document2['default'][fsApi.fullscreenElement]); + + // If cancelling fullscreen, remove event listener. + if (this.isFullscreen() === false) { + Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange); + } + /** + * @event Player#fullscreenchange + * @type {EventTarget~Event} + */ + this.trigger('fullscreenchange'); + })); + + this.el_[fsApi.requestFullscreen](); + } else if (this.tech_.supportsFullScreen()) { + // we can't take the video.js controls fullscreen but we can go fullscreen + // with native controls + this.techCall_('enterFullScreen'); + } else { + // fullscreen isn't supported so we'll just stretch the video element to + // fill the viewport + this.enterFullWindow(); + /** + * @event Player#fullscreenchange + * @type {EventTarget~Event} + */ + this.trigger('fullscreenchange'); + } + + return this; + }; + + /** + * Return the video to its normal size after having been in full screen mode + * + * @fires Player#fullscreenchange + * + * @return {Player} + * A reference to the current player + */ + + + Player.prototype.exitFullscreen = function exitFullscreen() { + var fsApi = _fullscreenApi2['default']; + + this.isFullscreen(false); + + // Check for browser element fullscreen support + if (fsApi.requestFullscreen) { + _document2['default'][fsApi.exitFullscreen](); + } else if (this.tech_.supportsFullScreen()) { + this.techCall_('exitFullScreen'); + } else { + this.exitFullWindow(); + /** + * @event Player#fullscreenchange + * @type {EventTarget~Event} + */ + this.trigger('fullscreenchange'); + } + + return this; + }; + + /** + * When fullscreen isn't supported we can stretch the + * video container to as wide as the browser will let us. + * + * @fires Player#enterFullWindow + */ + + + Player.prototype.enterFullWindow = function enterFullWindow() { + this.isFullWindow = true; + + // Storing original doc overflow value to return to when fullscreen is off + this.docOrigOverflow = _document2['default'].documentElement.style.overflow; + + // Add listener for esc key to exit fullscreen + Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey)); + + // Hide any scroll bars + _document2['default'].documentElement.style.overflow = 'hidden'; + + // Apply fullscreen styles + Dom.addElClass(_document2['default'].body, 'vjs-full-window'); + + /** + * @event Player#enterFullWindow + * @type {EventTarget~Event} + */ + this.trigger('enterFullWindow'); + }; + + /** + * Check for call to either exit full window or + * full screen on ESC key + * + * @param {string} event + * Event to check for key press + */ + + + Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) { + if (event.keyCode === 27) { + if (this.isFullscreen() === true) { + this.exitFullscreen(); + } else { + this.exitFullWindow(); + } + } + }; + + /** + * Exit full window + * + * @fires Player#exitFullWindow + */ + + + Player.prototype.exitFullWindow = function exitFullWindow() { + this.isFullWindow = false; + Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey); + + // Unhide scroll bars. + _document2['default'].documentElement.style.overflow = this.docOrigOverflow; + + // Remove fullscreen styles + Dom.removeElClass(_document2['default'].body, 'vjs-full-window'); + + // Resize the box, controller, and poster to original sizes + // this.positionAll(); + /** + * @event Player#exitFullWindow + * @type {EventTarget~Event} + */ + this.trigger('exitFullWindow'); + }; + + /** + * Check whether the player can play a given mimetype + * + * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype + * + * @param {string} type + * The mimetype to check + * + * @return {string} + * 'probably', 'maybe', or '' (empty string) + */ + + + Player.prototype.canPlayType = function canPlayType(type) { + var can = void 0; + + // Loop through each playback technology in the options order + for (var i = 0, j = this.options_.techOrder; i < j.length; i++) { + var techName = (0, _toTitleCase2['default'])(j[i]); + var tech = _tech2['default'].getTech(techName); + + // Support old behavior of techs being registered as components. + // Remove once that deprecated behavior is removed. + if (!tech) { + tech = _component2['default'].getComponent(techName); + } + + // Check if the current tech is defined before continuing + if (!tech) { + _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); + continue; + } + + // Check if the browser supports this technology + if (tech.isSupported()) { + can = tech.canPlayType(type); + + if (can) { + return can; + } + } + } + + return ''; + }; + + /** + * Select source based on tech-order or source-order + * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise, + * defaults to tech-order selection + * + * @param {Array} sources + * The sources for a media asset + * + * @return {Object|boolean} + * Object of source and tech order or false + */ + + + Player.prototype.selectSource = function selectSource(sources) { + var _this4 = this; + + // Get only the techs specified in `techOrder` that exist and are supported by the + // current platform + var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) { + // `Component.getComponent(...)` is for support of old behavior of techs + // being registered as components. + // Remove once that deprecated behavior is removed. + return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)]; + }).filter(function (_ref) { + var techName = _ref[0], + tech = _ref[1]; + + // Check if the current tech is defined before continuing + if (tech) { + // Check if the browser supports this technology + return tech.isSupported(); + } + + _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.'); + return false; + }); + + // Iterate over each `innerArray` element once per `outerArray` element and execute + // `tester` with both. If `tester` returns a non-falsy value, exit early and return + // that value. + var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) { + var found = void 0; + + outerArray.some(function (outerChoice) { + return innerArray.some(function (innerChoice) { + found = tester(outerChoice, innerChoice); + + if (found) { + return true; + } + }); + }); + + return found; + }; + + var foundSourceAndTech = void 0; + var flip = function flip(fn) { + return function (a, b) { + return fn(b, a); + }; + }; + var finder = function finder(_ref2, source) { + var techName = _ref2[0], + tech = _ref2[1]; + + if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) { + return { source: source, tech: techName }; + } + }; + + // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources + // to select from them based on their priority. + if (this.options_.sourceOrder) { + // Source-first ordering + foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder)); + } else { + // Tech-first ordering + foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder); + } + + return foundSourceAndTech || false; + }; + + /** + * The source function updates the video source + * There are three types of variables you can pass as the argument. + * **URL string**: A URL to the the video file. Use this method if you are sure + * the current playback technology (HTML5/Flash) can support the source you + * provide. Currently only MP4 files can be used in both HTML5 and Flash. + * + * @param {Tech~SourceObject|Tech~SourceObject[]} [source] + * One SourceObject or an array of SourceObjects + * + * @return {string|Player} + * - The current video source when getting + * - The player when setting + */ + + + Player.prototype.src = function src(source) { + if (source === undefined) { + return this.techGet_('src'); + } + + var currentTech = _tech2['default'].getTech(this.techName_); + + // Support old behavior of techs being registered as components. + // Remove once that deprecated behavior is removed. + if (!currentTech) { + currentTech = _component2['default'].getComponent(this.techName_); + } + + // case: Array of source objects to choose from and pick the best to play + if (Array.isArray(source)) { + this.sourceList_(source); + + // case: URL String (http://myvideo...) + } else if (typeof source === 'string') { + // create a source object from the string + this.src({ src: source }); + + // case: Source object { src: '', type: '' ... } + } else if (source instanceof Object) { + // check if the source has a type and the loaded tech cannot play the source + // if there's no type we'll just try the current tech + if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) { + // create a source list with the current source and send through + // the tech loop to check for a compatible technology + this.sourceList_([source]); + } else { + this.cache_.sources = null; + this.cache_.source = source; + this.cache_.src = source.src; + + this.currentType_ = source.type || ''; + + // wait until the tech is ready to set the source + this.ready(function () { + + // The setSource tech method was added with source handlers + // so older techs won't support it + // We need to check the direct prototype for the case where subclasses + // of the tech do not support source handlers + if (currentTech.prototype.hasOwnProperty('setSource')) { + this.techCall_('setSource', source); + } else { + this.techCall_('src', source.src); + } + + if (this.options_.preload === 'auto') { + this.load(); + } + + if (this.options_.autoplay) { + this.play(); + } + + // Set the source synchronously if possible (#2326) + }, true); + } + } + + return this; + }; + + /** + * Handle an array of source objects + * + * @param {Tech~SourceObject[]} sources + * Array of source objects + * + * @private + */ + + + Player.prototype.sourceList_ = function sourceList_(sources) { + var sourceTech = this.selectSource(sources); + + if (sourceTech) { + if (sourceTech.tech === this.techName_) { + // if this technology is already loaded, set the source + this.src(sourceTech.source); + } else { + // load this technology with the chosen source + this.loadTech_(sourceTech.tech, sourceTech.source); + } + + this.cache_.sources = sources; + } else { + // We need to wrap this in a timeout to give folks a chance to add error event handlers + this.setTimeout(function () { + this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) }); + }, 0); + + // we could not find an appropriate tech, but let's still notify the delegate that this is it + // this needs a better comment about why this is needed + this.triggerReady(); + } + }; + + /** + * Begin loading the src data. + * + * @return {Player} + * A reference to the player + */ + + + Player.prototype.load = function load() { + this.techCall_('load'); + return this; + }; + + /** + * Reset the player. Loads the first tech in the techOrder, + * and calls `reset` on the tech`. + * + * @return {Player} + * A reference to the player + */ + + + Player.prototype.reset = function reset() { + this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null); + this.techCall_('reset'); + return this; + }; + + /** + * Returns all of the current source objects. + * + * @return {Tech~SourceObject[]} + * The current source objects + */ + + + Player.prototype.currentSources = function currentSources() { + var source = this.currentSource(); + var sources = []; + + // assume `{}` or `{ src }` + if (Object.keys(source).length !== 0) { + sources.push(source); + } + + return this.cache_.sources || sources; + }; + + /** + * Returns the current source object. + * + * @return {Tech~SourceObject} + * The current source object + */ + + + Player.prototype.currentSource = function currentSource() { + var source = {}; + var src = this.currentSrc(); + + if (src) { + source.src = src; + } + + return this.cache_.source || source; + }; + + /** + * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4 + * Can be used in conjuction with `currentType` to assist in rebuilding the current source object. + * + * @return {string} + * The current source + */ + + + Player.prototype.currentSrc = function currentSrc() { + return this.techGet_('currentSrc') || this.cache_.src || ''; + }; + + /** + * Get the current source type e.g. video/mp4 + * This can allow you rebuild the current source object so that you could load the same + * source and tech later + * + * @return {string} + * The source MIME type + */ + + + Player.prototype.currentType = function currentType() { + return this.currentType_ || ''; + }; + + /** + * Get or set the preload attribute + * + * @param {boolean} [value] + * - true means that we should preload + * - false maens that we should not preload + * + * @return {string|Player} + * - the preload attribute value when getting + * - the player when setting + */ + + + Player.prototype.preload = function preload(value) { + if (value !== undefined) { + this.techCall_('setPreload', value); + this.options_.preload = value; + return this; + } + return this.techGet_('preload'); + }; + + /** + * Get or set the autoplay attribute. + * + * @param {boolean} [value] + * - true means that we should autoplay + * - false maens that we should not autoplay + * + * @return {string|Player} + * - the current value of autoplay + * - the player when setting + */ + + + Player.prototype.autoplay = function autoplay(value) { + if (value !== undefined) { + this.techCall_('setAutoplay', value); + this.options_.autoplay = value; + return this; + } + return this.techGet_('autoplay', value); + }; + + /** + * Get or set the loop attribute on the video element. + * + * @param {boolean} [value] + * - true means that we should loop the video + * - false means that we should not loop the video + * + * @return {string|Player} + * - the current value of loop when getting + * - the player when setting + */ + + + Player.prototype.loop = function loop(value) { + if (value !== undefined) { + this.techCall_('setLoop', value); + this.options_.loop = value; + return this; + } + return this.techGet_('loop'); + }; + + /** + * Get or set the poster image source url + * + * @fires Player#posterchange + * + * @param {string} [src] + * Poster image source URL + * + * @return {string|Player} + * - the current value of poster when getting + * - the player when setting + */ + + + Player.prototype.poster = function poster(src) { + if (src === undefined) { + return this.poster_; + } + + // The correct way to remove a poster is to set as an empty string + // other falsey values will throw errors + if (!src) { + src = ''; + } + + // update the internal poster variable + this.poster_ = src; + + // update the tech's poster + this.techCall_('setPoster', src); + + // alert components that the poster has been set + /** + * This event fires when the poster image is changed on the player. + * + * @event Player#posterchange + * @type {EventTarget~Event} + */ + this.trigger('posterchange'); + + return this; + }; + + /** + * Some techs (e.g. YouTube) can provide a poster source in an + * asynchronous way. We want the poster component to use this + * poster source so that it covers up the tech's controls. + * (YouTube's play button). However we only want to use this + * soruce if the player user hasn't set a poster through + * the normal APIs. + * + * @fires Player#posterchange + * @listens Tech#posterchange + * @private + */ + + + Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() { + if (!this.poster_ && this.tech_ && this.tech_.poster) { + this.poster_ = this.tech_.poster() || ''; + + // Let components know the poster has changed + this.trigger('posterchange'); + } + }; + + /** + * Get or set whether or not the controls are showing. + * + * @fires Player#controlsenabled + * + * @param {boolean} [bool] + * - true to turn controls on + * - false to turn controls off + * + * @return {boolean|Player} + * - the current value of controls when getting + * - the player when setting + */ + + + Player.prototype.controls = function controls(bool) { + if (bool !== undefined) { + bool = !!bool; + + // Don't trigger a change event unless it actually changed + if (this.controls_ !== bool) { + this.controls_ = bool; + + if (this.usingNativeControls()) { + this.techCall_('setControls', bool); + } + + if (bool) { + this.removeClass('vjs-controls-disabled'); + this.addClass('vjs-controls-enabled'); + /** + * @event Player#controlsenabled + * @type {EventTarget~Event} + */ + this.trigger('controlsenabled'); + + if (!this.usingNativeControls()) { + this.addTechControlsListeners_(); + } + } else { + this.removeClass('vjs-controls-enabled'); + this.addClass('vjs-controls-disabled'); + /** + * @event Player#controlsdisabled + * @type {EventTarget~Event} + */ + this.trigger('controlsdisabled'); + + if (!this.usingNativeControls()) { + this.removeTechControlsListeners_(); + } + } + } + return this; + } + return !!this.controls_; + }; + + /** + * Toggle native controls on/off. Native controls are the controls built into + * devices (e.g. default iPhone controls), Flash, or other techs + * (e.g. Vimeo Controls) + * **This should only be set by the current tech, because only the tech knows + * if it can support native controls** + * + * @fires Player#usingnativecontrols + * @fires Player#usingcustomcontrols + * + * @param {boolean} [bool] + * - true to turn native controls on + * - false to turn native controls off + * + * @return {boolean|Player} + * - the current value of native controls when getting + * - the player when setting + */ + + + Player.prototype.usingNativeControls = function usingNativeControls(bool) { + if (bool !== undefined) { + bool = !!bool; + + // Don't trigger a change event unless it actually changed + if (this.usingNativeControls_ !== bool) { + this.usingNativeControls_ = bool; + if (bool) { + this.addClass('vjs-using-native-controls'); + + /** + * player is using the native device controls + * + * @event Player#usingnativecontrols + * @type {EventTarget~Event} + */ + this.trigger('usingnativecontrols'); + } else { + this.removeClass('vjs-using-native-controls'); + + /** + * player is using the custom HTML controls + * + * @event Player#usingcustomcontrols + * @type {EventTarget~Event} + */ + this.trigger('usingcustomcontrols'); + } + } + return this; + } + return !!this.usingNativeControls_; + }; + + /** + * Set or get the current MediaError + * + * @fires Player#error + * + * @param {MediaError|string|number} [err] + * A MediaError or a string/number to be turned + * into a MediaError + * + * @return {MediaError|null|Player} + * - The current MediaError when getting (or null) + * - The player when setting + */ + + + Player.prototype.error = function error(err) { + if (err === undefined) { + return this.error_ || null; + } + + // restoring to default + if (err === null) { + this.error_ = err; + this.removeClass('vjs-error'); + if (this.errorDisplay) { + this.errorDisplay.close(); + } + return this; + } + + this.error_ = new _mediaError2['default'](err); + + // add the vjs-error classname to the player + this.addClass('vjs-error'); + + // log the name of the error type and any message + // ie8 just logs "[object object]" if you just log the error object + _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_); + + /** + * @event Player#error + * @type {EventTarget~Event} + */ + this.trigger('error'); + + return this; + }; + + /** + * Report user activity + * + * @param {Object} event + * Event object + */ + + + Player.prototype.reportUserActivity = function reportUserActivity(event) { + this.userActivity_ = true; + }; + + /** + * Get/set if user is active + * + * @fires Player#useractive + * @fires Player#userinactive + * + * @param {boolean} [bool] + * - true if the user is active + * - false if the user is inactive + * @return {boolean|Player} + * - the current value of userActive when getting + * - the player when setting + */ + + + Player.prototype.userActive = function userActive(bool) { + if (bool !== undefined) { + bool = !!bool; + if (bool !== this.userActive_) { + this.userActive_ = bool; + if (bool) { + // If the user was inactive and is now active we want to reset the + // inactivity timer + this.userActivity_ = true; + this.removeClass('vjs-user-inactive'); + this.addClass('vjs-user-active'); + /** + * @event Player#useractive + * @type {EventTarget~Event} + */ + this.trigger('useractive'); + } else { + // We're switching the state to inactive manually, so erase any other + // activity + this.userActivity_ = false; + + // Chrome/Safari/IE have bugs where when you change the cursor it can + // trigger a mousemove event. This causes an issue when you're hiding + // the cursor when the user is inactive, and a mousemove signals user + // activity. Making it impossible to go into inactive mode. Specifically + // this happens in fullscreen when we really need to hide the cursor. + // + // When this gets resolved in ALL browsers it can be removed + // https://code.google.com/p/chromium/issues/detail?id=103041 + if (this.tech_) { + this.tech_.one('mousemove', function (e) { + e.stopPropagation(); + e.preventDefault(); + }); + } + + this.removeClass('vjs-user-active'); + this.addClass('vjs-user-inactive'); + /** + * @event Player#userinactive + * @type {EventTarget~Event} + */ + this.trigger('userinactive'); + } + } + return this; + } + return this.userActive_; + }; + + /** + * Listen for user activity based on timeout value + * + * @private + */ + + + Player.prototype.listenForUserActivity_ = function listenForUserActivity_() { + var mouseInProgress = void 0; + var lastMoveX = void 0; + var lastMoveY = void 0; + var handleActivity = Fn.bind(this, this.reportUserActivity); + + var handleMouseMove = function handleMouseMove(e) { + // #1068 - Prevent mousemove spamming + // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970 + if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) { + lastMoveX = e.screenX; + lastMoveY = e.screenY; + handleActivity(); + } + }; + + var handleMouseDown = function handleMouseDown() { + handleActivity(); + // For as long as the they are touching the device or have their mouse down, + // we consider them active even if they're not moving their finger or mouse. + // So we want to continue to update that they are active + this.clearInterval(mouseInProgress); + // Setting userActivity=true now and setting the interval to the same time + // as the activityCheck interval (250) should ensure we never miss the + // next activityCheck + mouseInProgress = this.setInterval(handleActivity, 250); + }; + + var handleMouseUp = function handleMouseUp(event) { + handleActivity(); + // Stop the interval that maintains activity if the mouse/touch is down + this.clearInterval(mouseInProgress); + }; + + // Any mouse movement will be considered user activity + this.on('mousedown', handleMouseDown); + this.on('mousemove', handleMouseMove); + this.on('mouseup', handleMouseUp); + + // Listen for keyboard navigation + // Shouldn't need to use inProgress interval because of key repeat + this.on('keydown', handleActivity); + this.on('keyup', handleActivity); + + // Run an interval every 250 milliseconds instead of stuffing everything into + // the mousemove/touchmove function itself, to prevent performance degradation. + // `this.reportUserActivity` simply sets this.userActivity_ to true, which + // then gets picked up by this loop + // http://ejohn.org/blog/learning-from-twitter/ + var inactivityTimeout = void 0; + + this.setInterval(function () { + // Check to see if mouse/touch activity has happened + if (this.userActivity_) { + // Reset the activity tracker + this.userActivity_ = false; + + // If the user state was inactive, set the state to active + this.userActive(true); + + // Clear any existing inactivity timeout to start the timer over + this.clearTimeout(inactivityTimeout); + + var timeout = this.options_.inactivityTimeout; + + if (timeout > 0) { + // In <timeout> milliseconds, if no more activity has occurred the + // user will be considered inactive + inactivityTimeout = this.setTimeout(function () { + // Protect against the case where the inactivityTimeout can trigger just + // before the next user activity is picked up by the activity check loop + // causing a flicker + if (!this.userActivity_) { + this.userActive(false); + } + }, timeout); + } + } + }, 250); + }; + + /** + * Gets or sets the current playback rate. A playback rate of + * 1.0 represents normal speed and 0.5 would indicate half-speed + * playback, for instance. + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate + * + * @param {number} [rate] + * New playback rate to set. + * + * @return {number|Player} + * - The current playback rate when getting or 1.0 + * - the player when setting + */ + + + Player.prototype.playbackRate = function playbackRate(rate) { + if (rate !== undefined) { + this.techCall_('setPlaybackRate', rate); + return this; + } + + if (this.tech_ && this.tech_.featuresPlaybackRate) { + return this.techGet_('playbackRate'); + } + return 1.0; + }; + + /** + * Gets or sets the audio flag + * + * @param {boolean} bool + * - true signals that this is an audio player + * - false signals that this is not an audio player + * + * @return {Player|boolean} + * - the current value of isAudio when getting + * - the player if setting + */ + + + Player.prototype.isAudio = function isAudio(bool) { + if (bool !== undefined) { + this.isAudio_ = !!bool; + return this; + } + + return !!this.isAudio_; + }; + + /** + * Get the {@link VideoTrackList} + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist + * + * @return {VideoTrackList} + * the current video track list + */ + + + Player.prototype.videoTracks = function videoTracks() { + // if we have not yet loadTech_, we create videoTracks_ + // these will be passed to the tech during loading + if (!this.tech_) { + this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); + return this.videoTracks_; + } + + return this.tech_.videoTracks(); + }; + + /** + * Get the {@link AudioTrackList} + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist + * + * @return {AudioTrackList} + * the current audio track list + */ + + + Player.prototype.audioTracks = function audioTracks() { + // if we have not yet loadTech_, we create videoTracks_ + // these will be passed to the tech during loading + if (!this.tech_) { + this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); + return this.audioTracks_; + } + + return this.tech_.audioTracks(); + }; + + /** + * Get the {@link TextTrackList} + * + * Text tracks are tracks of timed text events. + * - Captions: text displayed over the video + * for the hearing impaired + * - Subtitles: text displayed over the video for + * those who don't understand language in the video + * - Chapters: text displayed in a menu allowing the user to jump + * to particular points (chapters) in the video + * - Descriptions: (not yet implemented) audio descriptions that are read back to + * the user by a screen reading device + * + * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks + * + * @return {TextTrackList|undefined} + * The current TextTrackList or undefined if + * or undefined if we don't have a tech + */ + + + Player.prototype.textTracks = function textTracks() { + // cannot use techGet_ directly because it checks to see whether the tech is ready. + // Flash is unlikely to be ready in time but textTracks should still work. + if (this.tech_) { + return this.tech_.textTracks(); + } + }; + + /** + * Get the "remote" {@link TextTrackList}. Remote Text Tracks + * are tracks that were added to the HTML video element and can + * be removed, whereas normal texttracks cannot be removed. + * + * + * @return {TextTrackList|undefined} + * The current remote text track list or undefined + * if we don't have a tech + */ + + + Player.prototype.remoteTextTracks = function remoteTextTracks() { + if (this.tech_) { + return this.tech_.remoteTextTracks(); + } + }; + + /** + * Get the "remote" {@link HTMLTrackElementList}. + * This gives the user all of the DOM elements that match up + * with the remote {@link TextTrackList}. + * + * @return {HTMLTrackElementList} + * The current remote text track list elements + * or undefined if we don't have a tech + */ + + + Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() { + if (this.tech_) { + return this.tech_.remoteTextTrackEls(); + } + }; + + /** + * A helper method for adding a {@link TextTrack} to our + * {@link TextTrackList}. + * + * In addition to the W3C settings we allow adding additional info through options. + * + * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack + * + * @param {string} [kind] + * the kind of TextTrack you are adding + * + * @param {string} [label] + * the label to give the TextTrack label + * + * @param {string} [language] + * the language to set on the TextTrack + * + * @return {TextTrack|undefined} + * the TextTrack that was added or undefined + * if there is no tech + */ + + + Player.prototype.addTextTrack = function addTextTrack(kind, label, language) { + if (this.tech_) { + return this.tech_.addTextTrack(kind, label, language); + } + }; + + /** + * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will + * automatically removed from the video element whenever the source changes, unless + * manualCleanup is set to false. + * + * @param {Object} options + * Options to pass to {@link HTMLTrackElement} during creation. See + * {@link HTMLTrackElement} for object properties that you should use. + * + * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be + * + * @return {HTMLTrackElement} + * the HTMLTrackElement that was created and added + * to the HTMLTrackElementList and the remote + * TextTrackList + * + * @deprecated The default value of the "manualCleanup" parameter will default + * to "false" in upcoming versions of Video.js + */ + + + Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { + if (this.tech_) { + return this.tech_.addRemoteTextTrack(options, manualCleanup); + } + }; + + /** + * Remove a remote {@link TextTrack} from the respective + * {@link TextTrackList} and {@link HTMLTrackElementList}. + * + * @param {Object} track + * Remote {@link TextTrack} to remove + * + * @return {undefined} + * does not return anything + */ + + + Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() { + var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref3$track = _ref3.track, + track = _ref3$track === undefined ? arguments[0] : _ref3$track; + + // destructure the input into an object with a track argument, defaulting to arguments[0] + // default the whole argument to an empty object if nothing was passed in + + if (this.tech_) { + return this.tech_.removeRemoteTextTrack(track); + } + }; + + /** + * Get video width + * + * @return {number} + * current video width + */ + + + Player.prototype.videoWidth = function videoWidth() { + return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0; + }; + + /** + * Get video height + * + * @return {number} + * current video height + */ + + + Player.prototype.videoHeight = function videoHeight() { + return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0; + }; + + // Methods to add support for + // initialTime: function() { return this.techCall_('initialTime'); }, + // startOffsetTime: function() { return this.techCall_('startOffsetTime'); }, + // played: function() { return this.techCall_('played'); }, + // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); }, + // defaultMuted: function() { return this.techCall_('defaultMuted'); } + + /** + * The player's language code + * NOTE: The language should be set in the player options if you want the + * the controls to be built with a specific language. Changing the lanugage + * later will not update controls text. + * + * @param {string} [code] + * the language code to set the player to + * + * @return {string|Player} + * - The current language code when getting + * - A reference to the player when setting + */ + + + Player.prototype.language = function language(code) { + if (code === undefined) { + return this.language_; + } + + this.language_ = String(code).toLowerCase(); + return this; + }; + + /** + * Get the player's language dictionary + * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time + * Languages specified directly in the player options have precedence + * + * @return {Array} + * An array of of supported languages + */ + + + Player.prototype.languages = function languages() { + return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_); + }; + + /** + * returns a JavaScript object reperesenting the current track + * information. **DOES not return it as JSON** + * + * @return {Object} + * Object representing the current of track info + */ + + + Player.prototype.toJSON = function toJSON() { + var options = (0, _mergeOptions2['default'])(this.options_); + var tracks = options.tracks; + + options.tracks = []; + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + // deep merge tracks and null out player so no circular references + track = (0, _mergeOptions2['default'])(track); + track.player = undefined; + options.tracks[i] = track; + } + + return options; + }; + + /** + * Creates a simple modal dialog (an instance of the {@link ModalDialog} + * component) that immediately overlays the player with arbitrary + * content and removes itself when closed. + * + * @param {string|Function|Element|Array|null} content + * Same as {@link ModalDialog#content}'s param of the same name. + * The most straight-forward usage is to provide a string or DOM + * element. + * + * @param {Object} [options] + * Extra options which will be passed on to the {@link ModalDialog}. + * + * @return {ModalDialog} + * the {@link ModalDialog} that was created + */ + + + Player.prototype.createModal = function createModal(content, options) { + var _this5 = this; + + options = options || {}; + options.content = content || ''; + + var modal = new _modalDialog2['default'](this, options); + + this.addChild(modal); + modal.on('dispose', function () { + _this5.removeChild(modal); + }); + + return modal.open(); + }; + + /** + * Gets tag settings + * + * @param {Element} tag + * The player tag + * + * @return {Object} + * An object containing all of the settings + * for a player tag + */ + + + Player.getTagSettings = function getTagSettings(tag) { + var baseOptions = { + sources: [], + tracks: [] + }; + + var tagOptions = Dom.getElAttributes(tag); + var dataSetup = tagOptions['data-setup']; + + if (Dom.hasElClass(tag, 'vjs-fluid')) { + tagOptions.fluid = true; + } + + // Check if data-setup attr exists. + if (dataSetup !== null) { + // Parse options JSON + // If empty string, make it a parsable json object. + var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'), + err = _safeParseTuple[0], + data = _safeParseTuple[1]; + + if (err) { + _log2['default'].error(err); + } + (0, _obj.assign)(tagOptions, data); + } + + (0, _obj.assign)(baseOptions, tagOptions); + + // Get tag children settings + if (tag.hasChildNodes()) { + var children = tag.childNodes; + + for (var i = 0, j = children.length; i < j; i++) { + var child = children[i]; + // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/ + var childName = child.nodeName.toLowerCase(); + + if (childName === 'source') { + baseOptions.sources.push(Dom.getElAttributes(child)); + } else if (childName === 'track') { + baseOptions.tracks.push(Dom.getElAttributes(child)); + } + } + } + + return baseOptions; + }; + + /** + * Determine wether or not flexbox is supported + * + * @return {boolean} + * - true if flexbox is supported + * - false if flexbox is not supported + */ + + + Player.prototype.flexNotSupported_ = function flexNotSupported_() { + var elem = _document2['default'].createElement('i'); + + // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more + // common flex features that we can rely on when checking for flex support. + return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || + // IE10-specific (2012 flex spec) + 'msFlexOrder' in elem.style); + }; + + return Player; +}(_component2['default']); + +/** + * Global player list + * + * @type {Object} + */ + + +Player.players = {}; + +var navigator = _window2['default'].navigator; + +/* + * Player instance options, surfaced using options + * options = Player.prototype.options_ + * Make changes in options, not here. + * + * @type {Object} + * @private + */ +Player.prototype.options_ = { + // Default order of fallback technology + techOrder: ['html5', 'flash'], + // techOrder: ['flash','html5'], + + html5: {}, + flash: {}, + + // defaultVolume: 0.85, + defaultVolume: 0.00, + + // default inactivity timeout + inactivityTimeout: 2000, + + // default playback rates + playbackRates: [], + // Add playback rate selection by adding rates + // 'playbackRates': [0.5, 1, 1.5, 2], + + // Included control sets + children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'], + + language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en', + + // locales and their language translations + languages: {}, + + // Default message to show when a video cannot be played. + notSupportedMessage: 'No compatible source was found for this media.' +}; + +[ +/** + * Returns whether or not the player is in the "ended" state. + * + * @return {Boolean} True if the player is in the ended state, false if not. + * @method Player#ended + */ +'ended', +/** + * Returns whether or not the player is in the "seeking" state. + * + * @return {Boolean} True if the player is in the seeking state, false if not. + * @method Player#seeking + */ +'seeking', +/** + * Returns the TimeRanges of the media that are currently available + * for seeking to. + * + * @return {TimeRanges} the seekable intervals of the media timeline + * @method Player#seekable + */ +'seekable', +/** + * Returns the current state of network activity for the element, from + * the codes in the list below. + * - NETWORK_EMPTY (numeric value 0) + * The element has not yet been initialised. All attributes are in + * their initial states. + * - NETWORK_IDLE (numeric value 1) + * The element's resource selection algorithm is active and has + * selected a resource, but it is not actually using the network at + * this time. + * - NETWORK_LOADING (numeric value 2) + * The user agent is actively trying to download data. + * - NETWORK_NO_SOURCE (numeric value 3) + * The element's resource selection algorithm is active, but it has + * not yet found a resource to use. + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states + * @return {number} the current network activity state + * @method Player#networkState + */ +'networkState', +/** + * Returns a value that expresses the current state of the element + * with respect to rendering the current playback position, from the + * codes in the list below. + * - HAVE_NOTHING (numeric value 0) + * No information regarding the media resource is available. + * - HAVE_METADATA (numeric value 1) + * Enough of the resource has been obtained that the duration of the + * resource is available. + * - HAVE_CURRENT_DATA (numeric value 2) + * Data for the immediate current playback position is available. + * - HAVE_FUTURE_DATA (numeric value 3) + * Data for the immediate current playback position is available, as + * well as enough data for the user agent to advance the current + * playback position in the direction of playback. + * - HAVE_ENOUGH_DATA (numeric value 4) + * The user agent estimates that enough data is available for + * playback to proceed uninterrupted. + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate + * @return {number} the current playback rendering state + * @method Player#readyState + */ +'readyState'].forEach(function (fn) { + Player.prototype[fn] = function () { + return this.techGet_(fn); + }; +}); + +TECH_EVENTS_RETRIGGER.forEach(function (event) { + Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () { + return this.trigger(event); + }; +}); + +/** + * Fired when the player has initial duration and dimension information + * + * @event Player#loadedmetadata + * @type {EventTarget~Event} + */ + +/** + * Fired when the player has downloaded data at the current playback position + * + * @event Player#loadeddata + * @type {EventTarget~Event} + */ + +/** + * Fired when the current playback position has changed * + * During playback this is fired every 15-250 milliseconds, depending on the + * playback technology in use. + * + * @event Player#timeupdate + * @type {EventTarget~Event} + */ + +/** + * Fired when the volume changes + * + * @event Player#volumechange + * @type {EventTarget~Event} + */ + +_component2['default'].registerComponent('Player', Player); +exports['default'] = Player; + +},{"1":1,"4":4,"41":41,"44":44,"45":45,"46":46,"5":5,"50":50,"55":55,"59":59,"60":60,"61":61,"62":62,"63":63,"68":68,"69":69,"71":71,"76":76,"78":78,"79":79,"8":8,"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"94":94,"95":95,"97":97}],52:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _player = _dereq_(51); + +var _player2 = _interopRequireDefault(_player); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin]. + * + * @param {string} name + * The name of the plugin that is being registered + * + * @param {plugins:PluginFn} init + * The function that gets run when a `Player` initializes. + */ +var plugin = function plugin(name, init) { + _player2['default'].prototype[name] = init; +}; /** + * @file plugins.js + * @module plugins + */ +exports['default'] = plugin; + +},{"51":51}],53:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _clickableComponent = _dereq_(3); + +var _clickableComponent2 = _interopRequireDefault(_clickableComponent); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file popup-button.js + */ + + +/** + * A button class for use with {@link Popup} controls + * + * @extends ClickableComponent + */ +var PopupButton = function (_ClickableComponent) { + _inherits(PopupButton, _ClickableComponent); + + /** + * Create an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PopupButton(player) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, PopupButton); + + var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); + + _this.update(); + return _this; + } + + /** + * Update the `Popup` that this button is attached to. + */ + + + PopupButton.prototype.update = function update() { + var popup = this.createPopup(); + + if (this.popup) { + this.removeChild(this.popup); + } + + this.popup = popup; + this.addChild(popup); + + if (this.items && this.items.length === 0) { + this.hide(); + } else if (this.items && this.items.length > 1) { + this.show(); + } + }; + + /** + * Create a `Popup`. - Override with specific functionality for component + * + * @abstract + */ + + + PopupButton.prototype.createPopup = function createPopup() {}; + + /** + * Create the `PopupButton`s DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + PopupButton.prototype.createEl = function createEl() { + return _ClickableComponent.prototype.createEl.call(this, 'div', { + className: this.buildCSSClass() + }); + }; + + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + + + PopupButton.prototype.buildCSSClass = function buildCSSClass() { + var menuButtonClass = 'vjs-menu-button'; + + // If the inline option is passed, we want to use different styles altogether. + if (this.options_.inline === true) { + menuButtonClass += '-inline'; + } else { + menuButtonClass += '-popup'; + } + + return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this); + }; + + return PopupButton; +}(_clickableComponent2['default']); + +_component2['default'].registerComponent('PopupButton', PopupButton); +exports['default'] = PopupButton; + +},{"3":3,"5":5}],54:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file popup.js + */ + + +/** + * The Popup component is used to build pop up controls. + * + * @extends Component + */ +var Popup = function (_Component) { + _inherits(Popup, _Component); + + function Popup() { + _classCallCheck(this, Popup); + + return _possibleConstructorReturn(this, _Component.apply(this, arguments)); + } + + /** + * Add a popup item to the popup + * + * @param {Object|string} component + * Component or component type to add + * + */ + Popup.prototype.addItem = function addItem(component) { + this.addChild(component); + component.on('click', Fn.bind(this, function () { + this.unlockShowing(); + })); + }; + + /** + * Create the `PopupButton`s DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + Popup.prototype.createEl = function createEl() { + var contentElType = this.options_.contentElType || 'ul'; + + this.contentEl_ = Dom.createEl(contentElType, { + className: 'vjs-menu-content' + }); + + var el = _Component.prototype.createEl.call(this, 'div', { + append: this.contentEl_, + className: 'vjs-menu' + }); + + el.appendChild(this.contentEl_); + + // Prevent clicks from bubbling up. Needed for Popup Buttons, + // where a click on the parent is significant + Events.on(el, 'click', function (event) { + event.preventDefault(); + event.stopImmediatePropagation(); + }); + + return el; + }; + + return Popup; +}(_component2['default']); + +_component2['default'].registerComponent('Popup', Popup); +exports['default'] = Popup; + +},{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _clickableComponent = _dereq_(3); + +var _clickableComponent2 = _interopRequireDefault(_clickableComponent); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file poster-image.js + */ + + +/** + * A `ClickableComponent` that handles showing the poster image for the player. + * + * @extends ClickableComponent + */ +var PosterImage = function (_ClickableComponent) { + _inherits(PosterImage, _ClickableComponent); + + /** + * Create an instance of this class. + * + * @param {Player} player + * The `Player` that this class should attach to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function PosterImage(player, options) { + _classCallCheck(this, PosterImage); + + var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options)); + + _this.update(); + player.on('posterchange', Fn.bind(_this, _this.update)); + return _this; + } + + /** + * Clean up and dispose of the `PosterImage`. + */ + + + PosterImage.prototype.dispose = function dispose() { + this.player().off('posterchange', this.update); + _ClickableComponent.prototype.dispose.call(this); + }; + + /** + * Create the `PosterImage`s DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + PosterImage.prototype.createEl = function createEl() { + var el = Dom.createEl('div', { + className: 'vjs-poster', + + // Don't want poster to be tabbable. + tabIndex: -1 + }); + + // To ensure the poster image resizes while maintaining its original aspect + // ratio, use a div with `background-size` when available. For browsers that + // do not support `background-size` (e.g. IE8), fall back on using a regular + // img element. + if (!browser.BACKGROUND_SIZE_SUPPORTED) { + this.fallbackImg_ = Dom.createEl('img'); + el.appendChild(this.fallbackImg_); + } + + return el; + }; + + /** + * An {@link EventTarget~EventListener} for {@link Player#posterchange} events. + * + * @listens Player#posterchange + * + * @param {EventTarget~Event} [event] + * The `Player#posterchange` event that triggered this function. + */ + + + PosterImage.prototype.update = function update(event) { + var url = this.player().poster(); + + this.setSrc(url); + + // If there's no poster source we should display:none on this component + // so it's not still clickable or right-clickable + if (url) { + this.show(); + } else { + this.hide(); + } + }; + + /** + * Set the source of the `PosterImage` depending on the display method. + * + * @param {string} url + * The URL to the source for the `PosterImage`. + */ + + + PosterImage.prototype.setSrc = function setSrc(url) { + if (this.fallbackImg_) { + this.fallbackImg_.src = url; + } else { + var backgroundImage = ''; + + // Any falsey values should stay as an empty string, otherwise + // this will throw an extra error + if (url) { + backgroundImage = 'url("' + url + '")'; + } + + this.el_.style.backgroundImage = backgroundImage; + } + }; + + /** + * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See + * {@link ClickableComponent#handleClick} for instances where this will be triggered. + * + * @listens tap + * @listens click + * @listens keydown + * + * @param {EventTarget~Event} event + + The `click`, `tap` or `keydown` event that caused this function to be called. + */ + + + PosterImage.prototype.handleClick = function handleClick(event) { + // We don't want a click to trigger playback when controls are disabled + // but CSS should be hiding the poster to prevent that from happening + if (this.player_.paused()) { + this.player_.play(); + } else { + this.player_.pause(); + } + }; + + return PosterImage; +}(_clickableComponent2['default']); + +_component2['default'].registerComponent('PosterImage', PosterImage); +exports['default'] = PosterImage; + +},{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined; + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +/** + * @file setup.js - Functions for setting up a player without + * user interaction based on the data-setup `attribute` of the video tag. + * + * @module setup + */ +var _windowLoaded = false; +var videojs = void 0; + +/** + * Set up any tags that have a data-setup `attribute` when the player is started. + */ +var autoSetup = function autoSetup() { + + // Protect against breakage in non-browser environments. + if (!Dom.isReal()) { + return; + } + + // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack* + // var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); + // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); + // var mediaEls = vids.concat(audios); + + // Because IE8 doesn't support calling slice on a node list, we need to loop + // through each list of elements to build up a new, combined list of elements. + var vids = _document2['default'].getElementsByTagName('video'); + var audios = _document2['default'].getElementsByTagName('audio'); + var mediaEls = []; + + if (vids && vids.length > 0) { + for (var i = 0, e = vids.length; i < e; i++) { + mediaEls.push(vids[i]); + } + } + + if (audios && audios.length > 0) { + for (var _i = 0, _e = audios.length; _i < _e; _i++) { + mediaEls.push(audios[_i]); + } + } + + // Check if any media elements exist + if (mediaEls && mediaEls.length > 0) { + + for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) { + var mediaEl = mediaEls[_i2]; + + // Check if element exists, has getAttribute func. + // IE seems to consider typeof el.getAttribute == 'object' instead of + // 'function' like expected, at least when loading the player immediately. + if (mediaEl && mediaEl.getAttribute) { + + // Make sure this player hasn't already been set up. + if (mediaEl.player === undefined) { + var options = mediaEl.getAttribute('data-setup'); + + // Check if data-setup attr exists. + // We only auto-setup if they've added the data-setup attr. + if (options !== null) { + // Create new video.js instance. + videojs(mediaEl); + } + } + + // If getAttribute isn't defined, we need to wait for the DOM. + } else { + autoSetupTimeout(1); + break; + } + } + + // No videos were found, so keep looping unless page is finished loading. + } else if (!_windowLoaded) { + autoSetupTimeout(1); + } +}; + +/** + * Wait until the page is loaded before running autoSetup. This will be called in + * autoSetup if `hasLoaded` returns false. + * + * @param {number} wait + * How long to wait in ms + * + * @param {videojs} [vjs] + * The videojs library function + */ +function autoSetupTimeout(wait, vjs) { + if (vjs) { + videojs = vjs; + } + + _window2['default'].setTimeout(autoSetup, wait); +} + +if (Dom.isReal() && _document2['default'].readyState === 'complete') { + _windowLoaded = true; +} else { + /** + * Listen for the load event on window, and set _windowLoaded to true. + * + * @listens load + */ + Events.one(_window2['default'], 'load', function () { + _windowLoaded = true; + }); +} + +/** + * check if the document has been loaded + */ +var hasLoaded = function hasLoaded() { + return _windowLoaded; +}; + +exports.autoSetup = autoSetup; +exports.autoSetupTimeout = autoSetupTimeout; +exports.hasLoaded = hasLoaded; + +},{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _obj = _dereq_(88); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file slider.js + */ + + +/** + * The base functionality for a slider. Can be vertical or horizontal. + * For instance the volume bar or the seek bar on a video is a slider. + * + * @extends Component + */ +var Slider = function (_Component) { + _inherits(Slider, _Component); + + /** + * Create an instance of this class + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function Slider(player, options) { + _classCallCheck(this, Slider); + + // Set property names to bar to match with the child Slider class is looking for + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.bar = _this.getChild(_this.options_.barName); + + // Set a horizontal or vertical class on the slider depending on the slider type + _this.vertical(!!_this.options_.vertical); + + _this.on('mousedown', _this.handleMouseDown); + _this.on('touchstart', _this.handleMouseDown); + _this.on('focus', _this.handleFocus); + _this.on('blur', _this.handleBlur); + _this.on('click', _this.handleClick); + + _this.on(player, 'controlsvisible', _this.update); + _this.on(player, _this.playerEvent, _this.update); + return _this; + } + + /** + * Create the `Button`s DOM element. + * + * @param {string} type + * Type of element to create. + * + * @param {Object} [props={}] + * List of properties in Object form. + * + * @param {Object} [attributes={}] + * list of attributes in Object form. + * + * @return {Element} + * The element that gets created. + */ + + + Slider.prototype.createEl = function createEl(type) { + var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + // Add the slider element class to all sub classes + props.className = props.className + ' vjs-slider'; + props = (0, _obj.assign)({ + tabIndex: 0 + }, props); + + attributes = (0, _obj.assign)({ + 'role': 'slider', + 'aria-valuenow': 0, + 'aria-valuemin': 0, + 'aria-valuemax': 100, + 'tabIndex': 0 + }, attributes); + + return _Component.prototype.createEl.call(this, type, props, attributes); + }; + + /** + * Handle `mousedown` or `touchstart` events on the `Slider`. + * + * @param {EventTarget~Event} event + * `mousedown` or `touchstart` event that triggered this function + * + * @listens mousedown + * @listens touchstart + * @fires Slider#slideractive + */ + + + Slider.prototype.handleMouseDown = function handleMouseDown(event) { + var doc = this.bar.el_.ownerDocument; + + event.preventDefault(); + Dom.blockTextSelection(); + + this.addClass('vjs-sliding'); + /** + * Triggered when the slider is in an active state + * + * @event Slider#slideractive + * @type {EventTarget~Event} + */ + this.trigger('slideractive'); + + this.on(doc, 'mousemove', this.handleMouseMove); + this.on(doc, 'mouseup', this.handleMouseUp); + this.on(doc, 'touchmove', this.handleMouseMove); + this.on(doc, 'touchend', this.handleMouseUp); + + this.handleMouseMove(event); + }; + + /** + * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`. + * The `mousemove` and `touchmove` events will only only trigger this function during + * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and + * {@link Slider#handleMouseUp}. + * + * @param {EventTarget~Event} event + * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered + * this function + * + * @listens mousemove + * @listens touchmove + */ + + + Slider.prototype.handleMouseMove = function handleMouseMove(event) {}; + + /** + * Handle `mouseup` or `touchend` events on the `Slider`. + * + * @param {EventTarget~Event} event + * `mouseup` or `touchend` event that triggered this function. + * + * @listens touchend + * @listens mouseup + * @fires Slider#sliderinactive + */ + + + Slider.prototype.handleMouseUp = function handleMouseUp() { + var doc = this.bar.el_.ownerDocument; + + Dom.unblockTextSelection(); + + this.removeClass('vjs-sliding'); + /** + * Triggered when the slider is no longer in an active state. + * + * @event Slider#sliderinactive + * @type {EventTarget~Event} + */ + this.trigger('sliderinactive'); + + this.off(doc, 'mousemove', this.handleMouseMove); + this.off(doc, 'mouseup', this.handleMouseUp); + this.off(doc, 'touchmove', this.handleMouseMove); + this.off(doc, 'touchend', this.handleMouseUp); + + this.update(); + }; + + /** + * Update the progress bar of the `Slider`. + */ + + + Slider.prototype.update = function update() { + // In VolumeBar init we have a setTimeout for update that pops and update to the end of the + // execution stack. The player is destroyed before then update will cause an error + if (!this.el_) { + return; + } + + // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse. + // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later. + // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration(); + var progress = this.getPercent(); + var bar = this.bar; + + // If there's no bar... + if (!bar) { + return; + } + + // Protect against no duration and other division issues + if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) { + progress = 0; + } + + // Convert to a percentage for setting + var percentage = (progress * 100).toFixed(2) + '%'; + + // Set the new bar width or height + if (this.vertical()) { + bar.el().style.height = percentage; + } else { + bar.el().style.width = percentage; + } + }; + + /** + * Calculate distance for slider + * + * @param {EventTarget~Event} event + * The event that caused this function to run. + * + * @return {number} + * The current position of the Slider. + * - postition.x for vertical `Slider`s + * - postition.y for horizontal `Slider`s + */ + + + Slider.prototype.calculateDistance = function calculateDistance(event) { + var position = Dom.getPointerPosition(this.el_, event); + + if (this.vertical()) { + return position.y; + } + return position.x; + }; + + /** + * Handle a `focus` event on this `Slider`. + * + * @param {EventTarget~Event} event + * The `focus` event that caused this function to run. + * + * @listens focus + */ + + + Slider.prototype.handleFocus = function handleFocus() { + this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); + }; + + /** + * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down + * arrow keys. This function will only be called when the slider has focus. See + * {@link Slider#handleFocus} and {@link Slider#handleBlur}. + * + * @param {EventTarget~Event} event + * the `keydown` event that caused this function to run. + * + * @listens keydown + */ + + + Slider.prototype.handleKeyPress = function handleKeyPress(event) { + // Left and Down Arrows + if (event.which === 37 || event.which === 40) { + event.preventDefault(); + this.stepBack(); + + // Up and Right Arrows + } else if (event.which === 38 || event.which === 39) { + event.preventDefault(); + this.stepForward(); + } + }; + + /** + * Handle a `blur` event on this `Slider`. + * + * @param {EventTarget~Event} event + * The `blur` event that caused this function to run. + * + * @listens blur + */ + + Slider.prototype.handleBlur = function handleBlur() { + this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress); + }; + + /** + * Listener for click events on slider, used to prevent clicks + * from bubbling up to parent elements like button menus. + * + * @param {Object} event + * Event that caused this object to run + */ + + + Slider.prototype.handleClick = function handleClick(event) { + event.stopImmediatePropagation(); + event.preventDefault(); + }; + + /** + * Get/set if slider is horizontal for vertical + * + * @param {boolean} [bool] + * - true if slider is vertical, + * - false is horizontal + * + * @return {boolean|Slider} + * - true if slider is vertical, and getting + * - false is horizontal, and getting + * - a reference to this object when setting + */ + + + Slider.prototype.vertical = function vertical(bool) { + if (bool === undefined) { + return this.vertical_ || false; + } + + this.vertical_ = !!bool; + + if (this.vertical_) { + this.addClass('vjs-slider-vertical'); + } else { + this.addClass('vjs-slider-horizontal'); + } + + return this; + }; + + return Slider; +}(_component2['default']); + +_component2['default'].registerComponent('Slider', Slider); +exports['default'] = Slider; + +},{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +/** + * @file flash-rtmp.js + * @module flash-rtmp + */ + +/** + * Add RTMP properties to the {@link Flash} Tech. + * + * @param {Flash} Flash + * The flash tech class. + * + * @mixin FlashRtmpDecorator + */ +function FlashRtmpDecorator(Flash) { + Flash.streamingFormats = { + 'rtmp/mp4': 'MP4', + 'rtmp/flv': 'FLV' + }; + + /** + * Join connection and stream with an ampersand. + * + * @param {string} connection + * The connection string. + * + * @param {string} stream + * The stream string. + */ + Flash.streamFromParts = function (connection, stream) { + return connection + '&' + stream; + }; + + /** + * The flash parts object that contains connection and stream info. + * + * @typedef {Object} Flash~PartsObject + * + * @property {string} connection + * The connection string of a source, defaults to an empty string. + * + * @property {string} stream + * The stream string of the source, defaults to an empty string. + */ + + /** + * Convert a source url into a stream and connection parts. + * + * @param {string} src + * the source url + * + * @return {Flash~PartsObject} + * The parts object that contains a connection and a stream + */ + Flash.streamToParts = function (src) { + var parts = { + connection: '', + stream: '' + }; + + if (!src) { + return parts; + } + + // Look for the normal URL separator we expect, '&'. + // If found, we split the URL into two pieces around the + // first '&'. + var connEnd = src.search(/&(?!\w+=)/); + var streamBegin = void 0; + + if (connEnd !== -1) { + streamBegin = connEnd + 1; + } else { + // If there's not a '&', we use the last '/' as the delimiter. + connEnd = streamBegin = src.lastIndexOf('/') + 1; + if (connEnd === 0) { + // really, there's not a '/'? + connEnd = streamBegin = src.length; + } + } + + parts.connection = src.substring(0, connEnd); + parts.stream = src.substring(streamBegin, src.length); + + return parts; + }; + + /** + * Check if the source type is a streaming type. + * + * @param {string} srcType + * The mime type to check. + * + * @return {boolean} + * - True if the source type is a streaming type. + * - False if the source type is not a streaming type. + */ + Flash.isStreamingType = function (srcType) { + return srcType in Flash.streamingFormats; + }; + + // RTMP has four variations, any string starting + // with one of these protocols should be valid + + /** + * Regular expression used to check if the source is an rtmp source. + * + * @property {RegExp} Flash.RTMP_RE + */ + Flash.RTMP_RE = /^rtmp[set]?:\/\//i; + + /** + * Check if the source itself is a streaming type. + * + * @param {string} src + * The url to the source. + * + * @return {boolean} + * - True if the source url indicates that the source is streaming. + * - False if the shource url indicates that the source url is not streaming. + */ + Flash.isStreamingSrc = function (src) { + return Flash.RTMP_RE.test(src); + }; + + /** + * A source handler for RTMP urls + * @type {Object} + */ + Flash.rtmpSourceHandler = {}; + + /** + * Check if Flash can play the given mime type. + * + * @param {string} type + * The mime type to check + * + * @return {string} + * 'maybe', or '' (empty string) + */ + Flash.rtmpSourceHandler.canPlayType = function (type) { + if (Flash.isStreamingType(type)) { + return 'maybe'; + } + + return ''; + }; + + /** + * Check if Flash can handle the source natively + * + * @param {Object} source + * The source object + * + * @param {Object} [options] + * The options passed to the tech + * + * @return {string} + * 'maybe', or '' (empty string) + */ + Flash.rtmpSourceHandler.canHandleSource = function (source, options) { + var can = Flash.rtmpSourceHandler.canPlayType(source.type); + + if (can) { + return can; + } + + if (Flash.isStreamingSrc(source.src)) { + return 'maybe'; + } + + return ''; + }; + + /** + * Pass the source to the flash object. + * + * @param {Object} source + * The source object + * + * @param {Flash} tech + * The instance of the Flash tech + * + * @param {Object} [options] + * The options to pass to the source + */ + Flash.rtmpSourceHandler.handleSource = function (source, tech, options) { + var srcParts = Flash.streamToParts(source.src); + + tech.setRtmpConnection(srcParts.connection); + tech.setRtmpStream(srcParts.stream); + }; + + // Register the native source handler + Flash.registerSourceHandler(Flash.rtmpSourceHandler); + + return Flash; +} + +exports['default'] = FlashRtmpDecorator; + +},{}],59:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _tech = _dereq_(62); + +var _tech2 = _interopRequireDefault(_tech); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _url = _dereq_(92); + +var Url = _interopRequireWildcard(_url); + +var _timeRanges = _dereq_(90); + +var _flashRtmp = _dereq_(58); + +var _flashRtmp2 = _interopRequireDefault(_flashRtmp); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _obj = _dereq_(88); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file flash.js + * VideoJS-SWF - Custom Flash Player with HTML5-ish API + * https://github.com/zencoder/video-js-swf + * Not using setupTriggers. Using global onEvent func to distribute events + */ + +var navigator = _window2['default'].navigator; + +/** + * Flash Media Controller - Wrapper for Flash Media API + * + * @mixes FlashRtmpDecorator + * @mixes Tech~SouceHandlerAdditions + * @extends Tech + */ + +var Flash = function (_Tech) { + _inherits(Flash, _Tech); + + /** + * Create an instance of this Tech. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} ready + * Callback function to call when the `Flash` Tech is ready. + */ + function Flash(options, ready) { + _classCallCheck(this, Flash); + + // Set the source when ready + var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); + + if (options.source) { + _this.ready(function () { + this.setSource(options.source); + }, true); + } + + // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers + // This allows resetting the playhead when we catch the reload + if (options.startTime) { + _this.ready(function () { + this.load(); + this.play(); + this.currentTime(options.startTime); + }, true); + } + + // Add global window functions that the swf expects + // A 4.x workflow we weren't able to solve for in 5.0 + // because of the need to hard code these functions + // into the swf for security reasons + _window2['default'].videojs = _window2['default'].videojs || {}; + _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {}; + _window2['default'].videojs.Flash.onReady = Flash.onReady; + _window2['default'].videojs.Flash.onEvent = Flash.onEvent; + _window2['default'].videojs.Flash.onError = Flash.onError; + + _this.on('seeked', function () { + this.lastSeekTarget_ = undefined; + }); + + return _this; + } + + /** + * Create the `Flash` Tech's DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + Flash.prototype.createEl = function createEl() { + var options = this.options_; + + // If video.js is hosted locally you should also set the location + // for the hosted swf, which should be relative to the page (not video.js) + // Otherwise this adds a CDN url. + // The CDN also auto-adds a swf URL for that specific version. + if (!options.swf) { + var ver = '5.1.0'; + + options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf'; + } + + // Generate ID for swf object + var objId = options.techId; + + // Merge default flashvars with ones passed in to init + var flashVars = (0, _obj.assign)({ + + // SWF Callback Functions + readyFunction: 'videojs.Flash.onReady', + eventProxyFunction: 'videojs.Flash.onEvent', + errorEventProxyFunction: 'videojs.Flash.onError', + + // Player Settings + autoplay: options.autoplay, + preload: options.preload, + loop: options.loop, + muted: options.muted + + }, options.flashVars); + + // Merge default parames with ones passed in + var params = (0, _obj.assign)({ + // Opaque is needed to overlay controls, but can affect playback performance + wmode: 'opaque', + // Using bgcolor prevents a white flash when the object is loading + bgcolor: '#000000' + }, options.params); + + // Merge default attributes with ones passed in + var attributes = (0, _obj.assign)({ + // Both ID and Name needed or swf to identify itself + id: objId, + name: objId, + 'class': 'vjs-tech' + }, options.attributes); + + this.el_ = Flash.embed(options.swf, flashVars, params, attributes); + this.el_.tech = this; + + return this.el_; + }; + + /** + * Called by {@link Player#play} to play using the `Flash` `Tech`. + */ + + + Flash.prototype.play = function play() { + if (this.ended()) { + this.setCurrentTime(0); + } + this.el_.vjs_play(); + }; + + /** + * Called by {@link Player#pause} to pause using the `Flash` `Tech`. + */ + + + Flash.prototype.pause = function pause() { + this.el_.vjs_pause(); + }; + + /** + * A getter/setter for the `Flash` Tech's source object. + * > Note: Please use {@link Flash#setSource} + * + * @param {Tech~SourceObject} [src] + * The source object you want to set on the `Flash` techs. + * + * @return {Tech~SourceObject|undefined} + * - The current source object when a source is not passed in. + * - undefined when setting + * + * @deprecated Since version 5. + */ + + + Flash.prototype.src = function src(_src) { + if (_src === undefined) { + return this.currentSrc(); + } + + // Setting src through `src` not `setSrc` will be deprecated + return this.setSrc(_src); + }; + + /** + * A getter/setter for the `Flash` Tech's source object. + * + * @param {Tech~SourceObject} [src] + * The source object you want to set on the `Flash` techs. + * + * @return {Tech~SourceObject|undefined} + * - The current source object when a source is not passed in. + * - undefined when setting + */ + + + Flash.prototype.setSrc = function setSrc(src) { + var _this2 = this; + + // Make sure source URL is absolute. + src = Url.getAbsoluteURL(src); + this.el_.vjs_src(src); + + // Currently the SWF doesn't autoplay if you load a source later. + // e.g. Load player w/ no source, wait 2s, set src. + if (this.autoplay()) { + this.setTimeout(function () { + return _this2.play(); + }, 0); + } + }; + + /** + * Indicates whether the media is currently seeking to a new position or not. + * + * @return {boolean} + * - True if seeking to a new position + * - False otherwise + */ + + + Flash.prototype.seeking = function seeking() { + return this.lastSeekTarget_ !== undefined; + }; + + /** + * Returns the current time in seconds that the media is at in playback. + * + * @param {number} time + * Current playtime of the media in seconds. + */ + + + Flash.prototype.setCurrentTime = function setCurrentTime(time) { + var seekable = this.seekable(); + + if (seekable.length) { + // clamp to the current seekable range + time = time > seekable.start(0) ? time : seekable.start(0); + time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1); + + this.lastSeekTarget_ = time; + this.trigger('seeking'); + this.el_.vjs_setProperty('currentTime', time); + _Tech.prototype.setCurrentTime.call(this); + } + }; + + /** + * Get the current playback time in seconds + * + * @return {number} + * The current time of playback in seconds. + */ + + + Flash.prototype.currentTime = function currentTime() { + // when seeking make the reported time keep up with the requested time + // by reading the time we're seeking to + if (this.seeking()) { + return this.lastSeekTarget_ || 0; + } + return this.el_.vjs_getProperty('currentTime'); + }; + + /** + * Get the current source + * + * @method currentSrc + * @return {Tech~SourceObject} + * The current source + */ + + + Flash.prototype.currentSrc = function currentSrc() { + if (this.currentSource_) { + return this.currentSource_.src; + } + return this.el_.vjs_getProperty('currentSrc'); + }; + + /** + * Get the total duration of the current media. + * + * @return {number} + 8 The total duration of the current media. + */ + + + Flash.prototype.duration = function duration() { + if (this.readyState() === 0) { + return NaN; + } + var duration = this.el_.vjs_getProperty('duration'); + + return duration >= 0 ? duration : Infinity; + }; + + /** + * Load media into Tech. + */ + + + Flash.prototype.load = function load() { + this.el_.vjs_load(); + }; + + /** + * Get the poster image that was set on the tech. + */ + + + Flash.prototype.poster = function poster() { + this.el_.vjs_getProperty('poster'); + }; + + /** + * Poster images are not handled by the Flash tech so make this is a no-op. + */ + + + Flash.prototype.setPoster = function setPoster() {}; + + /** + * Determine the time ranges that can be seeked to in the media. + * + * @return {TimeRange} + * Returns the time ranges that can be seeked to. + */ + + + Flash.prototype.seekable = function seekable() { + var duration = this.duration(); + + if (duration === 0) { + return (0, _timeRanges.createTimeRange)(); + } + return (0, _timeRanges.createTimeRange)(0, duration); + }; + + /** + * Get and create a `TimeRange` object for buffering. + * + * @return {TimeRange} + * The time range object that was created. + */ + + + Flash.prototype.buffered = function buffered() { + var ranges = this.el_.vjs_getProperty('buffered'); + + if (ranges.length === 0) { + return (0, _timeRanges.createTimeRange)(); + } + return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]); + }; + + /** + * Get fullscreen support - + * + * Flash does not allow fullscreen through javascript + * so this always returns false. + * + * @return {boolean} + * The Flash tech does not support fullscreen, so it will always return false. + */ + + + Flash.prototype.supportsFullScreen = function supportsFullScreen() { + // Flash does not allow fullscreen through javascript + return false; + }; + + /** + * Flash does not allow fullscreen through javascript + * so this always returns false. + * + * @return {boolean} + * The Flash tech does not support fullscreen, so it will always return false. + */ + + + Flash.prototype.enterFullScreen = function enterFullScreen() { + return false; + }; + + return Flash; +}(_tech2['default']); + +// Create setters and getters for attributes + + +var _api = Flash.prototype; +var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','); +var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(','); + +function _createSetter(attr) { + var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1); + + _api['set' + attrUpper] = function (val) { + return this.el_.vjs_setProperty(attr, val); + }; +} + +function _createGetter(attr) { + _api[attr] = function () { + return this.el_.vjs_getProperty(attr); + }; +} + +// Create getter and setters for all read/write attributes +for (var i = 0; i < _readWrite.length; i++) { + _createGetter(_readWrite[i]); + _createSetter(_readWrite[i]); +} + +// Create getters for read-only attributes +for (var _i = 0; _i < _readOnly.length; _i++) { + _createGetter(_readOnly[_i]); +} + +/** ------------------------------ Getters ------------------------------ **/ +/** + * Get the value of `rtmpConnection` from the swf. + * + * @method Flash#rtmpConnection + * @return {string} + * The current value of `rtmpConnection` on the swf. + */ + +/** + * Get the value of `rtmpStream` from the swf. + * + * @method Flash#rtmpStream + * @return {string} + * The current value of `rtmpStream` on the swf. + */ + +/** + * Get the value of `preload` from the swf. `preload` indicates + * what should download before the media is interacted with. It can have the following + * values: + * - none: nothing should be downloaded + * - metadata: poster and the first few frames of the media may be downloaded to get + * media dimensions and other metadata + * - auto: allow the media and metadata for the media to be downloaded before + * interaction + * + * @method Flash#preload + * @return {string} + * The value of `preload` from the swf. Will be 'none', 'metadata', + * or 'auto'. + */ + +/** + * Get the value of `defaultPlaybackRate` from the swf. + * + * @method Flash#defaultPlaybackRate + * @return {number} + * The current value of `defaultPlaybackRate` on the swf. + */ + +/** + * Get the value of `playbackRate` from the swf. `playbackRate` indicates + * the rate at which the media is currently playing back. Examples: + * - if playbackRate is set to 2, media will play twice as fast. + * - if playbackRate is set to 0.5, media will play half as fast. + * + * @method Flash#playbackRate + * @return {number} + * The value of `playbackRate` from the swf. A number indicating + * the current playback speed of the media, where 1 is normal speed. + */ + +/** + * Get the value of `autoplay` from the swf. `autoplay` indicates + * that the media should start to play as soon as the page is ready. + * + * @method Flash#autoplay + * @return {boolean} + * - The value of `autoplay` from the swf. + * - True indicates that the media ashould start as soon as the page loads. + * - False indicates that the media should not start as soon as the page loads. + */ + +/** + * Get the value of `loop` from the swf. `loop` indicates + * that the media should return to the start of the media and continue playing once + * it reaches the end. + * + * @method Flash#loop + * @return {boolean} + * - The value of `loop` from the swf. + * - True indicates that playback should seek back to start once + * the end of a media is reached. + * - False indicates that playback should not loop back to the start when the + * end of the media is reached. + */ + +/** + * Get the value of `mediaGroup` from the swf. + * + * @method Flash#mediaGroup + * @return {string} + * The current value of `mediaGroup` on the swf. + */ + +/** + * Get the value of `controller` from the swf. + * + * @method Flash#controller + * @return {string} + * The current value of `controller` on the swf. + */ + +/** + * Get the value of `controls` from the swf. `controls` indicates + * whether the native flash controls should be shown or hidden. + * + * @method Flash#controls + * @return {boolean} + * - The value of `controls` from the swf. + * - True indicates that native controls should be showing. + * - False indicates that native controls should be hidden. + */ + +/** + * Get the value of the `volume` from the swf. `volume` indicates the current + * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and + * so on. + * + * @method Flash#volume + * @return {number} + * The volume percent as a decimal. Value will be between 0-1. + */ + +/** + * Get the value of the `muted` from the swf. `muted` indicates the current + * audio level should be silent. + * + * @method Flash#muted + * @return {boolean} + * - True if the audio should be set to silent + * - False otherwise + */ + +/** + * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates + * whether the media should start muted or not. Only changes the default state of the + * media. `muted` and `defaultMuted` can have different values. `muted` indicates the + * current state. + * + * @method Flash#defaultMuted + * @return {boolean} + * - The value of `defaultMuted` from the swf. + * - True indicates that the media should start muted. + * - False indicates that the media should not start muted. + */ + +/** + * Get the value of `networkState` from the swf. `networkState` indicates + * the current network state. It returns an enumeration from the following list: + * - 0: NETWORK_EMPTY + * - 1: NEWORK_IDLE + * - 2: NETWORK_LOADING + * - 3: NETWORK_NO_SOURCE + * + * @method Flash#networkState + * @return {number} + * The value of `networkState` from the swf. This will be a number + * from the list in the description. + */ + +/** + * Get the value of `readyState` from the swf. `readyState` indicates + * the current state of the media element. It returns an enumeration from the + * following list: + * - 0: HAVE_NOTHING + * - 1: HAVE_METADATA + * - 2: HAVE_CURRENT_DATA + * - 3: HAVE_FUTURE_DATA + * - 4: HAVE_ENOUGH_DATA + * + * @method Flash#readyState + * @return {number} + * The value of `readyState` from the swf. This will be a number + * from the list in the description. + */ + +/** + * Get the value of `readyState` from the swf. `readyState` indicates + * the current state of the media element. It returns an enumeration from the + * following list: + * - 0: HAVE_NOTHING + * - 1: HAVE_METADATA + * - 2: HAVE_CURRENT_DATA + * - 3: HAVE_FUTURE_DATA + * - 4: HAVE_ENOUGH_DATA + * + * @method Flash#readyState + * @return {number} + * The value of `readyState` from the swf. This will be a number + * from the list in the description. + */ + +/** + * Get the value of `initialTime` from the swf. + * + * @method Flash#initialTime + * @return {number} + * The `initialTime` proprety on the swf. + */ + +/** + * Get the value of `startOffsetTime` from the swf. + * + * @method Flash#startOffsetTime + * @return {number} + * The `startOffsetTime` proprety on the swf. + */ + +/** + * Get the value of `paused` from the swf. `paused` indicates whether the swf + * is current paused or not. + * + * @method Flash#paused + * @return {boolean} + * The value of `paused` from the swf. + */ + +/** + * Get the value of `ended` from the swf. `ended` indicates whether + * the media has reached the end or not. + * + * @method Flash#ended + * @return {boolean} + * - True indicates that the media has ended. + * - False indicates that the media has not ended. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} + */ + +/** + * Get the value of `videoWidth` from the swf. `videoWidth` indicates + * the current width of the media in css pixels. + * + * @method Flash#videoWidth + * @return {number} + * The value of `videoWidth` from the swf. This will be a number + * in css pixels. + */ + +/** + * Get the value of `videoHeight` from the swf. `videoHeigth` indicates + * the current height of the media in css pixels. + * + * @method Flassh.prototype.videoHeight + * @return {number} + * The value of `videoHeight` from the swf. This will be a number + * in css pixels. + */ +/** ------------------------------ Setters ------------------------------ **/ + +/** + * Set the value of `rtmpConnection` on the swf. + * + * @method Flash#setRtmpConnection + * @param {string} rtmpConnection + * New value to set the `rtmpConnection` property to. + */ + +/** + * Set the value of `rtmpStream` on the swf. + * + * @method Flash#setRtmpStream + * @param {string} rtmpStream + * New value to set the `rtmpStream` property to. + */ + +/** + * Set the value of `preload` on the swf. `preload` indicates + * what should download before the media is interacted with. It can have the following + * values: + * - none: nothing should be downloaded + * - metadata: poster and the first few frames of the media may be downloaded to get + * media dimensions and other metadata + * - auto: allow the media and metadata for the media to be downloaded before + * interaction + * + * @method Flash#setPreload + * @param {string} preload + * The value of `preload` to set on the swf. Should be 'none', 'metadata', + * or 'auto'. + */ + +/** + * Set the value of `defaultPlaybackRate` on the swf. + * + * @method Flash#setDefaultPlaybackRate + * @param {number} defaultPlaybackRate + * New value to set the `defaultPlaybackRate` property to. + */ + +/** + * Set the value of `playbackRate` on the swf. `playbackRate` indicates + * the rate at which the media is currently playing back. Examples: + * - if playbackRate is set to 2, media will play twice as fast. + * - if playbackRate is set to 0.5, media will play half as fast. + * + * @method Flash#setPlaybackRate + * @param {number} playbackRate + * New value of `playbackRate` on the swf. A number indicating + * the current playback speed of the media, where 1 is normal speed. + */ + +/** + * Set the value of `autoplay` on the swf. `autoplay` indicates + * that the media should start to play as soon as the page is ready. + * + * @method Flash#setAutoplay + * @param {boolean} autoplay + * - The value of `autoplay` from the swf. + * - True indicates that the media ashould start as soon as the page loads. + * - False indicates that the media should not start as soon as the page loads. + */ + +/** + * Set the value of `loop` on the swf. `loop` indicates + * that the media should return to the start of the media and continue playing once + * it reaches the end. + * + * @method Flash#setLoop + * @param {boolean} loop + * - True indicates that playback should seek back to start once + * the end of a media is reached. + * - False indicates that playback should not loop back to the start when the + * end of the media is reached. + */ + +/** + * Set the value of `mediaGroup` on the swf. + * + * @method Flash#setMediaGroup + * @param {string} mediaGroup + * New value of `mediaGroup` to set on the swf. + */ + +/** + * Set the value of `controller` on the swf. + * + * @method Flash#setController + * @param {string} controller + * New value the current value of `controller` on the swf. + */ + +/** + * Get the value of `controls` from the swf. `controls` indicates + * whether the native flash controls should be shown or hidden. + * + * @method Flash#controls + * @return {boolean} + * - The value of `controls` from the swf. + * - True indicates that native controls should be showing. + * - False indicates that native controls should be hidden. + */ + +/** + * Set the value of the `volume` on the swf. `volume` indicates the current + * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and + * so on. + * + * @method Flash#setVolume + * @param {number} percentAsDecimal + * The volume percent as a decimal. Value will be between 0-1. + */ + +/** + * Set the value of the `muted` on the swf. `muted` indicates that the current + * audio level should be silent. + * + * @method Flash#setMuted + * @param {boolean} muted + * - True if the audio should be set to silent + * - False otherwise + */ + +/** + * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates + * whether the media should start muted or not. Only changes the default state of the + * media. `muted` and `defaultMuted` can have different values. `muted` indicates the + * current state. + * + * @method Flash#setDefaultMuted + * @param {boolean} defaultMuted + * - True indicates that the media should start muted. + * - False indicates that the media should not start muted. + */ + +/* Flash Support Testing -------------------------------------------------------- */ + +/** + * Check if the Flash tech is currently supported. + * + * @return {boolean} + * - True if the flash tech is supported. + * - False otherwise. + */ +Flash.isSupported = function () { + return Flash.version()[0] >= 10; + // return swfobject.hasFlashPlayerVersion('10'); +}; + +// Add Source Handler pattern functions to this tech +_tech2['default'].withSourceHandlers(Flash); + +/* + * Native source handler for flash, simply passes the source to the swf element. + * + * @property {Tech~SourceObject} source + * The source object + * + * @property {Flash} tech + * The instance of the Flash tech + */ +Flash.nativeSourceHandler = {}; + +/** + * Check if the Flash can play the given mime type. + * + * @param {string} type + * The mimetype to check + * + * @return {string} + * 'maybe', or '' (empty string) + */ +Flash.nativeSourceHandler.canPlayType = function (type) { + if (type in Flash.formats) { + return 'maybe'; + } + + return ''; +}; + +/** + * Check if the media element can handle a source natively. + * + * @param {Tech~SourceObject} source + * The source object + * + * @param {Object} [options] + * Options to be passed to the tech. + * + * @return {string} + * 'maybe', or '' (empty string). + */ +Flash.nativeSourceHandler.canHandleSource = function (source, options) { + var type = void 0; + + function guessMimeType(src) { + var ext = Url.getFileExtension(src); + + if (ext) { + return 'video/' + ext; + } + return ''; + } + + if (!source.type) { + type = guessMimeType(source.src); + } else { + // Strip code information from the type because we don't get that specific + type = source.type.replace(/;.*/, '').toLowerCase(); + } + + return Flash.nativeSourceHandler.canPlayType(type); +}; + +/** + * Pass the source to the swf. + * + * @param {Tech~SourceObject} source + * The source object + * + * @param {Flash} tech + * The instance of the Flash tech + * + * @param {Object} [options] + * The options to pass to the source + */ +Flash.nativeSourceHandler.handleSource = function (source, tech, options) { + tech.setSrc(source.src); +}; + +/** + * noop for native source handler dispose, as cleanup will happen automatically. + */ +Flash.nativeSourceHandler.dispose = function () {}; + +// Register the native source handler +Flash.registerSourceHandler(Flash.nativeSourceHandler); + +/** + * Flash supported mime types. + * + * @constant {Object} + */ +Flash.formats = { + 'video/flv': 'FLV', + 'video/x-flv': 'FLV', + 'video/mp4': 'MP4', + 'video/m4v': 'MP4' +}; + +/** + * Called when the the swf is "ready", and makes sure that the swf is really + * ready using {@link Flash#checkReady} + */ +Flash.onReady = function (currSwf) { + var el = Dom.getEl(currSwf); + var tech = el && el.tech; + + // if there is no el then the tech has been disposed + // and the tech element was removed from the player div + if (tech && tech.el()) { + // check that the flash object is really ready + Flash.checkReady(tech); + } +}; + +/** + * The SWF isn't always ready when it says it is. Sometimes the API functions still + * need to be added to the object. If it's not ready, we set a timeout to check again + * shortly. + * + * @param {Flash} tech + * The instance of the flash tech to check. + */ +Flash.checkReady = function (tech) { + // stop worrying if the tech has been disposed + if (!tech.el()) { + return; + } + + // check if API property exists + if (tech.el().vjs_getProperty) { + // tell tech it's ready + tech.triggerReady(); + } else { + // wait longer + this.setTimeout(function () { + Flash.checkReady(tech); + }, 50); + } +}; + +/** + * Trigger events from the swf on the Flash Tech. + * + * @param {number} swfID + * The id of the swf that had the event + * + * @param {string} eventName + * The name of the event to trigger + */ +Flash.onEvent = function (swfID, eventName) { + var tech = Dom.getEl(swfID).tech; + var args = Array.prototype.slice.call(arguments, 2); + + // dispatch Flash events asynchronously for two reasons: + // - Flash swallows any exceptions generated by javascript it + // invokes + // - Flash is suspended until the javascript returns which may cause + // playback performance issues + tech.setTimeout(function () { + tech.trigger(eventName, args); + }, 1); +}; + +/** + * Log errors from the swf on the Flash tech. + * + * @param {number} swfID + * The id of the swf that had an error. + * + * @param {string} The error string + * The error to set on the Flash Tech. + * + * @return {MediaError|undefined} + * - Returns a MediaError when err is 'srcnotfound' + * - Returns undefined otherwise. + */ +Flash.onError = function (swfID, err) { + var tech = Dom.getEl(swfID).tech; + + // trigger MEDIA_ERR_SRC_NOT_SUPPORTED + if (err === 'srcnotfound') { + return tech.error(4); + } + + // trigger a custom error + tech.error('FLASH: ' + err); +}; + +/** + * Get the current version of Flash that is in use on the page. + * + * @return {Array} + * an array of versions that are available. + */ +Flash.version = function () { + var version = '0,0,0'; + + // IE + try { + version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; + + // other browsers + } catch (e) { + try { + if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { + version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; + } + } catch (err) { + // satisfy linter + } + } + return version.split(','); +}; + +/** + * Only use for non-iframe embeds. + * + * @param {Object} swf + * The videojs-swf object. + * + * @param {Object} flashVars + * Names and values to use as flash option variables. + * + * @param {Object} params + * Style parameters to set on the object. + * + * @param {Object} attributes + * Attributes to set on the element. + * + * @return {Element} + * The embeded Flash DOM element. + */ +Flash.embed = function (swf, flashVars, params, attributes) { + var code = Flash.getEmbedCode(swf, flashVars, params, attributes); + + // Get element by embedding code and retrieving created element + var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0]; + + return obj; +}; + +/** + * Only use for non-iframe embeds. + * + * @param {Object} swf + * The videojs-swf object. + * + * @param {Object} flashVars + * Names and values to use as flash option variables. + * + * @param {Object} params + * Style parameters to set on the object. + * + * @param {Object} attributes + * Attributes to set on the element. + * + * @return {Element} + * The embeded Flash DOM element. + */ +Flash.getEmbedCode = function (swf, flashVars, params, attributes) { + var objTag = '<object type="application/x-shockwave-flash" '; + var flashVarsString = ''; + var paramsString = ''; + var attrsString = ''; + + // Convert flash vars to string + if (flashVars) { + Object.getOwnPropertyNames(flashVars).forEach(function (key) { + flashVarsString += key + '=' + flashVars[key] + '&'; + }); + } + + // Add swf, flashVars, and other default params + params = (0, _obj.assign)({ + movie: swf, + flashvars: flashVarsString, + // Required to talk to swf + allowScriptAccess: 'always', + // All should be default, but having security issues. + allowNetworking: 'all' + }, params); + + // Create param tags string + Object.getOwnPropertyNames(params).forEach(function (key) { + paramsString += '<param name="' + key + '" value="' + params[key] + '" />'; + }); + + attributes = (0, _obj.assign)({ + // Add swf to attributes (need both for IE and Others to work) + data: swf, + + // Default to 100% width/height + width: '100%', + height: '100%' + + }, attributes); + + // Create Attributes string + Object.getOwnPropertyNames(attributes).forEach(function (key) { + attrsString += key + '="' + attributes[key] + '" '; + }); + + return '' + objTag + attrsString + '>' + paramsString + '</object>'; +}; + +// Run Flash through the RTMP decorator +(0, _flashRtmp2['default'])(Flash); + +_component2['default'].registerComponent('Flash', Flash); +_tech2['default'].registerTech('Flash', Flash); +exports['default'] = Flash; + +},{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _templateObject = _taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.']); + +var _tech = _dereq_(62); + +var _tech2 = _interopRequireDefault(_tech); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _url = _dereq_(92); + +var Url = _interopRequireWildcard(_url); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _tsml = _dereq_(98); + +var _tsml2 = _interopRequireDefault(_tsml); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _obj = _dereq_(88); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file html5.js + */ + + +/** + * HTML5 Media Controller - Wrapper for HTML5 Media API + * + * @mixes Tech~SouceHandlerAdditions + * @extends Tech + */ +var Html5 = function (_Tech) { + _inherits(Html5, _Tech); + + /** + * Create an instance of this Tech. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} ready + * Callback function to call when the `HTML5` Tech is ready. + */ + function Html5(options, ready) { + _classCallCheck(this, Html5); + + var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready)); + + var source = options.source; + var crossoriginTracks = false; + + // Set the source if one is provided + // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted) + // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source + // anyway so the error gets fired. + if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) { + _this.setSource(source); + } else { + _this.handleLateInit_(_this.el_); + } + + if (_this.el_.hasChildNodes()) { + + var nodes = _this.el_.childNodes; + var nodesLength = nodes.length; + var removeNodes = []; + + while (nodesLength--) { + var node = nodes[nodesLength]; + var nodeName = node.nodeName.toLowerCase(); + + if (nodeName === 'track') { + if (!_this.featuresNativeTextTracks) { + // Empty video tag tracks so the built-in player doesn't use them also. + // This may not be fast enough to stop HTML5 browsers from reading the tags + // so we'll need to turn off any default tracks if we're manually doing + // captions and subtitles. videoElement.textTracks + removeNodes.push(node); + } else { + // store HTMLTrackElement and TextTrack to remote list + _this.remoteTextTrackEls().addTrackElement_(node); + _this.remoteTextTracks().addTrack_(node.track); + if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) { + crossoriginTracks = true; + } + } + } + } + + for (var i = 0; i < removeNodes.length; i++) { + _this.el_.removeChild(removeNodes[i]); + } + } + + // TODO: add text tracks into this list + var trackTypes = ['audio', 'video']; + + // ProxyNative Video/Audio Track + trackTypes.forEach(function (type) { + var elTracks = _this.el()[type + 'Tracks']; + var techTracks = _this[type + 'Tracks'](); + var capitalType = (0, _toTitleCase2['default'])(type); + + if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) { + return; + } + + _this['handle' + capitalType + 'TrackChange_'] = function (e) { + techTracks.trigger({ + type: 'change', + target: techTracks, + currentTarget: techTracks, + srcElement: techTracks + }); + }; + + _this['handle' + capitalType + 'TrackAdd_'] = function (e) { + return techTracks.addTrack(e.track); + }; + _this['handle' + capitalType + 'TrackRemove_'] = function (e) { + return techTracks.removeTrack(e.track); + }; + + elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']); + elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']); + elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']); + _this['removeOld' + capitalType + 'Tracks_'] = function (e) { + return _this.removeOldTracks_(techTracks, elTracks); + }; + + // Remove (native) tracks that are not used anymore + _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']); + }); + + if (_this.featuresNativeTextTracks) { + if (crossoriginTracks) { + _log2['default'].warn((0, _tsml2['default'])(_templateObject)); + } + + _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange); + _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd); + _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove); + _this.proxyNativeTextTracks_(); + } + + // Determine if native controls should be used + // Our goal should be to get the custom controls on mobile solid everywhere + // so we can remove this all together. Right now this will block custom + // controls on touch enabled laptops like the Chrome Pixel + if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) { + _this.setControls(true); + } + + // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen` + // into a `fullscreenchange` event + _this.proxyWebkitFullscreen_(); + + _this.triggerReady(); + return _this; + } + + /** + * Dispose of `HTML5` media element and remove all tracks. + */ + + + Html5.prototype.dispose = function dispose() { + var _this2 = this; + + // Un-ProxyNativeTracks + ['audio', 'video', 'text'].forEach(function (type) { + var capitalType = (0, _toTitleCase2['default'])(type); + var tl = _this2.el_[type + 'Tracks']; + + if (tl && tl.removeEventListener) { + tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']); + tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']); + tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']); + } + + // Stop removing old text tracks + if (tl) { + _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']); + } + }); + + Html5.disposeMediaElement(this.el_); + // tech will handle clearing of the emulated track list + _Tech.prototype.dispose.call(this); + }; + + /** + * Create the `Html5` Tech's DOM element. + * + * @return {Element} + * The element that gets created. + */ + + + Html5.prototype.createEl = function createEl() { + var el = this.options_.tag; + + // Check if this browser supports moving the element into the box. + // On the iPhone video will break if you move the element, + // So we have to create a brand new element. + // If we ingested the player div, we do not need to move the media element. + if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) { + + // If the original tag is still there, clone and remove it. + if (el) { + var clone = el.cloneNode(true); + + if (el.parentNode) { + el.parentNode.insertBefore(clone, el); + } + Html5.disposeMediaElement(el); + el = clone; + } else { + el = _document2['default'].createElement('video'); + + // determine if native controls should be used + var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag); + var attributes = (0, _mergeOptions2['default'])({}, tagAttributes); + + if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) { + delete attributes.controls; + } + + Dom.setElAttributes(el, (0, _obj.assign)(attributes, { + id: this.options_.techId, + 'class': 'vjs-tech' + })); + } + + el.playerId = this.options_.playerId; + } + + // Update specific tag settings, in case they were overridden + var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted']; + + for (var i = settingsAttrs.length - 1; i >= 0; i--) { + var attr = settingsAttrs[i]; + var overwriteAttrs = {}; + + if (typeof this.options_[attr] !== 'undefined') { + overwriteAttrs[attr] = this.options_[attr]; + } + Dom.setElAttributes(el, overwriteAttrs); + } + + return el; + }; + + /** + * This will be triggered if the loadstart event has already fired, before videojs was + * ready. Two known examples of when this can happen are: + * 1. If we're loading the playback object after it has started loading + * 2. The media is already playing the (often with autoplay on) then + * + * This function will fire another loadstart so that videojs can catchup. + * + * @fires Tech#loadstart + * + * @return {undefined} + * returns nothing. + */ + + + Html5.prototype.handleLateInit_ = function handleLateInit_(el) { + var _this3 = this; + + if (el.networkState === 0 || el.networkState === 3) { + // The video element hasn't started loading the source yet + // or didn't find a source + return; + } + + if (el.readyState === 0) { + var _ret = function () { + // NetworkState is set synchronously BUT loadstart is fired at the + // end of the current stack, usually before setInterval(fn, 0). + // So at this point we know loadstart may have already fired or is + // about to fire, and either way the player hasn't seen it yet. + // We don't want to fire loadstart prematurely here and cause a + // double loadstart so we'll wait and see if it happens between now + // and the next loop, and fire it if not. + // HOWEVER, we also want to make sure it fires before loadedmetadata + // which could also happen between now and the next loop, so we'll + // watch for that also. + var loadstartFired = false; + var setLoadstartFired = function setLoadstartFired() { + loadstartFired = true; + }; + + _this3.on('loadstart', setLoadstartFired); + + var triggerLoadstart = function triggerLoadstart() { + // We did miss the original loadstart. Make sure the player + // sees loadstart before loadedmetadata + if (!loadstartFired) { + this.trigger('loadstart'); + } + }; + + _this3.on('loadedmetadata', triggerLoadstart); + + _this3.ready(function () { + this.off('loadstart', setLoadstartFired); + this.off('loadedmetadata', triggerLoadstart); + + if (!loadstartFired) { + // We did miss the original native loadstart. Fire it now. + this.trigger('loadstart'); + } + }); + + return { + v: void 0 + }; + }(); + + if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; + } + + // From here on we know that loadstart already fired and we missed it. + // The other readyState events aren't as much of a problem if we double + // them, so not going to go to as much trouble as loadstart to prevent + // that unless we find reason to. + var eventsToTrigger = ['loadstart']; + + // loadedmetadata: newly equal to HAVE_METADATA (1) or greater + eventsToTrigger.push('loadedmetadata'); + + // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater + if (el.readyState >= 2) { + eventsToTrigger.push('loadeddata'); + } + + // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater + if (el.readyState >= 3) { + eventsToTrigger.push('canplay'); + } + + // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4) + if (el.readyState >= 4) { + eventsToTrigger.push('canplaythrough'); + } + + // We still need to give the player time to add event listeners + this.ready(function () { + eventsToTrigger.forEach(function (type) { + this.trigger(type); + }, this); + }); + }; + + /** + * Add event listeners to native text track events. This adds the native text tracks + * to our emulated {@link TextTrackList}. + */ + + + Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() { + var tt = this.el().textTracks; + + if (tt) { + // Add tracks - if player is initialised after DOM loaded, textTracks + // will not trigger addtrack + for (var i = 0; i < tt.length; i++) { + this.textTracks().addTrack_(tt[i]); + } + + if (tt.addEventListener) { + tt.addEventListener('change', this.handleTextTrackChange_); + tt.addEventListener('addtrack', this.handleTextTrackAdd_); + tt.addEventListener('removetrack', this.handleTextTrackRemove_); + } + + // Remove (native) texttracks that are not used anymore + this.on('loadstart', this.removeOldTextTracks_); + } + }; + + /** + * Handle any {@link TextTrackList} `change` event. + * + * @param {EventTarget~Event} e + * The `change` event that caused this to run. + * + * @listens TextTrackList#change + */ + + + Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) { + var tt = this.textTracks(); + + this.textTracks().trigger({ + type: 'change', + target: tt, + currentTarget: tt, + srcElement: tt + }); + }; + + /** + * Handle any {@link TextTrackList} `addtrack` event. + * + * @param {EventTarget~Event} e + * The `addtrack` event that caused this to run. + * + * @listens TextTrackList#addtrack + */ + + + Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) { + this.textTracks().addTrack_(e.track); + }; + + /** + * Handle any {@link TextTrackList} `removetrack` event. + * + * @param {EventTarget~Event} e + * The `removetrack` event that caused this to run. + * + * @listens TextTrackList#removetrack + */ + + + Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) { + this.textTracks().removeTrack_(e.track); + }; + + /** + * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or + * {@link TextTrack}s that are not in the media elements TrackList. + * + * @param {TrackList} techTracks + * HTML5 Tech's TrackList to search through + * + * @param {TrackList} elTracks + * HTML5 media elements TrackList to search trough. + * + * @private + */ + + + Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) { + // This will loop over the techTracks and check if they are still used by the HTML5 media element + // If not, they will be removed from the emulated list + var removeTracks = []; + + if (!elTracks) { + return; + } + + for (var i = 0; i < techTracks.length; i++) { + var techTrack = techTracks[i]; + var found = false; + + for (var j = 0; j < elTracks.length; j++) { + if (elTracks[j] === techTrack) { + found = true; + break; + } + } + + if (!found) { + removeTracks.push(techTrack); + } + } + + for (var _i = 0; _i < removeTracks.length; _i++) { + var track = removeTracks[_i]; + + techTracks.removeTrack_(track); + } + }; + + /** + * Remove {@link TextTrack}s that dont exist in the native track list from our + * emulated {@link TextTrackList}. + * + * @listens Tech#loadstart + */ + + + Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) { + var techTracks = this.textTracks(); + var elTracks = this.el().textTracks; + + this.removeOldTracks_(techTracks, elTracks); + }; + + /** + * Called by {@link Player#play} to play using the `Html5` `Tech`. + */ + + + Html5.prototype.play = function play() { + var playPromise = this.el_.play(); + + // Catch/silence error when a pause interrupts a play request + // on browsers which return a promise + if (playPromise !== undefined && typeof playPromise.then === 'function') { + playPromise.then(null, function (e) {}); + } + }; + + /** + * Set current time for the `HTML5` tech. + * + * @param {number} seconds + * Set the current time of the media to this. + */ + + + Html5.prototype.setCurrentTime = function setCurrentTime(seconds) { + try { + this.el_.currentTime = seconds; + } catch (e) { + (0, _log2['default'])(e, 'Video is not ready. (Video.js)'); + // this.warning(VideoJS.warnings.videoNotReady); + } + }; + + /** + * Get the current duration of the HTML5 media element. + * + * @return {number} + * The duration of the media or 0 if there is no duration. + */ + + + Html5.prototype.duration = function duration() { + var _this4 = this; + + // Android Chrome will report duration as Infinity for VOD HLS until after + // playback has started, which triggers the live display erroneously. + // Return NaN if playback has not started and trigger a durationupdate once + // the duration can be reliably known. + if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) { + if (this.el_.currentTime === 0) { + var _ret2 = function () { + // Wait for the first `timeupdate` with currentTime > 0 - there may be + // several with 0 + var checkProgress = function checkProgress() { + if (_this4.el_.currentTime > 0) { + // Trigger durationchange for genuinely live video + if (_this4.el_.duration === Infinity) { + _this4.trigger('durationchange'); + } + _this4.off('timeupdate', checkProgress); + } + }; + + _this4.on('timeupdate', checkProgress); + return { + v: NaN + }; + }(); + + if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v; + } + } + return this.el_.duration || NaN; + }; + + /** + * Get the current width of the HTML5 media element. + * + * @return {number} + * The width of the HTML5 media element. + */ + + + Html5.prototype.width = function width() { + return this.el_.offsetWidth; + }; + + /** + * Get the current height of the HTML5 media element. + * + * @return {number} + * The heigth of the HTML5 media element. + */ + + + Html5.prototype.height = function height() { + return this.el_.offsetHeight; + }; + + /** + * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into + * `fullscreenchange` event. + * + * @private + * @fires fullscreenchange + * @listens webkitendfullscreen + * @listens webkitbeginfullscreen + * @listens webkitbeginfullscreen + */ + + + Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() { + var _this5 = this; + + if (!('webkitDisplayingFullscreen' in this.el_)) { + return; + } + + var endFn = function endFn() { + this.trigger('fullscreenchange', { isFullscreen: false }); + }; + + var beginFn = function beginFn() { + this.one('webkitendfullscreen', endFn); + + this.trigger('fullscreenchange', { isFullscreen: true }); + }; + + this.on('webkitbeginfullscreen', beginFn); + this.on('dispose', function () { + _this5.off('webkitbeginfullscreen', beginFn); + _this5.off('webkitendfullscreen', endFn); + }); + }; + + /** + * Check if fullscreen is supported on the current playback device. + * + * @return {boolean} + * - True if fullscreen is supported. + * - False if fullscreen is not supported. + */ + + + Html5.prototype.supportsFullScreen = function supportsFullScreen() { + if (typeof this.el_.webkitEnterFullScreen === 'function') { + var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; + + // Seems to be broken in Chromium/Chrome && Safari in Leopard + if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) { + return true; + } + } + return false; + }; + + /** + * Request that the `HTML5` Tech enter fullscreen. + */ + + + Html5.prototype.enterFullScreen = function enterFullScreen() { + var video = this.el_; + + if (video.paused && video.networkState <= video.HAVE_METADATA) { + // attempt to prime the video element for programmatic access + // this isn't necessary on the desktop but shouldn't hurt + this.el_.play(); + + // playing and pausing synchronously during the transition to fullscreen + // can get iOS ~6.1 devices into a play/pause loop + this.setTimeout(function () { + video.pause(); + video.webkitEnterFullScreen(); + }, 0); + } else { + video.webkitEnterFullScreen(); + } + }; + + /** + * Request that the `HTML5` Tech exit fullscreen. + */ + + + Html5.prototype.exitFullScreen = function exitFullScreen() { + this.el_.webkitExitFullScreen(); + }; + + /** + * A getter/setter for the `Html5` Tech's source object. + * > Note: Please use {@link Html5#setSource} + * + * @param {Tech~SourceObject} [src] + * The source object you want to set on the `HTML5` techs element. + * + * @return {Tech~SourceObject|undefined} + * - The current source object when a source is not passed in. + * - undefined when setting + * + * @deprecated Since version 5. + */ + + + Html5.prototype.src = function src(_src) { + if (_src === undefined) { + return this.el_.src; + } + + // Setting src through `src` instead of `setSrc` will be deprecated + this.setSrc(_src); + }; + + /** + * Reset the tech by removing all sources and then calling + * {@link Html5.resetMediaElement}. + */ + + + Html5.prototype.reset = function reset() { + Html5.resetMediaElement(this.el_); + }; + + /** + * Get the current source on the `HTML5` Tech. Falls back to returning the source from + * the HTML5 media element. + * + * @return {Tech~SourceObject} + * The current source object from the HTML5 tech. With a fallback to the + * elements source. + */ + + + Html5.prototype.currentSrc = function currentSrc() { + if (this.currentSource_) { + return this.currentSource_.src; + } + return this.el_.currentSrc; + }; + + /** + * Set controls attribute for the HTML5 media Element. + * + * @param {string} val + * Value to set the controls attribute to + */ + + + Html5.prototype.setControls = function setControls(val) { + this.el_.controls = !!val; + }; + + /** + * Create and returns a remote {@link TextTrack} object. + * + * @param {string} kind + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) + * + * @param {string} [label] + * Label to identify the text track + * + * @param {string} [language] + * Two letter language abbreviation + * + * @return {TextTrack} + * The TextTrack that gets created. + */ + + + Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) { + if (!this.featuresNativeTextTracks) { + return _Tech.prototype.addTextTrack.call(this, kind, label, language); + } + + return this.el_.addTextTrack(kind, label, language); + }; + + /** + * Creates either native TextTrack or an emulated TextTrack depending + * on the value of `featuresNativeTextTracks` + * + * @param {Object} options + * The object should contain the options to intialize the TextTrack with. + * + * @param {string} [options.kind] + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). + * + * @param {string} [options.label]. + * Label to identify the text track + * + * @param {string} [options.language] + * Two letter language abbreviation. + * + * @param {boolean} [options.default] + * Default this track to on. + * + * @param {string} [options.id] + * The internal id to assign this track. + * + * @param {string} [options.src] + * A source url for the track. + * + * @return {HTMLTrackElement} + * The track element that gets created. + */ + + + Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { + if (!this.featuresNativeTextTracks) { + return _Tech.prototype.createRemoteTextTrack.call(this, options); + } + var htmlTrackElement = _document2['default'].createElement('track'); + + if (options.kind) { + htmlTrackElement.kind = options.kind; + } + if (options.label) { + htmlTrackElement.label = options.label; + } + if (options.language || options.srclang) { + htmlTrackElement.srclang = options.language || options.srclang; + } + if (options['default']) { + htmlTrackElement['default'] = options['default']; + } + if (options.id) { + htmlTrackElement.id = options.id; + } + if (options.src) { + htmlTrackElement.src = options.src; + } + + return htmlTrackElement; + }; + + /** + * Creates a remote text track object and returns an html track element. + * + * @param {Object} options The object should contain values for + * kind, language, label, and src (location of the WebVTT file) + * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be + * automatically removed from the video element whenever the source changes + * @return {HTMLTrackElement} An Html Track Element. + * This can be an emulated {@link HTMLTrackElement} or a native one. + * @deprecated The default value of the "manualCleanup" parameter will default + * to "false" in upcoming versions of Video.js + */ + + + Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { + var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup); + + if (this.featuresNativeTextTracks) { + this.el().appendChild(htmlTrackElement); + } + + return htmlTrackElement; + }; + + /** + * Remove remote `TextTrack` from `TextTrackList` object + * + * @param {TextTrack} track + * `TextTrack` object to remove + */ + + + Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { + _Tech.prototype.removeRemoteTextTrack.call(this, track); + + if (this.featuresNativeTextTracks) { + var tracks = this.$$('track'); + + var i = tracks.length; + + while (i--) { + if (track === tracks[i] || track === tracks[i].track) { + this.el().removeChild(tracks[i]); + } + } + } + }; + + return Html5; +}(_tech2['default']); + +/* HTML5 Support Testing ---------------------------------------------------- */ + +if (Dom.isReal()) { + + /** + * Element for testing browser HTML5 media capabilities + * + * @type {Element} + * @constant + * @private + */ + Html5.TEST_VID = _document2['default'].createElement('video'); + var track = _document2['default'].createElement('track'); + + track.kind = 'captions'; + track.srclang = 'en'; + track.label = 'English'; + Html5.TEST_VID.appendChild(track); +} + +/** + * Check if HTML5 media is supported by this browser/device. + * + * @return {boolean} + * - True if HTML5 media is supported. + * - False if HTML5 media is not supported. + */ +Html5.isSupported = function () { + // IE9 with no Media Player is a LIAR! (#984) + try { + Html5.TEST_VID.volume = 0.5; + } catch (e) { + return false; + } + + return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType); +}; + +/** + * Check if the volume can be changed in this browser/device. + * Volume cannot be changed in a lot of mobile devices. + * Specifically, it can't be changed from 1 on iOS. + * + * @return {boolean} + * - True if volume can be controlled + * - False otherwise + */ +Html5.canControlVolume = function () { + // IE will error if Windows Media Player not installed #3315 + try { + var volume = Html5.TEST_VID.volume; + + Html5.TEST_VID.volume = volume / 2 + 0.1; + return volume !== Html5.TEST_VID.volume; + } catch (e) { + return false; + } +}; + +/** + * Check if the playback rate can be changed in this browser/device. + * + * @return {boolean} + * - True if playback rate can be controlled + * - False otherwise + */ +Html5.canControlPlaybackRate = function () { + // Playback rate API is implemented in Android Chrome, but doesn't do anything + // https://github.com/videojs/video.js/issues/3180 + if (browser.IS_ANDROID && browser.IS_CHROME) { + return false; + } + // IE will error if Windows Media Player not installed #3315 + try { + var playbackRate = Html5.TEST_VID.playbackRate; + + Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1; + return playbackRate !== Html5.TEST_VID.playbackRate; + } catch (e) { + return false; + } +}; + +/** + * Check to see if native `TextTrack`s are supported by this browser/device. + * + * @return {boolean} + * - True if native `TextTrack`s are supported. + * - False otherwise + */ +Html5.supportsNativeTextTracks = function () { + return browser.IS_ANY_SAFARI; +}; + +/** + * Check to see if native `VideoTrack`s are supported by this browser/device + * + * @return {boolean} + * - True if native `VideoTrack`s are supported. + * - False otherwise + */ +Html5.supportsNativeVideoTracks = function () { + return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks); +}; + +/** + * Check to see if native `AudioTrack`s are supported by this browser/device + * + * @return {boolean} + * - True if native `AudioTrack`s are supported. + * - False otherwise + */ +Html5.supportsNativeAudioTracks = function () { + return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks); +}; + +/** + * An array of events available on the Html5 tech. + * + * @private + * @type {Array} + */ +Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange']; + +/** + * Boolean indicating whether the `Tech` supports volume control. + * + * @type {boolean} + * @default {@link Html5.canControlVolume} + */ +Html5.prototype.featuresVolumeControl = Html5.canControlVolume(); + +/** + * Boolean indicating whether the `Tech` supports changing the speed at which the media + * plays. Examples: + * - Set player to play 2x (twice) as fast + * - Set player to play 0.5x (half) as fast + * + * @type {boolean} + * @default {@link Html5.canControlPlaybackRate} + */ +Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate(); + +/** + * Boolean indicating whether the `HTML5` tech currently supports the media element + * moving in the DOM. iOS breaks if you move the media element, so this is set this to + * false there. Everywhere else this should be true. + * + * @type {boolean} + * @default + */ +Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS; + +// TODO: Previous comment: No longer appears to be used. Can probably be removed. +// Is this true? +/** + * Boolean indicating whether the `HTML5` tech currently supports automatic media resize + * when going into fullscreen. + * + * @type {boolean} + * @default + */ +Html5.prototype.featuresFullscreenResize = true; + +/** + * Boolean indicating whether the `HTML5` tech currently supports the progress event. + * If this is false, manual `progress` events will be triggred instead. + * + * @type {boolean} + * @default + */ +Html5.prototype.featuresProgressEvents = true; + +/** + * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event. + * If this is false, manual `timeupdate` events will be triggred instead. + * + * @default + */ +Html5.prototype.featuresTimeupdateEvents = true; + +/** + * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s. + * + * @type {boolean} + * @default {@link Html5.supportsNativeTextTracks} + */ +Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks(); + +/** + * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s. + * + * @type {boolean} + * @default {@link Html5.supportsNativeVideoTracks} + */ +Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks(); + +/** + * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s. + * + * @type {boolean} + * @default {@link Html5.supportsNativeAudioTracks} + */ +Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks(); + +// HTML5 Feature detection and Device Fixes --------------------------------- // +var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType; +var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i; +var mp4RE = /^video\/mp4/i; + +Html5.patchCanPlayType = function () { + + // Android 4.0 and above can play HLS to some extent but it reports being unable to do so + if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) { + Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { + if (type && mpegurlRE.test(type)) { + return 'maybe'; + } + return canPlayType.call(this, type); + }; + + // Override Android 2.2 and less canPlayType method which is broken + } else if (browser.IS_OLD_ANDROID) { + Html5.TEST_VID.constructor.prototype.canPlayType = function (type) { + if (type && mp4RE.test(type)) { + return 'maybe'; + } + return canPlayType.call(this, type); + }; + } +}; + +Html5.unpatchCanPlayType = function () { + var r = Html5.TEST_VID.constructor.prototype.canPlayType; + + Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType; + return r; +}; + +// by default, patch the media element +Html5.patchCanPlayType(); + +Html5.disposeMediaElement = function (el) { + if (!el) { + return; + } + + if (el.parentNode) { + el.parentNode.removeChild(el); + } + + // remove any child track or source nodes to prevent their loading + while (el.hasChildNodes()) { + el.removeChild(el.firstChild); + } + + // remove any src reference. not setting `src=''` because that causes a warning + // in firefox + el.removeAttribute('src'); + + // force the media element to update its loading state by calling load() + // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793) + if (typeof el.load === 'function') { + // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) + (function () { + try { + el.load(); + } catch (e) { + // not supported + } + })(); + } +}; + +Html5.resetMediaElement = function (el) { + if (!el) { + return; + } + + var sources = el.querySelectorAll('source'); + var i = sources.length; + + while (i--) { + el.removeChild(sources[i]); + } + + // remove any src reference. + // not setting `src=''` because that throws an error + el.removeAttribute('src'); + + if (typeof el.load === 'function') { + // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473) + (function () { + try { + el.load(); + } catch (e) { + // satisfy linter + } + })(); + } +}; + +/* Native HTML5 element property wrapping ----------------------------------- */ +// Wrap native properties with a getter +[ +/** + * Get the value of `paused` from the media element. `paused` indicates whether the media element + * is currently paused or not. + * + * @method Html5#paused + * @return {boolean} + * The value of `paused` from the media element. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused} + */ +'paused', + +/** + * Get the value of `currentTime` from the media element. `currentTime` indicates + * the current second that the media is at in playback. + * + * @method Html5#currentTime + * @return {number} + * The value of `currentTime` from the media element. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime} + */ +'currentTime', + +/** + * Get the value of `buffered` from the media element. `buffered` is a `TimeRange` + * object that represents the parts of the media that are already downloaded and + * available for playback. + * + * @method Html5#buffered + * @return {TimeRange} + * The value of `buffered` from the media element. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered} + */ +'buffered', + +/** + * Get the value of `volume` from the media element. `volume` indicates + * the current playback volume of audio for a media. `volume` will be a value from 0 + * (silent) to 1 (loudest and default). + * + * @method Html5#volume + * @return {number} + * The value of `volume` from the media element. Value will be between 0-1. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} + */ +'volume', + +/** + * Get the value of `muted` from the media element. `muted` indicates + * that the volume for the media should be set to silent. This does not actually change + * the `volume` attribute. + * + * @method Html5#muted + * @return {boolean} + * - True if the value of `volume` should be ignored and the audio set to silent. + * - False if the value of `volume` should be used. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} + */ +'muted', + +/** + * Get the value of `poster` from the media element. `poster` indicates + * that the url of an image file that can/will be shown when no media data is available. + * + * @method Html5#poster + * @return {string} + * The value of `poster` from the media element. Value will be a url to an + * image. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster} + */ +'poster', + +/** + * Get the value of `preload` from the media element. `preload` indicates + * what should download before the media is interacted with. It can have the following + * values: + * - none: nothing should be downloaded + * - metadata: poster and the first few frames of the media may be downloaded to get + * media dimensions and other metadata + * - auto: allow the media and metadata for the media to be downloaded before + * interaction + * + * @method Html5#preload + * @return {string} + * The value of `preload` from the media element. Will be 'none', 'metadata', + * or 'auto'. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} + */ +'preload', + +/** + * Get the value of `autoplay` from the media element. `autoplay` indicates + * that the media should start to play as soon as the page is ready. + * + * @method Html5#autoplay + * @return {boolean} + * - The value of `autoplay` from the media element. + * - True indicates that the media should start as soon as the page loads. + * - False indicates that the media should not start as soon as the page loads. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} + */ +'autoplay', + +/** + * Get the value of `controls` from the media element. `controls` indicates + * whether the native media controls should be shown or hidden. + * + * @method Html5#controls + * @return {boolean} + * - The value of `controls` from the media element. + * - True indicates that native controls should be showing. + * - False indicates that native controls should be hidden. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls} + */ +'controls', + +/** + * Get the value of `loop` from the media element. `loop` indicates + * that the media should return to the start of the media and continue playing once + * it reaches the end. + * + * @method Html5#loop + * @return {boolean} + * - The value of `loop` from the media element. + * - True indicates that playback should seek back to start once + * the end of a media is reached. + * - False indicates that playback should not loop back to the start when the + * end of the media is reached. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} + */ +'loop', + +/** + * Get the value of the `error` from the media element. `error` indicates any + * MediaError that may have occured during playback. If error returns null there is no + * current error. + * + * @method Html5#error + * @return {MediaError|null} + * The value of `error` from the media element. Will be `MediaError` if there + * is a current error and null otherwise. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error} + */ +'error', + +/** + * Get the value of `seeking` from the media element. `seeking` indicates whether the + * media is currently seeking to a new position or not. + * + * @method Html5#seeking + * @return {boolean} + * - The value of `seeking` from the media element. + * - True indicates that the media is currently seeking to a new position. + * - Flase indicates that the media is not seeking to a new position at this time. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking} + */ +'seeking', + +/** + * Get the value of `seekable` from the media element. `seekable` returns a + * `TimeRange` object indicating ranges of time that can currently be `seeked` to. + * + * @method Html5#seekable + * @return {TimeRange} + * The value of `seekable` from the media element. A `TimeRange` object + * indicating the current ranges of time that can be seeked to. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable} + */ +'seekable', + +/** + * Get the value of `ended` from the media element. `ended` indicates whether + * the media has reached the end or not. + * + * @method Html5#ended + * @return {boolean} + * - The value of `ended` from the media element. + * - True indicates that the media has ended. + * - False indicates that the media has not ended. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended} + */ +'ended', + +/** + * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates + * whether the media should start muted or not. Only changes the default state of the + * media. `muted` and `defaultMuted` can have different values. `muted` indicates the + * current state. + * + * @method Html5#defaultMuted + * @return {boolean} + * - The value of `defaultMuted` from the media element. + * - True indicates that the media should start muted. + * - False indicates that the media should not start muted + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted} + */ +'defaultMuted', + +/** + * Get the value of `playbackRate` from the media element. `playbackRate` indicates + * the rate at which the media is currently playing back. Examples: + * - if playbackRate is set to 2, media will play twice as fast. + * - if playbackRate is set to 0.5, media will play half as fast. + * + * @method Html5#playbackRate + * @return {number} + * The value of `playbackRate` from the media element. A number indicating + * the current playback speed of the media, where 1 is normal speed. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} + */ +'playbackRate', + +/** + * Get the value of `played` from the media element. `played` returns a `TimeRange` + * object representing points in the media timeline that have been played. + * + * @method Html5#played + * @return {TimeRange} + * The value of `played` from the media element. A `TimeRange` object indicating + * the ranges of time that have been played. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played} + */ +'played', + +/** + * Get the value of `networkState` from the media element. `networkState` indicates + * the current network state. It returns an enumeration from the following list: + * - 0: NETWORK_EMPTY + * - 1: NEWORK_IDLE + * - 2: NETWORK_LOADING + * - 3: NETWORK_NO_SOURCE + * + * @method Html5#networkState + * @return {number} + * The value of `networkState` from the media element. This will be a number + * from the list in the description. + * + * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate} + */ +'networkState', + +/** + * Get the value of `readyState` from the media element. `readyState` indicates + * the current state of the media element. It returns an enumeration from the + * following list: + * - 0: HAVE_NOTHING + * - 1: HAVE_METADATA + * - 2: HAVE_CURRENT_DATA + * - 3: HAVE_FUTURE_DATA + * - 4: HAVE_ENOUGH_DATA + * + * @method Html5#readyState + * @return {number} + * The value of `readyState` from the media element. This will be a number + * from the list in the description. + * + * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states} + */ +'readyState', + +/** + * Get the value of `videoWidth` from the video element. `videoWidth` indicates + * the current width of the video in css pixels. + * + * @method Html5#videoWidth + * @return {number} + * The value of `videoWidth` from the video element. This will be a number + * in css pixels. + * + * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} + */ +'videoWidth', + +/** + * Get the value of `videoHeight` from the video element. `videoHeigth` indicates + * the current height of the video in css pixels. + * + * @method Html5#videoHeight + * @return {number} + * The value of `videoHeight` from the video element. This will be a number + * in css pixels. + * + * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth} + */ +'videoHeight'].forEach(function (prop) { + Html5.prototype[prop] = function () { + return this.el_[prop]; + }; +}); + +// Wrap native properties with a setter in this format: +// set + toTitleCase(name) +[ +/** + * Set the value of `volume` on the media element. `volume` indicates the current + * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and + * so on. + * + * @method Html5#setVolume + * @param {number} percentAsDecimal + * The volume percent as a decimal. Valid range is from 0-1. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume} + */ +'volume', + +/** + * Set the value of `muted` on the media element. `muted` indicates the current + * audio level should be silent. + * + * @method Html5#setMuted + * @param {boolean} muted + * - True if the audio should be set to silent + * - False otherwise + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted} + */ +'muted', + +/** + * Set the value of `src` on the media element. `src` indicates the current + * {@link Tech~SourceObject} for the media. + * + * @method Html5#setSrc + * @param {Tech~SourceObject} src + * The source object to set as the current source. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src} + */ +'src', + +/** + * Set the value of `poster` on the media element. `poster` is the url to + * an image file that can/will be shown when no media data is available. + * + * @method Html5#setPoster + * @param {string} poster + * The url to an image that should be used as the `poster` for the media + * element. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster} + */ +'poster', + +/** + * Set the value of `preload` on the media element. `preload` indicates + * what should download before the media is interacted with. It can have the following + * values: + * - none: nothing should be downloaded + * - metadata: poster and the first few frames of the media may be downloaded to get + * media dimensions and other metadata + * - auto: allow the media and metadata for the media to be downloaded before + * interaction + * + * @method Html5#setPreload + * @param {string} preload + * The value of `preload` to set on the media element. Must be 'none', 'metadata', + * or 'auto'. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload} + */ +'preload', + +/** + * Set the value of `autoplay` on the media element. `autoplay` indicates + * that the media should start to play as soon as the page is ready. + * + * @method Html5#setAutoplay + * @param {boolean} autoplay + * - True indicates that the media should start as soon as the page loads. + * - False indicates that the media should not start as soon as the page loads. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay} + */ +'autoplay', + +/** + * Set the value of `loop` on the media element. `loop` indicates + * that the media should return to the start of the media and continue playing once + * it reaches the end. + * + * @method Html5#setLoop + * @param {boolean} loop + * - True indicates that playback should seek back to start once + * the end of a media is reached. + * - False indicates that playback should not loop back to the start when the + * end of the media is reached. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop} + */ +'loop', + +/** + * Set the value of `playbackRate` on the media element. `playbackRate` indicates + * the rate at which the media should play back. Examples: + * - if playbackRate is set to 2, media will play twice as fast. + * - if playbackRate is set to 0.5, media will play half as fast. + * + * @method Html5#setPlaybackRate + * @return {number} + * The value of `playbackRate` from the media element. A number indicating + * the current playback speed of the media, where 1 is normal speed. + * + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate} + */ +'playbackRate'].forEach(function (prop) { + Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) { + this.el_[prop] = v; + }; +}); + +// wrap native functions with a function +[ +/** + * A wrapper around the media elements `pause` function. This will call the `HTML5` + * media elements `pause` function. + * + * @method Html5#pause + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause} + */ +'pause', + +/** + * A wrapper around the media elements `load` function. This will call the `HTML5`s + * media element `load` function. + * + * @method Html5#load + * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load} + */ +'load'].forEach(function (prop) { + Html5.prototype[prop] = function () { + return this.el_[prop](); + }; +}); + +_tech2['default'].withSourceHandlers(Html5); + +/** + * Native source handler for Html5, simply passes the source to the media element. + * + * @proprety {Tech~SourceObject} source + * The source object + * + * @proprety {Html5} tech + * The instance of the HTML5 tech. + */ +Html5.nativeSourceHandler = {}; + +/** + * Check if the media element can play the given mime type. + * + * @param {string} type + * The mimetype to check + * + * @return {string} + * 'probably', 'maybe', or '' (empty string) + */ +Html5.nativeSourceHandler.canPlayType = function (type) { + // IE9 on Windows 7 without MediaPlayer throws an error here + // https://github.com/videojs/video.js/issues/519 + try { + return Html5.TEST_VID.canPlayType(type); + } catch (e) { + return ''; + } +}; + +/** + * Check if the media element can handle a source natively. + * + * @param {Tech~SourceObject} source + * The source object + * + * @param {Object} [options] + * Options to be passed to the tech. + * + * @return {string} + * 'probably', 'maybe', or '' (empty string). + */ +Html5.nativeSourceHandler.canHandleSource = function (source, options) { + + // If a type was provided we should rely on that + if (source.type) { + return Html5.nativeSourceHandler.canPlayType(source.type); + + // If no type, fall back to checking 'video/[EXTENSION]' + } else if (source.src) { + var ext = Url.getFileExtension(source.src); + + return Html5.nativeSourceHandler.canPlayType('video/' + ext); + } + + return ''; +}; + +/** + * Pass the source to the native media element. + * + * @param {Tech~SourceObject} source + * The source object + * + * @param {Html5} tech + * The instance of the Html5 tech + * + * @param {Object} [options] + * The options to pass to the source + */ +Html5.nativeSourceHandler.handleSource = function (source, tech, options) { + tech.setSrc(source.src); +}; + +/** + * A noop for the native dispose function, as cleanup is not needed. + */ +Html5.nativeSourceHandler.dispose = function () {}; + +// Register the native source handler +Html5.registerSourceHandler(Html5.nativeSourceHandler); + +_component2['default'].registerComponent('Html5', Html5); +_tech2['default'].registerTech('Html5', Html5); +exports['default'] = Html5; + +},{"5":5,"62":62,"78":78,"81":81,"83":83,"86":86,"87":87,"88":88,"91":91,"92":92,"94":94,"95":95,"98":98}],61:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _tech = _dereq_(62); + +var _tech2 = _interopRequireDefault(_tech); + +var _toTitleCase = _dereq_(91); + +var _toTitleCase2 = _interopRequireDefault(_toTitleCase); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file loader.js + */ + + +/** + * The `MediaLoader` is the `Component` that decides which playback technology to load + * when a player is initialized. + * + * @extends Component + */ +var MediaLoader = function (_Component) { + _inherits(MediaLoader, _Component); + + /** + * Create an instance of this class. + * + * @param {Player} player + * The `Player` that this class should attach to. + * + * @param {Object} [options] + * The key/value stroe of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function that is run when this component is ready. + */ + function MediaLoader(player, options, ready) { + _classCallCheck(this, MediaLoader); + + // If there are no sources when the player is initialized, + // load the first supported playback technology. + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); + + if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) { + for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) { + var techName = (0, _toTitleCase2['default'])(j[i]); + var tech = _tech2['default'].getTech(techName); + + // Support old behavior of techs being registered as components. + // Remove once that deprecated behavior is removed. + if (!techName) { + tech = _component2['default'].getComponent(techName); + } + + // Check if the browser supports this technology + if (tech && tech.isSupported()) { + player.loadTech_(techName); + break; + } + } + } else { + // Loop through playback technologies (HTML5, Flash) and check for support. + // Then load the best source. + // A few assumptions here: + // All playback technologies respect preload false. + player.src(options.playerOptions.sources); + } + return _this; + } + + return MediaLoader; +}(_component2['default']); + +_component2['default'].registerComponent('MediaLoader', MediaLoader); +exports['default'] = MediaLoader; + +},{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _htmlTrackElement = _dereq_(66); + +var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement); + +var _htmlTrackElementList = _dereq_(65); + +var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _textTrack = _dereq_(72); + +var _textTrack2 = _interopRequireDefault(_textTrack); + +var _textTrackList = _dereq_(70); + +var _textTrackList2 = _interopRequireDefault(_textTrackList); + +var _videoTrackList = _dereq_(76); + +var _videoTrackList2 = _interopRequireDefault(_videoTrackList); + +var _audioTrackList = _dereq_(63); + +var _audioTrackList2 = _interopRequireDefault(_audioTrackList); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _timeRanges = _dereq_(90); + +var _buffer = _dereq_(79); + +var _mediaError = _dereq_(46); + +var _mediaError2 = _interopRequireDefault(_mediaError); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file tech.js + */ + +/** + * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string + * that just contains the src url alone. + * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};` + * `var SourceString = 'http://example.com/some-video.mp4';` + * + * @typedef {Object|string} Tech~SourceObject + * + * @property {string} src + * The url to the source + * + * @property {string} type + * The mime type of the source + */ + +/** + * A function used by {@link Tech} to create a new {@link TextTrack}. + * + * @param {Tech} self + * An instance of the Tech class. + * + * @param {string} kind + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) + * + * @param {string} [label] + * Label to identify the text track + * + * @param {string} [language] + * Two letter language abbreviation + * + * @param {Object} [options={}] + * An object with additional text track options + * + * @return {TextTrack} + * The text track that was created. + */ +function createTrackHelper(self, kind, label, language) { + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + + var tracks = self.textTracks(); + + options.kind = kind; + + if (label) { + options.label = label; + } + if (language) { + options.language = language; + } + options.tech = self; + + var track = new _textTrack2['default'](options); + + tracks.addTrack_(track); + + return track; +} + +/** + * This is the base class for media playback technology controllers, such as + * {@link Flash} and {@link HTML5} + * + * @extends Component + */ + +var Tech = function (_Component) { + _inherits(Tech, _Component); + + /** + * Create an instance of this Tech. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} ready + * Callback function to call when the `HTML5` Tech is ready. + */ + function Tech() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; + + _classCallCheck(this, Tech); + + // we don't want the tech to report user activity automatically. + // This is done manually in addControlsListeners + options.reportTouchActivity = false; + + // keep track of whether the current source has played at all to + // implement a very limited played() + var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready)); + + _this.hasStarted_ = false; + _this.on('playing', function () { + this.hasStarted_ = true; + }); + _this.on('loadstart', function () { + this.hasStarted_ = false; + }); + + _this.textTracks_ = options.textTracks; + _this.videoTracks_ = options.videoTracks; + _this.audioTracks_ = options.audioTracks; + + // Manually track progress in cases where the browser/flash player doesn't report it. + if (!_this.featuresProgressEvents) { + _this.manualProgressOn(); + } + + // Manually track timeupdates in cases where the browser/flash player doesn't report it. + if (!_this.featuresTimeupdateEvents) { + _this.manualTimeUpdatesOn(); + } + + ['Text', 'Audio', 'Video'].forEach(function (track) { + if (options['native' + track + 'Tracks'] === false) { + _this['featuresNative' + track + 'Tracks'] = false; + } + }); + + if (options.nativeCaptions === false) { + _this.featuresNativeTextTracks = false; + } + + if (!_this.featuresNativeTextTracks) { + _this.emulateTextTracks(); + } + + _this.autoRemoteTextTracks_ = new _textTrackList2['default'](); + + _this.initTextTrackListeners(); + _this.initTrackListeners(); + + // Turn on component tap events only if not using native controls + if (!options.nativeControlsForTouch) { + _this.emitTapEvents(); + } + return _this; + } + + /* Fallbacks for unsupported event types + ================================================================================ */ + + /** + * Polyfill the `progress` event for browsers that don't support it natively. + * + * @see {@link Tech#trackProgress} + */ + + + Tech.prototype.manualProgressOn = function manualProgressOn() { + this.on('durationchange', this.onDurationChange); + + this.manualProgress = true; + + // Trigger progress watching when a source begins loading + this.one('ready', this.trackProgress); + }; + + /** + * Turn off the polyfill for `progress` events that was created in + * {@link Tech#manualProgressOn} + */ + + + Tech.prototype.manualProgressOff = function manualProgressOff() { + this.manualProgress = false; + this.stopTrackingProgress(); + + this.off('durationchange', this.onDurationChange); + }; + + /** + * This is used to trigger a `progress` event when the buffered percent changes. It + * sets an interval function that will be called every 500 milliseconds to check if the + * buffer end percent has changed. + * + * > This function is called by {@link Tech#manualProgressOn} + * + * @param {EventTarget~Event} event + * The `ready` event that caused this to run. + * + * @listens Tech#ready + * @fires Tech#progress + */ + + + Tech.prototype.trackProgress = function trackProgress(event) { + this.stopTrackingProgress(); + this.progressInterval = this.setInterval(Fn.bind(this, function () { + // Don't trigger unless buffered amount is greater than last time + + var numBufferedPercent = this.bufferedPercent(); + + if (this.bufferedPercent_ !== numBufferedPercent) { + /** + * See {@link Player#progress} + * + * @event Tech#progress + * @type {EventTarget~Event} + */ + this.trigger('progress'); + } + + this.bufferedPercent_ = numBufferedPercent; + + if (numBufferedPercent === 1) { + this.stopTrackingProgress(); + } + }), 500); + }; + + /** + * Update our internal duration on a `durationchange` event by calling + * {@link Tech#duration}. + * + * @param {EventTarget~Event} event + * The `durationchange` event that caused this to run. + * + * @listens Tech#durationchange + */ + + + Tech.prototype.onDurationChange = function onDurationChange(event) { + this.duration_ = this.duration(); + }; + + /** + * Get and create a `TimeRange` object for buffering. + * + * @return {TimeRange} + * The time range object that was created. + */ + + + Tech.prototype.buffered = function buffered() { + return (0, _timeRanges.createTimeRange)(0, 0); + }; + + /** + * Get the percentage of the current video that is currently buffered. + * + * @return {number} + * A number from 0 to 1 that represents the decimal percentage of the + * video that is buffered. + * + */ + + + Tech.prototype.bufferedPercent = function bufferedPercent() { + return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_); + }; + + /** + * Turn off the polyfill for `progress` events that was created in + * {@link Tech#manualProgressOn} + * Stop manually tracking progress events by clearing the interval that was set in + * {@link Tech#trackProgress}. + */ + + + Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { + this.clearInterval(this.progressInterval); + }; + + /** + * Polyfill the `timeupdate` event for browsers that don't support it. + * + * @see {@link Tech#trackCurrentTime} + */ + + + Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { + this.manualTimeUpdates = true; + + this.on('play', this.trackCurrentTime); + this.on('pause', this.stopTrackingCurrentTime); + }; + + /** + * Turn off the polyfill for `timeupdate` events that was created in + * {@link Tech#manualTimeUpdatesOn} + */ + + + Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { + this.manualTimeUpdates = false; + this.stopTrackingCurrentTime(); + this.off('play', this.trackCurrentTime); + this.off('pause', this.stopTrackingCurrentTime); + }; + + /** + * Sets up an interval function to track current time and trigger `timeupdate` every + * 250 milliseconds. + * + * @listens Tech#play + * @triggers Tech#timeupdate + */ + + + Tech.prototype.trackCurrentTime = function trackCurrentTime() { + if (this.currentTimeInterval) { + this.stopTrackingCurrentTime(); + } + this.currentTimeInterval = this.setInterval(function () { + /** + * Triggered at an interval of 250ms to indicated that time is passing in the video. + * + * @event Tech#timeupdate + * @type {EventTarget~Event} + */ + this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); + + // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 + }, 250); + }; + + /** + * Stop the interval function created in {@link Tech#trackCurrentTime} so that the + * `timeupdate` event is no longer triggered. + * + * @listens {Tech#pause} + */ + + + Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { + this.clearInterval(this.currentTimeInterval); + + // #1002 - if the video ends right before the next timeupdate would happen, + // the progress bar won't make it all the way to the end + this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); + }; + + /** + * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, + * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. + * + * @fires Component#dispose + */ + + + Tech.prototype.dispose = function dispose() { + + // clear out all tracks because we can't reuse them between techs + this.clearTracks(['audio', 'video', 'text']); + + // Turn off any manual progress or timeupdate tracking + if (this.manualProgress) { + this.manualProgressOff(); + } + + if (this.manualTimeUpdates) { + this.manualTimeUpdatesOff(); + } + + _Component.prototype.dispose.call(this); + }; + + /** + * Clear out a single `TrackList` or an array of `TrackLists` given their names. + * + * > Note: Techs without source handlers should call this between sources for `video` + * & `audio` tracks. You don't want to use them between tracks! + * + * @param {string[]|string} types + * TrackList names to clear, valid names are `video`, `audio`, and + * `text`. + */ + + + Tech.prototype.clearTracks = function clearTracks(types) { + var _this2 = this; + + types = [].concat(types); + // clear out all tracks because we can't reuse them between techs + types.forEach(function (type) { + var list = _this2[type + 'Tracks']() || []; + var i = list.length; + + while (i--) { + var track = list[i]; + + if (type === 'text') { + _this2.removeRemoteTextTrack(track); + } + list.removeTrack_(track); + } + }); + }; + + /** + * Remove any TextTracks added via addRemoteTextTrack that are + * flagged for automatic garbage collection + */ + + + Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() { + var list = this.autoRemoteTextTracks_ || []; + var i = list.length; + + while (i--) { + var track = list[i]; + + this.removeRemoteTextTrack(track); + } + }; + + /** + * Reset the tech, which will removes all sources and reset the internal readyState. + * + * @abstract + */ + + + Tech.prototype.reset = function reset() {}; + + /** + * Get or set an error on the Tech. + * + * @param {MediaError} [err] + * Error to set on the Tech + * + * @return {MediaError|null} + * The current error object on the tech, or null if there isn't one. + */ + + + Tech.prototype.error = function error(err) { + if (err !== undefined) { + this.error_ = new _mediaError2['default'](err); + this.trigger('error'); + } + return this.error_; + }; + + /** + * Returns the `TimeRange`s that have been played through for the current source. + * + * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. + * It only checks wether the source has played at all or not. + * + * @return {TimeRange} + * - A single time range if this video has played + * - An empty set of ranges if not. + */ + + + Tech.prototype.played = function played() { + if (this.hasStarted_) { + return (0, _timeRanges.createTimeRange)(0, 0); + } + return (0, _timeRanges.createTimeRange)(); + }; + + /** + * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was + * previously called. + * + * @fires Tech#timeupdate + */ + + + Tech.prototype.setCurrentTime = function setCurrentTime() { + // improve the accuracy of manual timeupdates + if (this.manualTimeUpdates) { + /** + * A manual `timeupdate` event. + * + * @event Tech#timeupdate + * @type {EventTarget~Event} + */ + this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); + } + }; + + /** + * Turn on listeners for {@link TextTrackList} events. This adds + * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and + * `removetrack`. + * + * @fires Tech#texttrackchange + */ + + + Tech.prototype.initTextTrackListeners = function initTextTrackListeners() { + var textTrackListChanges = Fn.bind(this, function () { + /** + * Triggered when tracks are added or removed on the Tech {@link TextTrackList} + * + * @event Tech#texttrackchange + * @type {EventTarget~Event} + */ + this.trigger('texttrackchange'); + }); + + var tracks = this.textTracks(); + + if (!tracks) { + return; + } + + tracks.addEventListener('removetrack', textTrackListChanges); + tracks.addEventListener('addtrack', textTrackListChanges); + + this.on('dispose', Fn.bind(this, function () { + tracks.removeEventListener('removetrack', textTrackListChanges); + tracks.removeEventListener('addtrack', textTrackListChanges); + })); + }; + + /** + * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events. + * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. + * + * @fires Tech#audiotrackchange + * @fires Tech#videotrackchange + */ + + + Tech.prototype.initTrackListeners = function initTrackListeners() { + var _this3 = this; + + var trackTypes = ['video', 'audio']; + + trackTypes.forEach(function (type) { + /** + * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} + * + * @event Tech#audiotrackchange + * @type {EventTarget~Event} + */ + + /** + * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} + * + * @event Tech#videotrackchange + * @type {EventTarget~Event} + */ + var trackListChanges = function trackListChanges() { + _this3.trigger(type + 'trackchange'); + }; + + var tracks = _this3[type + 'Tracks'](); + + tracks.addEventListener('removetrack', trackListChanges); + tracks.addEventListener('addtrack', trackListChanges); + + _this3.on('dispose', function () { + tracks.removeEventListener('removetrack', trackListChanges); + tracks.removeEventListener('addtrack', trackListChanges); + }); + }); + }; + + /** + * Emulate TextTracks using vtt.js if necessary + * + * @fires Tech#vttjsloaded + * @fires Tech#vttjserror + * @fires Tech#texttrackchange + */ + + + Tech.prototype.addWebVttScript_ = function addWebVttScript_() { + var _this4 = this; + + if (!_window2['default'].WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) { + (function () { + var script = _document2['default'].createElement('script'); + + script.src = _this4.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js'; + script.onload = function () { + /** + * Fired when vtt.js is loaded. + * + * @event Tech#vttjsloaded + * @type {EventTarget~Event} + */ + _this4.trigger('vttjsloaded'); + }; + script.onerror = function () { + /** + * Fired when vtt.js was not loaded due to an error + * + * @event Tech#vttjsloaded + * @type {EventTarget~Event} + */ + _this4.trigger('vttjserror'); + }; + _this4.on('dispose', function () { + script.onload = null; + script.onerror = null; + }); + // but have not loaded yet and we set it to true before the inject so that + // we don't overwrite the injected window.WebVTT if it loads right away + _window2['default'].WebVTT = true; + _this4.el().parentNode.appendChild(script); + })(); + } + }; + + /** + * Emulate texttracks + * + * @method emulateTextTracks + */ + + + Tech.prototype.emulateTextTracks = function emulateTextTracks() { + var _this5 = this; + + var tracks = this.textTracks(); + + if (!tracks) { + return; + } + + this.remoteTextTracks().on('addtrack', function (e) { + _this5.textTracks().addTrack_(e.track); + }); + + this.remoteTextTracks().on('removetrack', function (e) { + _this5.textTracks().removeTrack_(e.track); + }); + + // Initially, Tech.el_ is a child of a dummy-div wait until the Component system + // signals that the Tech is ready at which point Tech.el_ is part of the DOM + // before inserting the WebVTT script + this.on('ready', this.addWebVttScript_); + + var updateDisplay = function updateDisplay() { + return _this5.trigger('texttrackchange'); + }; + var textTracksChanges = function textTracksChanges() { + updateDisplay(); + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + + track.removeEventListener('cuechange', updateDisplay); + if (track.mode === 'showing') { + track.addEventListener('cuechange', updateDisplay); + } + } + }; + + textTracksChanges(); + tracks.addEventListener('change', textTracksChanges); + + this.on('dispose', function () { + tracks.removeEventListener('change', textTracksChanges); + }); + }; + + /** + * Get the `Tech`s {@link VideoTrackList}. + * + * @return {VideoTrackList} + * The video track list that the Tech is currently using. + */ + + + Tech.prototype.videoTracks = function videoTracks() { + this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default'](); + return this.videoTracks_; + }; + + /** + * Get the `Tech`s {@link AudioTrackList}. + * + * @return {AudioTrackList} + * The audio track list that the Tech is currently using. + */ + + + Tech.prototype.audioTracks = function audioTracks() { + this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default'](); + return this.audioTracks_; + }; + + /** + * Get the `Tech`s {@link TextTrackList}. + * + * @return {TextTrackList} + * The text track list that the Tech is currently using. + */ + + + Tech.prototype.textTracks = function textTracks() { + this.textTracks_ = this.textTracks_ || new _textTrackList2['default'](); + return this.textTracks_; + }; + + /** + * Get the `Tech`s remote {@link TextTrackList}, which is created from elements + * that were added to the DOM. + * + * @return {TextTrackList} + * The remote text track list that the Tech is currently using. + */ + + + Tech.prototype.remoteTextTracks = function remoteTextTracks() { + this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default'](); + return this.remoteTextTracks_; + }; + + /** + * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are + * being used as TextTracks. + * + * @return {HTMLTrackElementList} + * The current HTML track elements that exist for the tech. + */ + + + Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() { + this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default'](); + return this.remoteTextTrackEls_; + }; + + /** + * Create and returns a remote {@link TextTrack} object. + * + * @param {string} kind + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) + * + * @param {string} [label] + * Label to identify the text track + * + * @param {string} [language] + * Two letter language abbreviation + * + * @return {TextTrack} + * The TextTrack that gets created. + */ + + + Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { + if (!kind) { + throw new Error('TextTrack kind is required but was not provided'); + } + + return createTrackHelper(this, kind, label, language); + }; + + /** + * Create an emulated TextTrack for use by addRemoteTextTrack + * + * This is intended to be overridden by classes that inherit from + * Tech in order to create native or custom TextTracks. + * + * @param {Object} options + * The object should contain the options to initialize the TextTrack with. + * + * @param {string} [options.kind] + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). + * + * @param {string} [options.label]. + * Label to identify the text track + * + * @param {string} [options.language] + * Two letter language abbreviation. + * + * @return {HTMLTrackElement} + * The track element that gets created. + */ + + + Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { + var track = (0, _mergeOptions2['default'])(options, { + tech: this + }); + + return new _htmlTrackElement2['default'](track); + }; + + /** + * Creates a remote text track object and returns an html track element. + * + * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. + * + * @param {Object} options + * See {@link Tech#createRemoteTextTrack} for more detailed properties. + * + * @param {boolean} [manualCleanup=true] + * - When false: the TextTrack will be automatically removed from the video + * element whenever the source changes + * - When True: The TextTrack will have to be cleaned up manually + * + * @return {HTMLTrackElement} + * An Html Track Element. + * + * @deprecated The default functionality for this function will be equivalent + * to "manualCleanup=false" in the future. The manualCleanup parameter will + * also be removed. + */ + + + Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var manualCleanup = arguments[1]; + + var htmlTrackElement = this.createRemoteTextTrack(options); + + if (manualCleanup !== true && manualCleanup !== false) { + // deprecation warning + _log2['default'].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'); + manualCleanup = true; + } + + // store HTMLTrackElement and TextTrack to remote list + this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); + this.remoteTextTracks().addTrack_(htmlTrackElement.track); + + if (manualCleanup !== true) { + // create the TextTrackList if it doesn't exist + this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track); + } + + return htmlTrackElement; + }; + + /** + * Remove a remote text track from the remote `TextTrackList`. + * + * @param {TextTrack} track + * `TextTrack` to remove from the `TextTrackList` + */ + + + Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { + var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); + + // remove HTMLTrackElement and TextTrack from remote list + this.remoteTextTrackEls().removeTrackElement_(trackElement); + this.remoteTextTracks().removeTrack_(track); + this.autoRemoteTextTracks_.removeTrack_(track); + }; + + /** + * A method to set a poster from a `Tech`. + * + * @abstract + */ + + + Tech.prototype.setPoster = function setPoster() {}; + + /* + * Check if the tech can support the given mime-type. + * + * The base tech does not support any type, but source handlers might + * overwrite this. + * + * @param {string} type + * The mimetype to check for support + * + * @return {string} + * 'probably', 'maybe', or empty string + * + * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType} + * + * @abstract + */ + + + Tech.prototype.canPlayType = function canPlayType() { + return ''; + }; + + /* + * Return whether the argument is a Tech or not. + * Can be passed either a Class like `Html5` or a instance like `player.tech_` + * + * @param {Object} component + * The item to check + * + * @return {boolean} + * Whether it is a tech or not + * - True if it is a tech + * - False if it is not + */ + + + Tech.isTech = function isTech(component) { + return component.prototype instanceof Tech || component instanceof Tech || component === Tech; + }; + + /** + * Registers a `Tech` into a shared list for videojs. + * + * @param {string} name + * Name of the `Tech` to register. + * + * @param {Object} tech + * The `Tech` class to register. + */ + + + Tech.registerTech = function registerTech(name, tech) { + if (!Tech.techs_) { + Tech.techs_ = {}; + } + + if (!Tech.isTech(tech)) { + throw new Error('Tech ' + name + ' must be a Tech'); + } + + Tech.techs_[name] = tech; + return tech; + }; + + /** + * Get a `Tech` from the shared list by name. + * + * @param {string} name + * Name of the component to get + * + * @return {Tech|undefined} + * The `Tech` or undefined if there was no tech with the name requsted. + */ + + + Tech.getTech = function getTech(name) { + if (Tech.techs_ && Tech.techs_[name]) { + return Tech.techs_[name]; + } + + if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) { + _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)'); + return _window2['default'].videojs[name]; + } + }; + + return Tech; +}(_component2['default']); + +/** + * List of associated text tracks. + * + * @type {TextTrackList} + * @private + */ + + +Tech.prototype.textTracks_; // eslint-disable-line + +/** + * List of associated audio tracks. + * + * @type {AudioTrackList} + * @private + */ +Tech.prototype.audioTracks_; // eslint-disable-line + +/** + * List of associated video tracks. + * + * @type {VideoTrackList} + * @private + */ +Tech.prototype.videoTracks_; // eslint-disable-line + +/** + * Boolean indicating wether the `Tech` supports volume control. + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresVolumeControl = true; + +/** + * Boolean indicating wether the `Tech` support fullscreen resize control. + * Resizing plugins using request fullscreen reloads the plugin + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresFullscreenResize = false; + +/** + * Boolean indicating wether the `Tech` supports changing the speed at which the video + * plays. Examples: + * - Set player to play 2x (twice) as fast + * - Set player to play 0.5x (half) as fast + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresPlaybackRate = false; + +/** + * Boolean indicating wether the `Tech` supports the `progress` event. This is currently + * not triggered by video-js-swf. This will be used to determine if + * {@link Tech#manualProgressOn} should be called. + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresProgressEvents = false; + +/** + * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently + * not triggered by video-js-swf. This will be used to determine if + * {@link Tech#manualTimeUpdates} should be called. + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresTimeupdateEvents = false; + +/** + * Boolean indicating wether the `Tech` supports the native `TextTrack`s. + * This will help us integrate with native `TextTrack`s if the browser supports them. + * + * @type {boolean} + * @default + */ +Tech.prototype.featuresNativeTextTracks = false; + +/** + * A functional mixin for techs that want to use the Source Handler pattern. + * Source handlers are scripts for handling specific formats. + * The source handler pattern is used for adaptive formats (HLS, DASH) that + * manually load video data and feed it into a Source Buffer (Media Source Extensions) + * Example: `Tech.withSourceHandlers.call(MyTech);` + * + * @param {Tech} _Tech + * The tech to add source handler functions to. + * + * @mixes Tech~SourceHandlerAdditions + */ +Tech.withSourceHandlers = function (_Tech) { + + /** + * Register a source handler + * + * @param {Function} handler + * The source handler class + * + * @param {number} [index] + * Register it at the following index + */ + _Tech.registerSourceHandler = function (handler, index) { + var handlers = _Tech.sourceHandlers; + + if (!handlers) { + handlers = _Tech.sourceHandlers = []; + } + + if (index === undefined) { + // add to the end of the list + index = handlers.length; + } + + handlers.splice(index, 0, handler); + }; + + /** + * Check if the tech can support the given type. Also checks the + * Techs sourceHandlers. + * + * @param {string} type + * The mimetype to check. + * + * @return {string} + * 'probably', 'maybe', or '' (empty string) + */ + _Tech.canPlayType = function (type) { + var handlers = _Tech.sourceHandlers || []; + var can = void 0; + + for (var i = 0; i < handlers.length; i++) { + can = handlers[i].canPlayType(type); + + if (can) { + return can; + } + } + + return ''; + }; + + /** + * Returns the first source handler that supports the source. + * + * TODO: Answer question: should 'probably' be prioritized over 'maybe' + * + * @param {Tech~SourceObject} source + * The source object + * + * @param {Object} options + * The options passed to the tech + * + * @return {SourceHandler|null} + * The first source handler that supports the source or null if + * no SourceHandler supports the source + */ + _Tech.selectSourceHandler = function (source, options) { + var handlers = _Tech.sourceHandlers || []; + var can = void 0; + + for (var i = 0; i < handlers.length; i++) { + can = handlers[i].canHandleSource(source, options); + + if (can) { + return handlers[i]; + } + } + + return null; + }; + + /** + * Check if the tech can support the given source. + * + * @param {Tech~SourceObject} srcObj + * The source object + * + * @param {Object} options + * The options passed to the tech + * + * @return {string} + * 'probably', 'maybe', or '' (empty string) + */ + _Tech.canPlaySource = function (srcObj, options) { + var sh = _Tech.selectSourceHandler(srcObj, options); + + if (sh) { + return sh.canHandleSource(srcObj, options); + } + + return ''; + }; + + /** + * When using a source handler, prefer its implementation of + * any function normally provided by the tech. + */ + var deferrable = ['seekable', 'duration']; + + /** + * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable + * function if it exists, with a fallback to the Techs seekable function. + * + * @method _Tech.seekable + */ + + /** + * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration + * function if it exists, otherwise it will fallback to the techs duration function. + * + * @method _Tech.duration + */ + + deferrable.forEach(function (fnName) { + var originalFn = this[fnName]; + + if (typeof originalFn !== 'function') { + return; + } + + this[fnName] = function () { + if (this.sourceHandler_ && this.sourceHandler_[fnName]) { + return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments); + } + return originalFn.apply(this, arguments); + }; + }, _Tech.prototype); + + /** + * Create a function for setting the source using a source object + * and source handlers. + * Should never be called unless a source handler was found. + * + * @param {Tech~SourceObject} source + * A source object with src and type keys + * + * @return {Tech} + * Returns itself; this method is chainable + */ + _Tech.prototype.setSource = function (source) { + var sh = _Tech.selectSourceHandler(source, this.options_); + + if (!sh) { + // Fall back to a native source hander when unsupported sources are + // deliberately set + if (_Tech.nativeSourceHandler) { + sh = _Tech.nativeSourceHandler; + } else { + _log2['default'].error('No source hander found for the current source.'); + } + } + + // Dispose any existing source handler + this.disposeSourceHandler(); + this.off('dispose', this.disposeSourceHandler); + + if (sh !== _Tech.nativeSourceHandler) { + this.currentSource_ = source; + + // Catch if someone replaced the src without calling setSource. + // If they do, set currentSource_ to null and dispose our source handler. + this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); + this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); + this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); + } + + this.sourceHandler_ = sh.handleSource(source, this, this.options_); + this.on('dispose', this.disposeSourceHandler); + + return this; + }; + + /** + * Called once for the first loadstart of a video. + * + * @listens Tech#loadstart + */ + _Tech.prototype.firstLoadStartListener_ = function () { + this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); + }; + + // On successive loadstarts when setSource has not been called again + /** + * Called after the first loadstart for a video occurs. + * + * @listens Tech#loadstart + */ + _Tech.prototype.successiveLoadStartListener_ = function () { + this.disposeSourceHandler(); + this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); + }; + + /** + * Clean up any existing SourceHandlers and listeners when the Tech is disposed. + * + * @listens Tech#dispose + */ + _Tech.prototype.disposeSourceHandler = function () { + // if we have a source and get another one + // then we are loading something new + // than clear all of our current tracks + if (this.currentSource_) { + this.clearTracks(['audio', 'video']); + this.currentSource_ = null; + } + + // always clean up auto-text tracks + this.cleanupAutoTextTracks(); + + if (this.sourceHandler_) { + this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_); + this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_); + + if (this.sourceHandler_.dispose) { + this.sourceHandler_.dispose(); + } + + this.sourceHandler_ = null; + } + }; +}; + +_component2['default'].registerComponent('Tech', Tech); +// Old name for Tech +// @deprecated +_component2['default'].registerComponent('MediaTechController', Tech); +Tech.registerTech('Tech', Tech); +exports['default'] = Tech; + +},{"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"90":90,"94":94,"95":95}],63:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackList = _dereq_(74); + +var _trackList2 = _interopRequireDefault(_trackList); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file audio-track-list.js + */ + + +/** + * Anywhere we call this function we diverge from the spec + * as we only support one enabled audiotrack at a time + * + * @param {AudioTrackList} list + * list to work on + * + * @param {AudioTrack} track + * The track to skip + * + * @private + */ +var disableOthers = function disableOthers(list, track) { + for (var i = 0; i < list.length; i++) { + if (track.id === list[i].id) { + continue; + } + // another audio track is enabled, disable it + list[i].enabled = false; + } +}; + +/** + * The current list of {@link AudioTrack} for a media file. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist} + * @extends TrackList + */ + +var AudioTrackList = function (_TrackList) { + _inherits(AudioTrackList, _TrackList); + + /** + * Create an instance of this class. + * + * @param {AudioTrack[]} [tracks=[]] + * A list of `AudioTrack` to instantiate the list with. + */ + function AudioTrackList() { + var _this, _ret; + + var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + _classCallCheck(this, AudioTrackList); + + var list = void 0; + + // make sure only 1 track is enabled + // sorted from last index to first index + for (var i = tracks.length - 1; i >= 0; i--) { + if (tracks[i].enabled) { + disableOthers(tracks, tracks[i]); + break; + } + } + + // IE8 forces us to implement inheritance ourselves + // as it does not support Object.defineProperty properly + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + for (var prop in _trackList2['default'].prototype) { + if (prop !== 'constructor') { + list[prop] = _trackList2['default'].prototype[prop]; + } + } + for (var _prop in AudioTrackList.prototype) { + if (_prop !== 'constructor') { + list[_prop] = AudioTrackList.prototype[_prop]; + } + } + } + + list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); + list.changing_ = false; + + return _ret = list, _possibleConstructorReturn(_this, _ret); + } + + /** + * Add an {@link AudioTrack} to the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to add to the list + * + * @fires Track#addtrack + * @private + */ + + + AudioTrackList.prototype.addTrack_ = function addTrack_(track) { + var _this2 = this; + + if (track.enabled) { + disableOthers(this, track); + } + + _TrackList.prototype.addTrack_.call(this, track); + // native tracks don't have this + if (!track.addEventListener) { + return; + } + + /** + * @listens AudioTrack#enabledchange + * @fires TrackList#change + */ + track.addEventListener('enabledchange', function () { + // when we are disabling other tracks (since we don't support + // more than one track at a time) we will set changing_ + // to true so that we don't trigger additional change events + if (_this2.changing_) { + return; + } + _this2.changing_ = true; + disableOthers(_this2, track); + _this2.changing_ = false; + _this2.trigger('change'); + }); + }; + + /** + * Add an {@link AudioTrack} to the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to add to the list + * + * @fires Track#addtrack + */ + + + AudioTrackList.prototype.addTrack = function addTrack(track) { + this.addTrack_(track); + }; + + /** + * Remove an {@link AudioTrack} from the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to remove from the list + * + * @fires Track#removetrack + */ + + + AudioTrackList.prototype.removeTrack = function removeTrack(track) { + _TrackList.prototype.removeTrack_.call(this, track); + }; + + return AudioTrackList; +}(_trackList2['default']); + +exports['default'] = AudioTrackList; + +},{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackEnums = _dereq_(73); + +var _track = _dereq_(75); + +var _track2 = _interopRequireDefault(_track); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList} + * only one `AudioTrack` in the list will be enabled at a time. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack} + * @extends Track + */ +var AudioTrack = function (_Track) { + _inherits(AudioTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {AudioTrack~Kind} [options.kind=''] + * A valid audio track kind + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {boolean} [options.enabled] + * If this track is the one that is currently playing. If this track is part of + * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. + */ + function AudioTrack() { + var _this, _ret; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, AudioTrack); + + var settings = (0, _mergeOptions2['default'])(options, { + kind: _trackEnums.AudioTrackKind[options.kind] || '' + }); + // on IE8 this will be a document element + // for every other browser this will be a normal object + var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); + var enabled = false; + + if (browser.IS_IE8) { + for (var prop in AudioTrack.prototype) { + if (prop !== 'constructor') { + track[prop] = AudioTrack.prototype[prop]; + } + } + } + /** + * @member {boolean} enabled + * If this `AudioTrack` is enabled or not. When setting this will + * fire {@link AudioTrack#enabledchange} if the state of enabled is changed. + * + * @fires VideoTrack#selectedchange + */ + Object.defineProperty(track, 'enabled', { + get: function get() { + return enabled; + }, + set: function set(newEnabled) { + // an invalid or unchanged value + if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { + return; + } + enabled = newEnabled; + + /** + * An event that fires when enabled changes on this track. This allows + * the AudioTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! Native tracks will do + * this internally without an event. + * + * @event AudioTrack#enabledchange + * @type {EventTarget~Event} + */ + this.trigger('enabledchange'); + } + }); + + // if the user sets this track to selected then + // set selected to that true value otherwise + // we keep it false + if (settings.enabled) { + track.enabled = settings.enabled; + } + track.loaded_ = true; + + return _ret = track, _possibleConstructorReturn(_this, _ret); + } + + return AudioTrack; +}(_track2['default']); + +exports['default'] = AudioTrack; + +},{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** + * @file html-track-element-list.js + */ + +/** + * The current list of {@link HtmlTrackElement}s. + */ +var HtmlTrackElementList = function () { + + /** + * Create an instance of this class. + * + * @param {HtmlTrackElement[]} [tracks=[]] + * A list of `HtmlTrackElement` to instantiate the list with. + */ + function HtmlTrackElementList() { + var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + _classCallCheck(this, HtmlTrackElementList); + + var list = this; // eslint-disable-line + + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + + for (var prop in HtmlTrackElementList.prototype) { + if (prop !== 'constructor') { + list[prop] = HtmlTrackElementList.prototype[prop]; + } + } + } + + list.trackElements_ = []; + + /** + * @member {number} length + * The current number of `Track`s in the this Trackist. + */ + Object.defineProperty(list, 'length', { + get: function get() { + return this.trackElements_.length; + } + }); + + for (var i = 0, length = trackElements.length; i < length; i++) { + list.addTrackElement_(trackElements[i]); + } + + if (browser.IS_IE8) { + return list; + } + } + + /** + * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to add to the list. + * + * @private + */ + + + HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) { + var index = this.trackElements_.length; + + if (!('' + index in this)) { + Object.defineProperty(this, index, { + get: function get() { + return this.trackElements_[index]; + } + }); + } + + // Do not add duplicate elements + if (this.trackElements_.indexOf(trackElement) === -1) { + this.trackElements_.push(trackElement); + } + }; + + /** + * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an + * {@link TextTrack}. + * + * @param {TextTrack} track + * The track associated with a track element. + * + * @return {HtmlTrackElement|undefined} + * The track element that was found or undefined. + * + * @private + */ + + + HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { + var trackElement_ = void 0; + + for (var i = 0, length = this.trackElements_.length; i < length; i++) { + if (track === this.trackElements_[i].track) { + trackElement_ = this.trackElements_[i]; + + break; + } + } + + return trackElement_; + }; + + /** + * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to remove from the list. + * + * @private + */ + + + HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { + for (var i = 0, length = this.trackElements_.length; i < length; i++) { + if (trackElement === this.trackElements_[i]) { + this.trackElements_.splice(i, 1); + + break; + } + } + }; + + return HtmlTrackElementList; +}(); + +exports['default'] = HtmlTrackElementList; + +},{"78":78,"94":94}],66:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _eventTarget = _dereq_(42); + +var _eventTarget2 = _interopRequireDefault(_eventTarget); + +var _textTrack = _dereq_(72); + +var _textTrack2 = _interopRequireDefault(_textTrack); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file html-track-element.js + */ + +/** + * @typedef {HTMLTrackElement~ReadyState} + * @enum {number} + */ +var NONE = 0; +var LOADING = 1; +var LOADED = 2; +var ERROR = 3; + +/** + * A single track represented in the DOM. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement} + * @extends EventTarget + */ + +var HTMLTrackElement = function (_EventTarget) { + _inherits(HTMLTrackElement, _EventTarget); + + /** + * Create an instance of this class. + * + * @param {Object} options={} + * Object of option names and values + * + * @param {Tech} options.tech + * A reference to the tech that owns this HTMLTrackElement. + * + * @param {TextTrack~Kind} [options.kind='subtitles'] + * A valid text track kind. + * + * @param {TextTrack~Mode} [options.mode='disabled'] + * A valid text track mode. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this TextTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {string} [options.srclang=''] + * A valid two character language code. An alternative, but deprioritized + * vesion of `options.language` + * + * @param {string} [options.src] + * A url to TextTrack cues. + * + * @param {boolean} [options.default] + * If this track should default to on or off. + */ + function HTMLTrackElement() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, HTMLTrackElement); + + var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); + + var readyState = void 0; + var trackElement = _this; // eslint-disable-line + + if (browser.IS_IE8) { + trackElement = _document2['default'].createElement('custom'); + + for (var prop in HTMLTrackElement.prototype) { + if (prop !== 'constructor') { + trackElement[prop] = HTMLTrackElement.prototype[prop]; + } + } + } + + var track = new _textTrack2['default'](options); + + trackElement.kind = track.kind; + trackElement.src = track.src; + trackElement.srclang = track.language; + trackElement.label = track.label; + trackElement['default'] = track['default']; + + /** + * @member {HTMLTrackElement~ReadyState} readyState + * The current ready state of the track element. + */ + Object.defineProperty(trackElement, 'readyState', { + get: function get() { + return readyState; + } + }); + + /** + * @member {TextTrack} track + * The underlying TextTrack object. + */ + Object.defineProperty(trackElement, 'track', { + get: function get() { + return track; + } + }); + + readyState = NONE; + + /** + * @listens TextTrack#loadeddata + * @fires HTMLTrackElement#load + */ + track.addEventListener('loadeddata', function () { + readyState = LOADED; + + trackElement.trigger({ + type: 'load', + target: trackElement + }); + }); + + if (browser.IS_IE8) { + var _ret; + + return _ret = trackElement, _possibleConstructorReturn(_this, _ret); + } + return _this; + } + + return HTMLTrackElement; +}(_eventTarget2['default']); + +HTMLTrackElement.prototype.allowedEvents_ = { + load: 'load' +}; + +HTMLTrackElement.NONE = NONE; +HTMLTrackElement.LOADING = LOADING; +HTMLTrackElement.LOADED = LOADED; +HTMLTrackElement.ERROR = ERROR; + +exports['default'] = HTMLTrackElement; + +},{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** + * @file text-track-cue-list.js + */ + + +/** + * @typedef {Object} TextTrackCue + * + * @property {string} id + * The unique id for this text track cue + * + * @property {number} startTime + * The start time for this text track cue + * + * @property {number} endTime + * The end time for this text track cue + * + * @property {boolean} pauseOnExit + * Pause when the end time is reached if true. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue} + */ + +/** + * A List of TextTrackCues. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} + */ +var TextTrackCueList = function () { + + /** + * Create an instance of this class.. + * + * @param {Array} cues + * A list of cues to be initialized with + */ + function TextTrackCueList(cues) { + _classCallCheck(this, TextTrackCueList); + + var list = this; // eslint-disable-line + + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + + for (var prop in TextTrackCueList.prototype) { + if (prop !== 'constructor') { + list[prop] = TextTrackCueList.prototype[prop]; + } + } + } + + TextTrackCueList.prototype.setCues_.call(list, cues); + + /** + * @member {number} length + * The current number of `TextTrackCue`s in the TextTrackCueList. + */ + Object.defineProperty(list, 'length', { + get: function get() { + return this.length_; + } + }); + + if (browser.IS_IE8) { + return list; + } + } + + /** + * A setter for cues in this list. Creates getters + * an an index for the cues. + * + * @param {Array} cues + * An array of cues to set + * + * @private + */ + + + TextTrackCueList.prototype.setCues_ = function setCues_(cues) { + var oldLength = this.length || 0; + var i = 0; + var l = cues.length; + + this.cues_ = cues; + this.length_ = cues.length; + + var defineProp = function defineProp(index) { + if (!('' + index in this)) { + Object.defineProperty(this, '' + index, { + get: function get() { + return this.cues_[index]; + } + }); + } + }; + + if (oldLength < l) { + i = oldLength; + + for (; i < l; i++) { + defineProp.call(this, i); + } + } + }; + + /** + * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. + * + * @param {string} id + * The id of the cue that should be searched for. + * + * @return {TextTrackCue|null} + * A single cue or null if none was found. + */ + + + TextTrackCueList.prototype.getCueById = function getCueById(id) { + var result = null; + + for (var i = 0, l = this.length; i < l; i++) { + var cue = this[i]; + + if (cue.id === id) { + result = cue; + break; + } + } + + return result; + }; + + return TextTrackCueList; +}(); + +exports['default'] = TextTrackCueList; + +},{"78":78,"94":94}],68:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track-display.js + */ + + +var darkGray = '#222'; +var lightGray = '#ccc'; +var fontMap = { + monospace: 'monospace', + sansSerif: 'sans-serif', + serif: 'serif', + monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace', + monospaceSerif: '"Courier New", monospace', + proportionalSansSerif: 'sans-serif', + proportionalSerif: 'serif', + casual: '"Comic Sans MS", Impact, fantasy', + script: '"Monotype Corsiva", cursive', + smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif' +}; + +/** + * Construct an rgba color from a given hex color code. + * + * @param {number} color + * Hex number for color, like #f0e. + * + * @param {number} opacity + * Value for opacity, 0.0 - 1.0. + * + * @return {string} + * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'. + * + * @private + */ +function constructColor(color, opacity) { + return 'rgba(' + + // color looks like "#f0e" + parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')'; +} + +/** + * Try to update the style of a DOM element. Some style changes will throw an error, + * particularly in IE8. Those should be noops. + * + * @param {Element} el + * The DOM element to be styled. + * + * @param {string} style + * The CSS property on the element that should be styled. + * + * @param {string} rule + * The style rule that should be applied to the property. + */ +function tryUpdateStyle(el, style, rule) { + try { + el.style[style] = rule; + } catch (e) { + + // Satisfies linter. + return; + } +} + +/** + * The component for displaying text track cues. + * + * @extends Component + */ + +var TextTrackDisplay = function (_Component) { + _inherits(TextTrackDisplay, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when `TextTrackDisplay` is ready. + */ + function TextTrackDisplay(player, options, ready) { + _classCallCheck(this, TextTrackDisplay); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready)); + + player.on('loadstart', Fn.bind(_this, _this.toggleDisplay)); + player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay)); + + // This used to be called during player init, but was causing an error + // if a track should show by default and the display hadn't loaded yet. + // Should probably be moved to an external track loader when we support + // tracks that don't need a display. + player.ready(Fn.bind(_this, function () { + if (player.tech_ && player.tech_.featuresNativeTextTracks) { + this.hide(); + return; + } + + player.on('fullscreenchange', Fn.bind(this, this.updateDisplay)); + + var tracks = this.options_.playerOptions.tracks || []; + + for (var i = 0; i < tracks.length; i++) { + this.player_.addRemoteTextTrack(tracks[i], true); + } + + var modes = { captions: 1, subtitles: 1 }; + var trackList = this.player_.textTracks(); + var firstDesc = void 0; + var firstCaptions = void 0; + + if (trackList) { + for (var _i = 0; _i < trackList.length; _i++) { + var track = trackList[_i]; + + if (track['default']) { + if (track.kind === 'descriptions' && !firstDesc) { + firstDesc = track; + } else if (track.kind in modes && !firstCaptions) { + firstCaptions = track; + } + } + } + + // We want to show the first default track but captions and subtitles + // take precedence over descriptions. + // So, display the first default captions or subtitles track + // and otherwise the first default descriptions track. + if (firstCaptions) { + firstCaptions.mode = 'showing'; + } else if (firstDesc) { + firstDesc.mode = 'showing'; + } + } + })); + return _this; + } + + /** + * Turn display of {@link TextTrack}'s from the current state into the other state. + * There are only two states: + * - 'shown' + * - 'hidden' + * + * @listens Player#loadstart + */ + + + TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() { + if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) { + this.hide(); + } else { + this.show(); + } + }; + + /** + * Create the {@link Component}'s DOM element. + * + * @return {Element} + * The element that was created. + */ + + + TextTrackDisplay.prototype.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: 'vjs-text-track-display' + }, { + 'aria-live': 'off', + 'aria-atomic': 'true' + }); + }; + + /** + * Clear all displayed {@link TextTrack}s. + */ + + + TextTrackDisplay.prototype.clearDisplay = function clearDisplay() { + if (typeof _window2['default'].WebVTT === 'function') { + _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_); + } + }; + + /** + * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or + * a {@link Player#fullscreenchange} is fired. + * + * @listens Player#texttrackchange + * @listens Player#fullscreenchange + */ + + + TextTrackDisplay.prototype.updateDisplay = function updateDisplay() { + var tracks = this.player_.textTracks(); + + this.clearDisplay(); + + if (!tracks) { + return; + } + + // Track display prioritization model: if multiple tracks are 'showing', + // display the first 'subtitles' or 'captions' track which is 'showing', + // otherwise display the first 'descriptions' track which is 'showing' + + var descriptionsTrack = null; + var captionsSubtitlesTrack = null; + + var i = tracks.length; + + while (i--) { + var track = tracks[i]; + + if (track.mode === 'showing') { + if (track.kind === 'descriptions') { + descriptionsTrack = track; + } else { + captionsSubtitlesTrack = track; + } + } + } + + if (captionsSubtitlesTrack) { + if (this.getAttribute('aria-live') !== 'off') { + this.setAttribute('aria-live', 'off'); + } + this.updateForTrack(captionsSubtitlesTrack); + } else if (descriptionsTrack) { + if (this.getAttribute('aria-live') !== 'assertive') { + this.setAttribute('aria-live', 'assertive'); + } + this.updateForTrack(descriptionsTrack); + } + }; + + /** + * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}. + * + * @param {TextTrack} track + * Text track object to be added to the list. + */ + + + TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) { + if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) { + return; + } + + var overrides = this.player_.textTrackSettings.getValues(); + var cues = []; + + for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) { + cues.push(track.activeCues[_i2]); + } + + _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_); + + var i = cues.length; + + while (i--) { + var cue = cues[i]; + + if (!cue) { + continue; + } + + var cueDiv = cue.displayState; + + if (overrides.color) { + cueDiv.firstChild.style.color = overrides.color; + } + if (overrides.textOpacity) { + tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity)); + } + if (overrides.backgroundColor) { + cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor; + } + if (overrides.backgroundOpacity) { + tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity)); + } + if (overrides.windowColor) { + if (overrides.windowOpacity) { + tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity)); + } else { + cueDiv.style.backgroundColor = overrides.windowColor; + } + } + if (overrides.edgeStyle) { + if (overrides.edgeStyle === 'dropshadow') { + cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray; + } else if (overrides.edgeStyle === 'raised') { + cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray; + } else if (overrides.edgeStyle === 'depressed') { + cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray; + } else if (overrides.edgeStyle === 'uniform') { + cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray; + } + } + if (overrides.fontPercent && overrides.fontPercent !== 1) { + var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize); + + cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px'; + cueDiv.style.height = 'auto'; + cueDiv.style.top = 'auto'; + cueDiv.style.bottom = '2px'; + } + if (overrides.fontFamily && overrides.fontFamily !== 'default') { + if (overrides.fontFamily === 'small-caps') { + cueDiv.firstChild.style.fontVariant = 'small-caps'; + } else { + cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily]; + } + } + } + }; + + return TextTrackDisplay; +}(_component2['default']); + +_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay); +exports['default'] = TextTrackDisplay; + +},{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +/** + * @file text-track-list-converter.js Utilities for capturing text track state and + * re-creating tracks based on a capture. + * + * @module text-track-list-converter + */ + +/** + * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that + * represents the {@link TextTrack}'s state. + * + * @param {TextTrack} track + * The text track to query. + * + * @return {Object} + * A serializable javascript representation of the TextTrack. + * @private + */ +var trackToJson_ = function trackToJson_(track) { + var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { + + if (track[prop]) { + acc[prop] = track[prop]; + } + + return acc; + }, { + cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { + return { + startTime: cue.startTime, + endTime: cue.endTime, + text: cue.text, + id: cue.id + }; + }) + }); + + return ret; +}; + +/** + * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the + * state of all {@link TextTrack}s currently configured. The return array is compatible with + * {@link text-track-list-converter:jsonToTextTracks}. + * + * @param {Tech} tech + * The tech object to query + * + * @return {Array} + * A serializable javascript representation of the {@link Tech}s + * {@link TextTrackList}. + */ +var textTracksToJson = function textTracksToJson(tech) { + + var trackEls = tech.$$('track'); + + var trackObjs = Array.prototype.map.call(trackEls, function (t) { + return t.track; + }); + var tracks = Array.prototype.map.call(trackEls, function (trackEl) { + var json = trackToJson_(trackEl.track); + + if (trackEl.src) { + json.src = trackEl.src; + } + return json; + }); + + return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { + return trackObjs.indexOf(track) === -1; + }).map(trackToJson_)); +}; + +/** + * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript + * object {@link TextTrack} representations. + * + * @param {Array} json + * An array of `TextTrack` representation objects, like those that would be + * produced by `textTracksToJson`. + * + * @param {Tech} tech + * The `Tech` to create the `TextTrack`s on. + */ +var jsonToTextTracks = function jsonToTextTracks(json, tech) { + json.forEach(function (track) { + var addedTrack = tech.addRemoteTextTrack(track).track; + + if (!track.src && track.cues) { + track.cues.forEach(function (cue) { + return addedTrack.addCue(cue); + }); + } + }); + + return tech.textTracks(); +}; + +exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; + +},{}],70:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackList = _dereq_(74); + +var _trackList2 = _interopRequireDefault(_trackList); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track-list.js + */ + + +/** + * The current list of {@link TextTrack} for a media file. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist} + * @extends TrackList + */ +var TextTrackList = function (_TrackList) { + _inherits(TextTrackList, _TrackList); + + /** + * Create an instance of this class. + * + * @param {TextTrack[]} [tracks=[]] + * A list of `TextTrack` to instantiate the list with. + */ + function TextTrackList() { + var _this, _ret; + + var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + _classCallCheck(this, TextTrackList); + + var list = void 0; + + // IE8 forces us to implement inheritance ourselves + // as it does not support Object.defineProperty properly + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + for (var prop in _trackList2['default'].prototype) { + if (prop !== 'constructor') { + list[prop] = _trackList2['default'].prototype[prop]; + } + } + for (var _prop in TextTrackList.prototype) { + if (_prop !== 'constructor') { + list[_prop] = TextTrackList.prototype[_prop]; + } + } + } + + list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); + return _ret = list, _possibleConstructorReturn(_this, _ret); + } + + /** + * Add a {@link TextTrack} to the `TextTrackList` + * + * @param {TextTrack} track + * The text track to add to the list. + * + * @fires TrackList#addtrack + * @private + */ + + + TextTrackList.prototype.addTrack_ = function addTrack_(track) { + _TrackList.prototype.addTrack_.call(this, track); + + /** + * @listens TextTrack#modechange + * @fires TrackList#change + */ + track.addEventListener('modechange', Fn.bind(this, function () { + this.trigger('change'); + })); + }; + + return TextTrackList; +}(_trackList2['default']); + +exports['default'] = TextTrackList; + +},{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _dom = _dereq_(81); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _obj = _dereq_(88); + +var Obj = _interopRequireWildcard(_obj); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track-settings.js + */ + + +var LOCAL_STORAGE_KEY = 'vjs-text-track-settings'; + +var COLOR_BLACK = ['#000', 'Black']; +var COLOR_BLUE = ['#00F', 'Blue']; +var COLOR_CYAN = ['#0FF', 'Cyan']; +var COLOR_GREEN = ['#0F0', 'Green']; +var COLOR_MAGENTA = ['#F0F', 'Magenta']; +var COLOR_RED = ['#F00', 'Red']; +var COLOR_WHITE = ['#FFF', 'White']; +var COLOR_YELLOW = ['#FF0', 'Yellow']; + +var OPACITY_OPAQUE = ['1', 'Opaque']; +var OPACITY_SEMI = ['0.5', 'Semi-Transparent']; +var OPACITY_TRANS = ['0', 'Transparent']; + +// Configuration for the various <select> elements in the DOM of this component. +// +// Possible keys include: +// +// `default`: +// The default option index. Only needs to be provided if not zero. +// `parser`: +// A function which is used to parse the value from the selected option in +// a customized way. +// `selector`: +// The selector used to find the associated <select> element. +var selectConfigs = { + backgroundColor: { + selector: '.vjs-bg-color > select', + id: 'captions-background-color-%s', + label: 'Color', + options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] + }, + + backgroundOpacity: { + selector: '.vjs-bg-opacity > select', + id: 'captions-background-opacity-%s', + label: 'Transparency', + options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS] + }, + + color: { + selector: '.vjs-fg-color > select', + id: 'captions-foreground-color-%s', + label: 'Color', + options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN] + }, + + edgeStyle: { + selector: '.vjs-edge-style > select', + id: '%s', + label: 'Text Edge Style', + options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']] + }, + + fontFamily: { + selector: '.vjs-font-family > select', + id: 'captions-font-family-%s', + label: 'Font Family', + options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']] + }, + + fontPercent: { + selector: '.vjs-font-percent > select', + id: 'captions-font-size-%s', + label: 'Font Size', + options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']], + 'default': 2, + parser: function parser(v) { + return v === '1.00' ? null : Number(v); + } + }, + + textOpacity: { + selector: '.vjs-text-opacity > select', + id: 'captions-foreground-opacity-%s', + label: 'Transparency', + options: [OPACITY_OPAQUE, OPACITY_SEMI] + }, + + // Options for this object are defined below. + windowColor: { + selector: '.vjs-window-color > select', + id: 'captions-window-color-%s', + label: 'Color' + }, + + // Options for this object are defined below. + windowOpacity: { + selector: '.vjs-window-opacity > select', + id: 'captions-window-opacity-%s', + label: 'Transparency', + options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE] + } +}; + +selectConfigs.windowColor.options = selectConfigs.backgroundColor.options; + +/** + * Get the actual value of an option. + * + * @param {string} value + * The value to get + * + * @param {Function} [parser] + * Optional function to adjust the value. + * + * @return {Mixed} + * - Will be `undefined` if no value exists + * - Will be `undefined` if the given value is "none". + * - Will be the actual value otherwise. + * + * @private + */ +function parseOptionValue(value, parser) { + if (parser) { + value = parser(value); + } + + if (value && value !== 'none') { + return value; + } +} + +/** + * Gets the value of the selected <option> element within a <select> element. + * + * @param {Element} el + * the element to look in + * + * @param {Function} [parser] + * Optional function to adjust the value. + * + * @return {Mixed} + * - Will be `undefined` if no value exists + * - Will be `undefined` if the given value is "none". + * - Will be the actual value otherwise. + * + * @private + */ +function getSelectedOptionValue(el, parser) { + var value = el.options[el.options.selectedIndex].value; + + return parseOptionValue(value, parser); +} + +/** + * Sets the selected <option> element within a <select> element based on a + * given value. + * + * @param {Element} el + * The element to look in. + * + * @param {string} value + * the property to look on. + * + * @param {Function} [parser] + * Optional function to adjust the value before comparing. + * + * @private + */ +function setSelectedOption(el, value, parser) { + if (!value) { + return; + } + + for (var i = 0; i < el.options.length; i++) { + if (parseOptionValue(el.options[i].value, parser) === value) { + el.selectedIndex = i; + break; + } + } +} + +/** + * Manipulate Text Tracks settings. + * + * @extends Component + */ + +var TextTrackSettings = function (_Component) { + _inherits(TextTrackSettings, _Component); + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + function TextTrackSettings(player, options) { + _classCallCheck(this, TextTrackSettings); + + var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); + + _this.setDefaults(); + _this.hide(); + + _this.updateDisplay = Fn.bind(_this, _this.updateDisplay); + + // Grab `persistTextTrackSettings` from the player options if not passed in child options + if (options.persistTextTrackSettings === undefined) { + _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings; + } + + _this.on(_this.$('.vjs-done-button'), 'click', function () { + _this.saveSettings(); + _this.hide(); + }); + + _this.on(_this.$('.vjs-default-button'), 'click', function () { + _this.setDefaults(); + _this.updateDisplay(); + }); + + Obj.each(selectConfigs, function (config) { + _this.on(_this.$(config.selector), 'change', _this.updateDisplay); + }); + + if (_this.options_.persistTextTrackSettings) { + _this.restoreSettings(); + } + return _this; + } + + /** + * Create a <select> element with configured options. + * + * @param {string} key + * Configuration key to use during creation. + * + * @return {Element} + * The DOM element that gets created. + * @private + */ + + + TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) { + var _this2 = this; + + var config = selectConfigs[key]; + var id = config.id.replace('%s', this.id_); + + return [(0, _dom.createEl)('label', { + className: 'vjs-label', + textContent: config.label + }, { + 'for': id + }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) { + return (0, _dom.createEl)('option', { + textContent: _this2.localize(o[1]), + value: o[0] + }); + }))]; + }; + + /** + * Create foreground color element for the component + * + * @return {Element} + * The element that was created. + * + * @private + */ + + + TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() { + var legend = (0, _dom.createEl)('legend', { + textContent: this.localize('Text') + }); + + var select = this.createElSelect_('color'); + + var opacity = (0, _dom.createEl)('span', { + className: 'vjs-text-opacity vjs-opacity' + }, undefined, this.createElSelect_('textOpacity')); + + return (0, _dom.createEl)('fieldset', { + className: 'vjs-fg-color vjs-tracksetting' + }, undefined, [legend].concat(select, opacity)); + }; + + /** + * Create background color element for the component + * + * @return {Element} + * The element that was created + * + * @private + */ + + + TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() { + var legend = (0, _dom.createEl)('legend', { + textContent: this.localize('Background') + }); + + var select = this.createElSelect_('backgroundColor'); + + var opacity = (0, _dom.createEl)('span', { + className: 'vjs-bg-opacity vjs-opacity' + }, undefined, this.createElSelect_('backgroundOpacity')); + + return (0, _dom.createEl)('fieldset', { + className: 'vjs-bg-color vjs-tracksetting' + }, undefined, [legend].concat(select, opacity)); + }; + + /** + * Create window color element for the component + * + * @return {Element} + * The element that was created + * + * @private + */ + + + TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() { + var legend = (0, _dom.createEl)('legend', { + textContent: this.localize('Window') + }); + + var select = this.createElSelect_('windowColor'); + + var opacity = (0, _dom.createEl)('span', { + className: 'vjs-window-opacity vjs-opacity' + }, undefined, this.createElSelect_('windowOpacity')); + + return (0, _dom.createEl)('fieldset', { + className: 'vjs-window-color vjs-tracksetting' + }, undefined, [legend].concat(select, opacity)); + }; + + /** + * Create color elements for the component + * + * @return {Element} + * The element that was created + * + * @private + */ + + + TextTrackSettings.prototype.createElColors_ = function createElColors_() { + return (0, _dom.createEl)('div', { + className: 'vjs-tracksettings-colors' + }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]); + }; + + /** + * Create font elements for the component + * + * @return {Element} + * The element that was created. + * + * @private + */ + + + TextTrackSettings.prototype.createElFont_ = function createElFont_() { + var fontPercent = (0, _dom.createEl)('div', { + className: 'vjs-font-percent vjs-tracksetting' + }, undefined, this.createElSelect_('fontPercent')); + + var edgeStyle = (0, _dom.createEl)('div', { + className: 'vjs-edge-style vjs-tracksetting' + }, undefined, this.createElSelect_('edgeStyle')); + + var fontFamily = (0, _dom.createEl)('div', { + className: 'vjs-font-family vjs-tracksetting' + }, undefined, this.createElSelect_('fontFamily')); + + return (0, _dom.createEl)('div', { + className: 'vjs-tracksettings-font' + }, undefined, [fontPercent, edgeStyle, fontFamily]); + }; + + /** + * Create controls for the component + * + * @return {Element} + * The element that was created. + * + * @private + */ + + + TextTrackSettings.prototype.createElControls_ = function createElControls_() { + var defaultsButton = (0, _dom.createEl)('button', { + className: 'vjs-default-button', + textContent: this.localize('Defaults') + }); + + var doneButton = (0, _dom.createEl)('button', { + className: 'vjs-done-button', + textContent: 'Done' + }); + + return (0, _dom.createEl)('div', { + className: 'vjs-tracksettings-controls' + }, undefined, [defaultsButton, doneButton]); + }; + + /** + * Create the component's DOM element + * + * @return {Element} + * The element that was created. + */ + + + TextTrackSettings.prototype.createEl = function createEl() { + var settings = (0, _dom.createEl)('div', { + className: 'vjs-tracksettings' + }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]); + + var heading = (0, _dom.createEl)('div', { + className: 'vjs-control-text', + id: 'TTsettingsDialogLabel-' + this.id_, + textContent: 'Caption Settings Dialog' + }, { + 'aria-level': '1', + 'role': 'heading' + }); + + var description = (0, _dom.createEl)('div', { + className: 'vjs-control-text', + id: 'TTsettingsDialogDescription-' + this.id_, + textContent: 'Beginning of dialog window. Escape will cancel and close the window.' + }); + + var doc = (0, _dom.createEl)('div', undefined, { + role: 'document' + }, [heading, description, settings]); + + return (0, _dom.createEl)('div', { + className: 'vjs-caption-settings vjs-modal-overlay', + tabIndex: -1 + }, { + 'role': 'dialog', + 'aria-labelledby': heading.id, + 'aria-describedby': description.id + }, doc); + }; + + /** + * Gets an object of text track settings (or null). + * + * @return {Object} + * An object with config values parsed from the DOM or localStorage. + */ + + + TextTrackSettings.prototype.getValues = function getValues() { + var _this3 = this; + + return Obj.reduce(selectConfigs, function (accum, config, key) { + var value = getSelectedOptionValue(_this3.$(config.selector), config.parser); + + if (value !== undefined) { + accum[key] = value; + } + + return accum; + }, {}); + }; + + /** + * Sets text track settings from an object of values. + * + * @param {Object} values + * An object with config values parsed from the DOM or localStorage. + */ + + + TextTrackSettings.prototype.setValues = function setValues(values) { + var _this4 = this; + + Obj.each(selectConfigs, function (config, key) { + setSelectedOption(_this4.$(config.selector), values[key], config.parser); + }); + }; + + /** + * Sets all <select> elements to their default values. + */ + + + TextTrackSettings.prototype.setDefaults = function setDefaults() { + var _this5 = this; + + Obj.each(selectConfigs, function (config) { + var index = config.hasOwnProperty('default') ? config['default'] : 0; + + _this5.$(config.selector).selectedIndex = index; + }); + }; + + /** + * Restore texttrack settings from localStorage + */ + + + TextTrackSettings.prototype.restoreSettings = function restoreSettings() { + var values = void 0; + + try { + values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY)); + } catch (err) { + _log2['default'].warn(err); + } + + if (values) { + this.setValues(values); + } + }; + + /** + * Save text track settings to localStorage + */ + + + TextTrackSettings.prototype.saveSettings = function saveSettings() { + if (!this.options_.persistTextTrackSettings) { + return; + } + + var values = this.getValues(); + + try { + if (Object.keys(values).length) { + _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values)); + } else { + _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY); + } + } catch (err) { + _log2['default'].warn(err); + } + }; + + /** + * Update display of text track settings + */ + + + TextTrackSettings.prototype.updateDisplay = function updateDisplay() { + var ttDisplay = this.player_.getChild('textTrackDisplay'); + + if (ttDisplay) { + ttDisplay.updateDisplay(); + } + }; + + return TextTrackSettings; +}(_component2['default']); + +_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings); + +exports['default'] = TextTrackSettings; + +},{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _textTrackCueList = _dereq_(67); + +var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _trackEnums = _dereq_(73); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _track = _dereq_(75); + +var _track2 = _interopRequireDefault(_track); + +var _url = _dereq_(92); + +var _xhr = _dereq_(99); + +var _xhr2 = _interopRequireDefault(_xhr); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file text-track.js + */ + + +/** + * Takes a webvtt file contents and parses it into cues + * + * @param {string} srcContent + * webVTT file contents + * + * @param {TextTrack} track + * TextTrack to add cues to. Cues come from the srcContent. + * + * @private + */ +var parseCues = function parseCues(srcContent, track) { + var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder()); + var errors = []; + + parser.oncue = function (cue) { + track.addCue(cue); + }; + + parser.onparsingerror = function (error) { + errors.push(error); + }; + + parser.onflush = function () { + track.trigger({ + type: 'loadeddata', + target: track + }); + }; + + parser.parse(srcContent); + if (errors.length > 0) { + if (_window2['default'].console && _window2['default'].console.groupCollapsed) { + _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src); + } + errors.forEach(function (error) { + return _log2['default'].error(error); + }); + if (_window2['default'].console && _window2['default'].console.groupEnd) { + _window2['default'].console.groupEnd(); + } + } + + parser.flush(); +}; + +/** + * Load a `TextTrack` from a specifed url. + * + * @param {string} src + * Url to load track from. + * + * @param {TextTrack} track + * Track to add cues to. Comes from the content at the end of `url`. + * + * @private + */ +var loadTrack = function loadTrack(src, track) { + var opts = { + uri: src + }; + var crossOrigin = (0, _url.isCrossOrigin)(src); + + if (crossOrigin) { + opts.cors = crossOrigin; + } + + (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) { + if (err) { + return _log2['default'].error(err, response); + } + + track.loaded_ = true; + + // Make sure that vttjs has loaded, otherwise, wait till it finished loading + // NOTE: this is only used for the alt/video.novtt.js build + if (typeof _window2['default'].WebVTT !== 'function') { + if (track.tech_) { + (function () { + var loadHandler = function loadHandler() { + return parseCues(responseBody, track); + }; + + track.tech_.on('vttjsloaded', loadHandler); + track.tech_.on('vttjserror', function () { + _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src); + track.tech_.off('vttjsloaded', loadHandler); + }); + })(); + } + } else { + parseCues(responseBody, track); + } + })); +}; + +/** + * A representation of a single `TextTrack`. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack} + * @extends Track + */ + +var TextTrack = function (_Track) { + _inherits(TextTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} options={} + * Object of option names and values + * + * @param {Tech} options.tech + * A reference to the tech that owns this TextTrack. + * + * @param {TextTrack~Kind} [options.kind='subtitles'] + * A valid text track kind. + * + * @param {TextTrack~Mode} [options.mode='disabled'] + * A valid text track mode. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this TextTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {string} [options.srclang=''] + * A valid two character language code. An alternative, but deprioritized + * vesion of `options.language` + * + * @param {string} [options.src] + * A url to TextTrack cues. + * + * @param {boolean} [options.default] + * If this track should default to on or off. + */ + function TextTrack() { + var _this, _ret2; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, TextTrack); + + if (!options.tech) { + throw new Error('A tech was not provided.'); + } + + var settings = (0, _mergeOptions2['default'])(options, { + kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles', + language: options.language || options.srclang || '' + }); + var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled'; + var default_ = settings['default']; + + if (settings.kind === 'metadata' || settings.kind === 'chapters') { + mode = 'hidden'; + } + // on IE8 this will be a document element + // for every other browser this will be a normal object + var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); + + tt.tech_ = settings.tech; + + if (browser.IS_IE8) { + for (var prop in TextTrack.prototype) { + if (prop !== 'constructor') { + tt[prop] = TextTrack.prototype[prop]; + } + } + } + + tt.cues_ = []; + tt.activeCues_ = []; + + var cues = new _textTrackCueList2['default'](tt.cues_); + var activeCues = new _textTrackCueList2['default'](tt.activeCues_); + var changed = false; + var timeupdateHandler = Fn.bind(tt, function () { + + // Accessing this.activeCues for the side-effects of updating itself + // due to it's nature as a getter function. Do not remove or cues will + // stop updating! + /* eslint-disable no-unused-expressions */ + this.activeCues; + /* eslint-enable no-unused-expressions */ + if (changed) { + this.trigger('cuechange'); + changed = false; + } + }); + + if (mode !== 'disabled') { + tt.tech_.on('timeupdate', timeupdateHandler); + } + + /** + * @member {boolean} default + * If this track was set to be on or off by default. Cannot be changed after + * creation. + * + * @readonly + */ + Object.defineProperty(tt, 'default', { + get: function get() { + return default_; + }, + set: function set() {} + }); + + /** + * @member {string} mode + * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will + * not be set if setting to an invalid mode. + * + * @fires TextTrack#modechange + */ + Object.defineProperty(tt, 'mode', { + get: function get() { + return mode; + }, + set: function set(newMode) { + if (!_trackEnums.TextTrackMode[newMode]) { + return; + } + mode = newMode; + if (mode === 'showing') { + this.tech_.on('timeupdate', timeupdateHandler); + } + /** + * An event that fires when mode changes on this track. This allows + * the TextTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! + * + * @event TextTrack#modechange + * @type {EventTarget~Event} + */ + this.trigger('modechange'); + } + }); + + /** + * @member {TextTrackCueList} cues + * The text track cue list for this TextTrack. + */ + Object.defineProperty(tt, 'cues', { + get: function get() { + if (!this.loaded_) { + return null; + } + + return cues; + }, + set: function set() {} + }); + + /** + * @member {TextTrackCueList} activeCues + * The list text track cues that are currently active for this TextTrack. + */ + Object.defineProperty(tt, 'activeCues', { + get: function get() { + if (!this.loaded_) { + return null; + } + + // nothing to do + if (this.cues.length === 0) { + return activeCues; + } + + var ct = this.tech_.currentTime(); + var active = []; + + for (var i = 0, l = this.cues.length; i < l; i++) { + var cue = this.cues[i]; + + if (cue.startTime <= ct && cue.endTime >= ct) { + active.push(cue); + } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) { + active.push(cue); + } + } + + changed = false; + + if (active.length !== this.activeCues_.length) { + changed = true; + } else { + for (var _i = 0; _i < active.length; _i++) { + if (this.activeCues_.indexOf(active[_i]) === -1) { + changed = true; + } + } + } + + this.activeCues_ = active; + activeCues.setCues_(this.activeCues_); + + return activeCues; + }, + set: function set() {} + }); + + if (settings.src) { + tt.src = settings.src; + loadTrack(settings.src, tt); + } else { + tt.loaded_ = true; + } + + return _ret2 = tt, _possibleConstructorReturn(_this, _ret2); + } + + /** + * Add a cue to the internal list of cues. + * + * @param {TextTrack~Cue} cue + * The cue to add to our internal list + */ + + + TextTrack.prototype.addCue = function addCue(cue) { + var tracks = this.tech_.textTracks(); + + if (tracks) { + for (var i = 0; i < tracks.length; i++) { + if (tracks[i] !== this) { + tracks[i].removeCue(cue); + } + } + } + + this.cues_.push(cue); + this.cues.setCues_(this.cues_); + }; + + /** + * Remove a cue from our internal list + * + * @param {TextTrack~Cue} removeCue + * The cue to remove from our internal list + */ + + + TextTrack.prototype.removeCue = function removeCue(_removeCue) { + var removed = false; + + for (var i = 0, l = this.cues_.length; i < l; i++) { + var cue = this.cues_[i]; + + if (cue === _removeCue) { + this.cues_.splice(i, 1); + removed = true; + } + } + + if (removed) { + this.cues.setCues_(this.cues_); + } + }; + + return TextTrack; +}(_track2['default']); + +/** + * cuechange - One or more cues in the track have become active or stopped being active. + */ + + +TextTrack.prototype.allowedEvents_ = { + cuechange: 'cuechange' +}; + +exports['default'] = TextTrack; + +},{"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95,"99":99}],73:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +/** + * @file track-kinds.js + */ + +/** + * All possible `VideoTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind + * @typedef VideoTrack~Kind + * @enum + */ +var VideoTrackKind = exports.VideoTrackKind = { + alternative: 'alternative', + captions: 'captions', + main: 'main', + sign: 'sign', + subtitles: 'subtitles', + commentary: 'commentary' +}; + +/** + * All possible `AudioTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind + * @typedef AudioTrack~Kind + * @enum + */ +var AudioTrackKind = exports.AudioTrackKind = { + 'alternative': 'alternative', + 'descriptions': 'descriptions', + 'main': 'main', + 'main-desc': 'main-desc', + 'translation': 'translation', + 'commentary': 'commentary' +}; + +/** + * All possible `TextTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind + * @typedef TextTrack~Kind + * @enum + */ +var TextTrackKind = exports.TextTrackKind = { + subtitles: 'subtitles', + captions: 'captions', + descriptions: 'descriptions', + chapters: 'chapters', + metadata: 'metadata' +}; + +/** + * All possible `TextTrackMode`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode + * @typedef TextTrack~Mode + * @enum + */ +var TextTrackMode = exports.TextTrackMode = { + disabled: 'disabled', + hidden: 'hidden', + showing: 'showing' +}; + +},{}],74:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _eventTarget = _dereq_(42); + +var _eventTarget2 = _interopRequireDefault(_eventTarget); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file track-list.js + */ + + +/** + * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and + * {@link VideoTrackList} + * + * @extends EventTarget + */ +var TrackList = function (_EventTarget) { + _inherits(TrackList, _EventTarget); + + /** + * Create an instance of this class + * + * @param {Track[]} tracks + * A list of tracks to initialize the list with. + * + * @param {Object} [list] + * The child object with inheritance done manually for ie8. + * + * @abstract + */ + function TrackList() { + var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + var _ret; + + var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + _classCallCheck(this, TrackList); + + var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); + + if (!list) { + list = _this; // eslint-disable-line + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + for (var prop in TrackList.prototype) { + if (prop !== 'constructor') { + list[prop] = TrackList.prototype[prop]; + } + } + } + } + + list.tracks_ = []; + + /** + * @member {number} length + * The current number of `Track`s in the this Trackist. + */ + Object.defineProperty(list, 'length', { + get: function get() { + return this.tracks_.length; + } + }); + + for (var i = 0; i < tracks.length; i++) { + list.addTrack_(tracks[i]); + } + + // must return the object, as for ie8 it will not be this + // but a reference to a document object + return _ret = list, _possibleConstructorReturn(_this, _ret); + } + + /** + * Add a {@link Track} to the `TrackList` + * + * @param {Track} track + * The audio, video, or text track to add to the list. + * + * @fires TrackList#addtrack + * @private + */ + + + TrackList.prototype.addTrack_ = function addTrack_(track) { + var index = this.tracks_.length; + + if (!('' + index in this)) { + Object.defineProperty(this, index, { + get: function get() { + return this.tracks_[index]; + } + }); + } + + // Do not add duplicate tracks + if (this.tracks_.indexOf(track) === -1) { + this.tracks_.push(track); + /** + * Triggered when a track is added to a track list. + * + * @event TrackList#addtrack + * @type {EventTarget~Event} + * @property {Track} track + * A reference to track that was added. + */ + this.trigger({ + track: track, + type: 'addtrack' + }); + } + }; + + /** + * Remove a {@link Track} from the `TrackList` + * + * @param {Track} track + * The audio, video, or text track to remove from the list. + * + * @fires TrackList#removetrack + * @private + */ + + + TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) { + var track = void 0; + + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === rtrack) { + track = this[i]; + if (track.off) { + track.off(); + } + + this.tracks_.splice(i, 1); + + break; + } + } + + if (!track) { + return; + } + + /** + * Triggered when a track is removed from track list. + * + * @event TrackList#removetrack + * @type {EventTarget~Event} + * @property {Track} track + * A reference to track that was removed. + */ + this.trigger({ + track: track, + type: 'removetrack' + }); + }; + + /** + * Get a Track from the TrackList by a tracks id + * + * @param {String} id - the id of the track to get + * @method getTrackById + * @return {Track} + * @private + */ + + + TrackList.prototype.getTrackById = function getTrackById(id) { + var result = null; + + for (var i = 0, l = this.length; i < l; i++) { + var track = this[i]; + + if (track.id === id) { + result = track; + break; + } + } + + return result; + }; + + return TrackList; +}(_eventTarget2['default']); + +/** + * Triggered when a different track is selected/enabled. + * + * @event TrackList#change + * @type {EventTarget~Event} + */ + +/** + * Events that can be called with on + eventName. See {@link EventHandler}. + * + * @property {Object} TrackList#allowedEvents_ + * @private + */ + + +TrackList.prototype.allowedEvents_ = { + change: 'change', + addtrack: 'addtrack', + removetrack: 'removetrack' +}; + +// emulate attribute EventHandler support to allow for feature detection +for (var event in TrackList.prototype.allowedEvents_) { + TrackList.prototype['on' + event] = null; +} + +exports['default'] = TrackList; + +},{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _guid = _dereq_(85); + +var Guid = _interopRequireWildcard(_guid); + +var _eventTarget = _dereq_(42); + +var _eventTarget2 = _interopRequireDefault(_eventTarget); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file track.js + */ + + +/** + * A Track class that contains all of the common functionality for {@link AudioTrack}, + * {@link VideoTrack}, and {@link TextTrack}. + * + * > Note: This class should not be used directly + * + * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html} + * @extends EventTarget + * @abstract + */ +var Track = function (_EventTarget) { + _inherits(Track, _EventTarget); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {string} [options.kind=''] + * A valid kind for the track type you are creating. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @abstract + */ + function Track() { + var _ret; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Track); + + var _this = _possibleConstructorReturn(this, _EventTarget.call(this)); + + var track = _this; // eslint-disable-line + + if (browser.IS_IE8) { + track = _document2['default'].createElement('custom'); + for (var prop in Track.prototype) { + if (prop !== 'constructor') { + track[prop] = Track.prototype[prop]; + } + } + } + + var trackProps = { + id: options.id || 'vjs_track_' + Guid.newGUID(), + kind: options.kind || '', + label: options.label || '', + language: options.language || '' + }; + + /** + * @member {string} id + * The id of this track. Cannot be changed after creation. + * + * @readonly + */ + + /** + * @member {string} kind + * The kind of track that this is. Cannot be changed after creation. + * + * @readonly + */ + + /** + * @member {string} label + * The label of this track. Cannot be changed after creation. + * + * @readonly + */ + + /** + * @member {string} language + * The two letter language code for this track. Cannot be changed after + * creation. + * + * @readonly + */ + + var _loop = function _loop(key) { + Object.defineProperty(track, key, { + get: function get() { + return trackProps[key]; + }, + set: function set() {} + }); + }; + + for (var key in trackProps) { + _loop(key); + } + + return _ret = track, _possibleConstructorReturn(_this, _ret); + } + + return Track; +}(_eventTarget2['default']); + +exports['default'] = Track; + +},{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackList = _dereq_(74); + +var _trackList2 = _interopRequireDefault(_trackList); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** + * @file video-track-list.js + */ + + +/** + * Un-select all other {@link VideoTrack}s that are selected. + * + * @param {VideoTrackList} list + * list to work on + * + * @param {VideoTrack} track + * The track to skip + * + * @private + */ +var disableOthers = function disableOthers(list, track) { + for (var i = 0; i < list.length; i++) { + if (track.id === list[i].id) { + continue; + } + // another video track is enabled, disable it + list[i].selected = false; + } +}; + +/** + * The current list of {@link VideoTrack} for a video. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist} + * @extends TrackList + */ + +var VideoTrackList = function (_TrackList) { + _inherits(VideoTrackList, _TrackList); + + /** + * Create an instance of this class. + * + * @param {VideoTrack[]} [tracks=[]] + * A list of `VideoTrack` to instantiate the list with. + */ + function VideoTrackList() { + var _this, _ret; + + var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + _classCallCheck(this, VideoTrackList); + + var list = void 0; + + // make sure only 1 track is enabled + // sorted from last index to first index + for (var i = tracks.length - 1; i >= 0; i--) { + if (tracks[i].selected) { + disableOthers(tracks, tracks[i]); + break; + } + } + + // IE8 forces us to implement inheritance ourselves + // as it does not support Object.defineProperty properly + if (browser.IS_IE8) { + list = _document2['default'].createElement('custom'); + for (var prop in _trackList2['default'].prototype) { + if (prop !== 'constructor') { + list[prop] = _trackList2['default'].prototype[prop]; + } + } + for (var _prop in VideoTrackList.prototype) { + if (_prop !== 'constructor') { + list[_prop] = VideoTrackList.prototype[_prop]; + } + } + } + + list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this); + list.changing_ = false; + + /** + * @member {number} VideoTrackList#selectedIndex + * The current index of the selected {@link VideoTrack`}. + */ + Object.defineProperty(list, 'selectedIndex', { + get: function get() { + for (var _i = 0; _i < this.length; _i++) { + if (this[_i].selected) { + return _i; + } + } + return -1; + }, + set: function set() {} + }); + + return _ret = list, _possibleConstructorReturn(_this, _ret); + } + + /** + * Add a {@link VideoTrack} to the `VideoTrackList`. + * + * @param {VideoTrack} track + * The VideoTrack to add to the list + * + * @fires TrackList#addtrack + * @private + */ + + + VideoTrackList.prototype.addTrack_ = function addTrack_(track) { + var _this2 = this; + + if (track.selected) { + disableOthers(this, track); + } + + _TrackList.prototype.addTrack_.call(this, track); + // native tracks don't have this + if (!track.addEventListener) { + return; + } + + /** + * @listens VideoTrack#selectedchange + * @fires TrackList#change + */ + track.addEventListener('selectedchange', function () { + if (_this2.changing_) { + return; + } + _this2.changing_ = true; + disableOthers(_this2, track); + _this2.changing_ = false; + _this2.trigger('change'); + }); + }; + + /** + * Add a {@link VideoTrack} to the `VideoTrackList`. + * + * @param {VideoTrack} track + * The VideoTrack to add to the list + * + * @fires TrackList#addtrack + */ + + + VideoTrackList.prototype.addTrack = function addTrack(track) { + this.addTrack_(track); + }; + + /** + * Remove a {@link VideoTrack} to the `VideoTrackList`. + * + * @param {VideoTrack} track + * The VideoTrack to remove from the list. + * + * @fires TrackList#removetrack + */ + + + VideoTrackList.prototype.removeTrack = function removeTrack(track) { + _TrackList.prototype.removeTrack_.call(this, track); + }; + + return VideoTrackList; +}(_trackList2['default']); + +exports['default'] = VideoTrackList; + +},{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _trackEnums = _dereq_(73); + +var _track = _dereq_(75); + +var _track2 = _interopRequireDefault(_track); + +var _mergeOptions = _dereq_(87); + +var _mergeOptions2 = _interopRequireDefault(_mergeOptions); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * A representation of a single `VideoTrack`. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack} + * @extends Track + */ +var VideoTrack = function (_Track) { + _inherits(VideoTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {string} [options.kind=''] + * A valid {@link VideoTrack~Kind} + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {boolean} [options.selected] + * If this track is the one that is currently playing. + */ + function VideoTrack() { + var _this, _ret; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, VideoTrack); + + var settings = (0, _mergeOptions2['default'])(options, { + kind: _trackEnums.VideoTrackKind[options.kind] || '' + }); + + // on IE8 this will be a document element + // for every other browser this will be a normal object + var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this); + var selected = false; + + if (browser.IS_IE8) { + for (var prop in VideoTrack.prototype) { + if (prop !== 'constructor') { + track[prop] = VideoTrack.prototype[prop]; + } + } + } + + /** + * @member {boolean} selected + * If this `VideoTrack` is selected or not. When setting this will + * fire {@link VideoTrack#selectedchange} if the state of selected changed. + * + * @fires VideoTrack#selectedchange + */ + Object.defineProperty(track, 'selected', { + get: function get() { + return selected; + }, + set: function set(newSelected) { + // an invalid or unchanged value + if (typeof newSelected !== 'boolean' || newSelected === selected) { + return; + } + selected = newSelected; + + /** + * An event that fires when selected changes on this track. This allows + * the VideoTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! Native tracks will do + * this internally without an event. + * + * @event VideoTrack#selectedchange + * @type {EventTarget~Event} + */ + this.trigger('selectedchange'); + } + }); + + // if the user sets this track to selected then + // set selected to that true value otherwise + // we keep it false + if (settings.selected) { + track.selected = settings.selected; + } + + return _ret = track, _possibleConstructorReturn(_this, _ret); + } + + return VideoTrack; +}(_track2['default']); + +exports['default'] = VideoTrack; + +},{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exports.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined; + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +/** + * @file browser.js + * @module browser + */ +var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; +var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); +var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; + +/* + * Device is an iPhone + * + * @type {Boolean} + * @constant + * @private + */ +var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT); + +// The Facebook app's UIWebView identifies as both an iPhone and iPad, so +// to identify iPhones, we need to exclude iPads. +// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ +var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; +var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT); +var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; + +var IOS_VERSION = exports.IOS_VERSION = function () { + var match = USER_AGENT.match(/OS (\d+)_/i); + + if (match && match[1]) { + return match[1]; + } + return null; +}(); + +var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT); +var ANDROID_VERSION = exports.ANDROID_VERSION = function () { + // This matches Android Major.Minor.Patch versions + // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned + var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); + + if (!match) { + return null; + } + + var major = match[1] && parseFloat(match[1]); + var minor = match[2] && parseFloat(match[2]); + + if (major && minor) { + return parseFloat(match[1] + '.' + match[2]); + } else if (major) { + return major; + } + return null; +}(); + +// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser +var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; +var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; + +var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT); +var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT); +var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT); +var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); +var IE_VERSION = exports.IE_VERSION = function (result) { + return result && parseFloat(result[1]); +}(/MSIE\s(\d+)\.\d/.exec(USER_AGENT)); + +var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; +var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS; + +var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch); + +var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style; + +},{"81":81,"95":95}],79:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.bufferedPercent = bufferedPercent; + +var _timeRanges = _dereq_(90); + +/** + * Compute the percentage of the media that has been buffered. + * + * @param {TimeRange} buffered + * The current `TimeRange` object representing buffered time ranges + * + * @param {number} duration + * Total duration of the media + * + * @return {number} + * Percent buffered of the total duration in decimal form. + */ +function bufferedPercent(buffered, duration) { + var bufferedDuration = 0; + var start = void 0; + var end = void 0; + + if (!duration) { + return 0; + } + + if (!buffered || !buffered.length) { + buffered = (0, _timeRanges.createTimeRange)(0, 0); + } + + for (var i = 0; i < buffered.length; i++) { + start = buffered.start(i); + end = buffered.end(i); + + // buffered end can be bigger than duration by a very small fraction + if (end > duration) { + end = duration; + } + + bufferedDuration += end - start; + } + + return bufferedDuration / duration; +} /** + * @file buffer.js + * @module buffer + */ + +},{"90":90}],80:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports['default'] = computedStyle; + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * A safe getComputedStyle with an IE8 fallback. + * + * This is needed because in Firefox, if the player is loaded in an iframe with + * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to + * make sure that the player doesn't break in these cases. + * + * @param {Element} el + * The element you want the computed style of + * + * @param {string} prop + * The property name you want + * + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 + */ +function computedStyle(el, prop) { + if (!el || !prop) { + return ''; + } + + if (typeof _window2['default'].getComputedStyle === 'function') { + var cs = _window2['default'].getComputedStyle(el); + + return cs ? cs[prop] : ''; + } + + return el.currentStyle[prop] || ''; +} /** + * @file computed-style.js + * @module computed-style + */ + +},{"95":95}],81:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.$$ = exports.$ = undefined; + +var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']); + +exports.isReal = isReal; +exports.isEl = isEl; +exports.getEl = getEl; +exports.createEl = createEl; +exports.textContent = textContent; +exports.insertElFirst = insertElFirst; +exports.getElData = getElData; +exports.hasElData = hasElData; +exports.removeElData = removeElData; +exports.hasElClass = hasElClass; +exports.addElClass = addElClass; +exports.removeElClass = removeElClass; +exports.toggleElClass = toggleElClass; +exports.setElAttributes = setElAttributes; +exports.getElAttributes = getElAttributes; +exports.getAttribute = getAttribute; +exports.setAttribute = setAttribute; +exports.removeAttribute = removeAttribute; +exports.blockTextSelection = blockTextSelection; +exports.unblockTextSelection = unblockTextSelection; +exports.findElPosition = findElPosition; +exports.getPointerPosition = getPointerPosition; +exports.isTextNode = isTextNode; +exports.emptyEl = emptyEl; +exports.normalizeContent = normalizeContent; +exports.appendContent = appendContent; +exports.insertContent = insertContent; + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _guid = _dereq_(85); + +var Guid = _interopRequireWildcard(_guid); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _tsml = _dereq_(98); + +var _tsml2 = _interopRequireDefault(_tsml); + +var _obj = _dereq_(88); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /** + * @file dom.js + * @module dom + */ + + +/** + * Detect if a value is a string with any non-whitespace characters. + * + * @param {string} str + * The string to check + * + * @return {boolean} + * - True if the string is non-blank + * - False otherwise + * + */ +function isNonBlankString(str) { + return typeof str === 'string' && /\S/.test(str); +} + +/** + * Throws an error if the passed string has whitespace. This is used by + * class methods to be relatively consistent with the classList API. + * + * @param {string} str + * The string to check for whitespace. + * + * @throws {Error} + * Throws an error if there is whitespace in the string. + * + */ +function throwIfWhitespace(str) { + if (/\s/.test(str)) { + throw new Error('class has illegal whitespace characters'); + } +} + +/** + * Produce a regular expression for matching a className within an elements className. + * + * @param {string} className + * The className to generate the RegExp for. + * + * @return {RegExp} + * The RegExp that will check for a specific `className` in an elements + * className. + */ +function classRegExp(className) { + return new RegExp('(^|\\s)' + className + '($|\\s)'); +} + +/** + * Whether the current DOM interface appears to be real. + * + * @return {Boolean} + */ +function isReal() { + return ( + + // Both document and window will never be undefined thanks to `global`. + _document2['default'] === _window2['default'].document && + + // In IE < 9, DOM methods return "object" as their type, so all we can + // confidently check is that it exists. + typeof _document2['default'].createElement !== 'undefined' + ); +} + +/** + * Determines, via duck typing, whether or not a value is a DOM element. + * + * @param {Mixed} value + * The thing to check + * + * @return {boolean} + * - True if it is a DOM element + * - False otherwise + */ +function isEl(value) { + return (0, _obj.isObject)(value) && value.nodeType === 1; +} + +/** + * Creates functions to query the DOM using a given method. + * + * @param {string} method + * The method to create the query with. + * + * @return {Function} + * The query method + */ +function createQuerier(method) { + return function (selector, context) { + if (!isNonBlankString(selector)) { + return _document2['default'][method](null); + } + if (isNonBlankString(context)) { + context = _document2['default'].querySelector(context); + } + + var ctx = isEl(context) ? context : _document2['default']; + + return ctx[method] && ctx[method](selector); + }; +} + +/** + * Shorthand for document.getElementById() + * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. + * + * @param {string} id + * The id of the element to get + * + * @return {Element|null} + * Element with supplied ID or null if there wasn't one. + */ +function getEl(id) { + if (id.indexOf('#') === 0) { + id = id.slice(1); + } + + return _document2['default'].getElementById(id); +} + +/** + * Creates an element and applies properties. + * + * @param {string} [tagName='div'] + * Name of tag to be created. + * + * @param {Object} [properties={}] + * Element properties to be applied. + * + * @param {Object} [attributes={}] + * Element attributes to be applied. + * + * @param {String|Element|TextNode|Array|Function} [content] + * Contents for the element (see: {@link dom:normalizeContent}) + * + * @return {Element} + * The element that was created. + */ +function createEl() { + var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; + var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var content = arguments[3]; + + var el = _document2['default'].createElement(tagName); + + Object.getOwnPropertyNames(properties).forEach(function (propName) { + var val = properties[propName]; + + // See #2176 + // We originally were accepting both properties and attributes in the + // same object, but that doesn't work so well. + if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { + _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val)); + el.setAttribute(propName, val); + + // Handle textContent since it's not supported everywhere and we have a + // method for it. + } else if (propName === 'textContent') { + textContent(el, val); + } else { + el[propName] = val; + } + }); + + Object.getOwnPropertyNames(attributes).forEach(function (attrName) { + el.setAttribute(attrName, attributes[attrName]); + }); + + if (content) { + appendContent(el, content); + } + + return el; +} + +/** + * Injects text into an element, replacing any existing contents entirely. + * + * @param {Element} el + * The element to add text content into + * + * @param {string} text + * The text content to add. + * + * @return {Element} + * The element with added text content. + */ +function textContent(el, text) { + if (typeof el.textContent === 'undefined') { + el.innerText = text; + } else { + el.textContent = text; + } + return el; +} + +/** + * Insert an element as the first child node of another + * + * @param {Element} child + * Element to insert + * + * @param {Element} parent + * Element to insert child into + * + */ +function insertElFirst(child, parent) { + if (parent.firstChild) { + parent.insertBefore(child, parent.firstChild); + } else { + parent.appendChild(child); + } +} + +/** + * Element Data Store. Allows for binding data to an element without putting it directly on the element. + * Ex. Event listeners are stored here. + * (also from jsninja.com, slightly modified and updated for closure compiler) + * + * @type {Object} + * @private + */ +var elData = {}; + +/* + * Unique attribute name to store an element's guid in + * + * @type {string} + * @constant + * @private + */ +var elIdAttr = 'vdata' + new Date().getTime(); + +/** + * Returns the cache object where data for an element is stored + * + * @param {Element} el + * Element to store data for. + * + * @return {Object} + * The cache object for that el that was passed in. + */ +function getElData(el) { + var id = el[elIdAttr]; + + if (!id) { + id = el[elIdAttr] = Guid.newGUID(); + } + + if (!elData[id]) { + elData[id] = {}; + } + + return elData[id]; +} + +/** + * Returns whether or not an element has cached data + * + * @param {Element} el + * Check if this element has cached data. + * + * @return {boolean} + * - True if the DOM element has cached data. + * - False otherwise. + */ +function hasElData(el) { + var id = el[elIdAttr]; + + if (!id) { + return false; + } + + return !!Object.getOwnPropertyNames(elData[id]).length; +} + +/** + * Delete data for the element from the cache and the guid attr from getElementById + * + * @param {Element} el + * Remove cached data for this element. + */ +function removeElData(el) { + var id = el[elIdAttr]; + + if (!id) { + return; + } + + // Remove all stored data + delete elData[id]; + + // Remove the elIdAttr property from the DOM node + try { + delete el[elIdAttr]; + } catch (e) { + if (el.removeAttribute) { + el.removeAttribute(elIdAttr); + } else { + // IE doesn't appear to support removeAttribute on the document element + el[elIdAttr] = null; + } + } +} + +/** + * Check if an element has a CSS class + * + * @param {Element} element + * Element to check + * + * @param {string} classToCheck + * Class name to check for + * + * @return {boolean} + * - True if the element had the class + * - False otherwise. + * + * @throws {Error} + * Throws an error if `classToCheck` has white space. + */ +function hasElClass(element, classToCheck) { + throwIfWhitespace(classToCheck); + if (element.classList) { + return element.classList.contains(classToCheck); + } + return classRegExp(classToCheck).test(element.className); +} + +/** + * Add a CSS class name to an element + * + * @param {Element} element + * Element to add class name to. + * + * @param {string} classToAdd + * Class name to add. + * + * @return {Element} + * The dom element with the added class name. + */ +function addElClass(element, classToAdd) { + if (element.classList) { + element.classList.add(classToAdd); + + // Don't need to `throwIfWhitespace` here because `hasElClass` will do it + // in the case of classList not being supported. + } else if (!hasElClass(element, classToAdd)) { + element.className = (element.className + ' ' + classToAdd).trim(); + } + + return element; +} + +/** + * Remove a CSS class name from an element + * + * @param {Element} element + * Element to remove a class name from. + * + * @param {string} classToRemove + * Class name to remove + * + * @return {Element} + * The dom element with class name removed. + */ +function removeElClass(element, classToRemove) { + if (element.classList) { + element.classList.remove(classToRemove); + } else { + throwIfWhitespace(classToRemove); + element.className = element.className.split(/\s+/).filter(function (c) { + return c !== classToRemove; + }).join(' '); + } + + return element; +} + +/** + * The callback definition for toggleElClass. + * + * @callback Dom~PredicateCallback + * @param {Element} element + * The DOM element of the Component. + * + * @param {string} classToToggle + * The `className` that wants to be toggled + * + * @return {boolean|undefined} + * - If true the `classToToggle` will get added to `element`. + * - If false the `classToToggle` will get removed from `element`. + * - If undefined this callback will be ignored + */ + +/** + * Adds or removes a CSS class name on an element depending on an optional + * condition or the presence/absence of the class name. + * + * @param {Element} element + * The element to toggle a class name on. + * + * @param {string} classToToggle + * The class that should be toggled + * + * @param {boolean|PredicateCallback} [predicate] + * See the return value for {@link Dom~PredicateCallback} + * + * @return {Element} + * The element with a class that has been toggled. + */ +function toggleElClass(element, classToToggle, predicate) { + + // This CANNOT use `classList` internally because IE does not support the + // second parameter to the `classList.toggle()` method! Which is fine because + // `classList` will be used by the add/remove functions. + var has = hasElClass(element, classToToggle); + + if (typeof predicate === 'function') { + predicate = predicate(element, classToToggle); + } + + if (typeof predicate !== 'boolean') { + predicate = !has; + } + + // If the necessary class operation matches the current state of the + // element, no action is required. + if (predicate === has) { + return; + } + + if (predicate) { + addElClass(element, classToToggle); + } else { + removeElClass(element, classToToggle); + } + + return element; +} + +/** + * Apply attributes to an HTML element. + * + * @param {Element} el + * Element to add attributes to. + * + * @param {Object} [attributes] + * Attributes to be applied. + */ +function setElAttributes(el, attributes) { + Object.getOwnPropertyNames(attributes).forEach(function (attrName) { + var attrValue = attributes[attrName]; + + if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { + el.removeAttribute(attrName); + } else { + el.setAttribute(attrName, attrValue === true ? '' : attrValue); + } + }); +} + +/** + * Get an element's attribute values, as defined on the HTML tag + * Attributes are not the same as properties. They're defined on the tag + * or with setAttribute (which shouldn't be used with HTML) + * This will return true or false for boolean attributes. + * + * @param {Element} tag + * Element from which to get tag attributes. + * + * @return {Object} + * All attributes of the element. + */ +function getElAttributes(tag) { + var obj = {}; + + // known boolean attributes + // we can check for matching boolean properties, but older browsers + // won't know about HTML5 boolean attributes that we still read from + var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ','; + + if (tag && tag.attributes && tag.attributes.length > 0) { + var attrs = tag.attributes; + + for (var i = attrs.length - 1; i >= 0; i--) { + var attrName = attrs[i].name; + var attrVal = attrs[i].value; + + // check for known booleans + // the matching element property will return a value for typeof + if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { + // the value of an included boolean attribute is typically an empty + // string ('') which would equal false if we just check for a false value. + // we also don't want support bad code like autoplay='false' + attrVal = attrVal !== null ? true : false; + } + + obj[attrName] = attrVal; + } + } + + return obj; +} + +/** + * Get the value of an element's attribute + * + * @param {Element} el + * A DOM element + * + * @param {string} attribute + * Attribute to get the value of + * + * @return {string} + * value of the attribute + */ +function getAttribute(el, attribute) { + return el.getAttribute(attribute); +} + +/** + * Set the value of an element's attribute + * + * @param {Element} el + * A DOM element + * + * @param {string} attribute + * Attribute to set + * + * @param {string} value + * Value to set the attribute to + */ +function setAttribute(el, attribute, value) { + el.setAttribute(attribute, value); +} + +/** + * Remove an element's attribute + * + * @param {Element} el + * A DOM element + * + * @param {string} attribute + * Attribute to remove + */ +function removeAttribute(el, attribute) { + el.removeAttribute(attribute); +} + +/** + * Attempt to block the ability to select text while dragging controls + */ +function blockTextSelection() { + _document2['default'].body.focus(); + _document2['default'].onselectstart = function () { + return false; + }; +} + +/** + * Turn off text selection blocking + */ +function unblockTextSelection() { + _document2['default'].onselectstart = function () { + return true; + }; +} + +/** + * The postion of a DOM element on the page. + * + * @typedef {Object} Dom~Position + * + * @property {number} left + * Pixels to the left + * + * @property {number} top + * Pixels on top + */ + +/** + * Offset Left. + * getBoundingClientRect technique from + * John Resig + * + * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/ + * + * @param {Element} el + * Element from which to get offset + * + * @return {Dom~Position} + * The position of the element that was passed in. + */ +function findElPosition(el) { + var box = void 0; + + if (el.getBoundingClientRect && el.parentNode) { + box = el.getBoundingClientRect(); + } + + if (!box) { + return { + left: 0, + top: 0 + }; + } + + var docEl = _document2['default'].documentElement; + var body = _document2['default'].body; + + var clientLeft = docEl.clientLeft || body.clientLeft || 0; + var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft; + var left = box.left + scrollLeft - clientLeft; + + var clientTop = docEl.clientTop || body.clientTop || 0; + var scrollTop = _window2['default'].pageYOffset || body.scrollTop; + var top = box.top + scrollTop - clientTop; + + // Android sometimes returns slightly off decimal values, so need to round + return { + left: Math.round(left), + top: Math.round(top) + }; +} + +/** + * x and y coordinates for a dom element or mouse pointer + * + * @typedef {Object} Dom~Coordinates + * + * @property {number} x + * x coordinate in pixels + * + * @property {number} y + * y coordinate in pixels + */ + +/** + * Get pointer position in element + * Returns an object with x and y coordinates. + * The base on the coordinates are the bottom left of the element. + * + * @param {Element} el + * Element on which to get the pointer position on + * + * @param {EventTarget~Event} event + * Event object + * + * @return {Dom~Coordinates} + * A Coordinates object corresponding to the mouse position. + * + */ +function getPointerPosition(el, event) { + var position = {}; + var box = findElPosition(el); + var boxW = el.offsetWidth; + var boxH = el.offsetHeight; + + var boxY = box.top; + var boxX = box.left; + var pageY = event.pageY; + var pageX = event.pageX; + + if (event.changedTouches) { + pageX = event.changedTouches[0].pageX; + pageY = event.changedTouches[0].pageY; + } + + position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); + position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); + + return position; +} + +/** + * Determines, via duck typing, whether or not a value is a text node. + * + * @param {Mixed} value + * Check if this value is a text node. + * + * @return {boolean} + * - True if it is a text node + * - False otherwise + */ +function isTextNode(value) { + return (0, _obj.isObject)(value) && value.nodeType === 3; +} + +/** + * Empties the contents of an element. + * + * @param {Element} el + * The element to empty children from + * + * @return {Element} + * The element with no children + */ +function emptyEl(el) { + while (el.firstChild) { + el.removeChild(el.firstChild); + } + return el; +} + +/** + * Normalizes content for eventual insertion into the DOM. + * + * This allows a wide range of content definition methods, but protects + * from falling into the trap of simply writing to `innerHTML`, which is + * an XSS concern. + * + * The content for an element can be passed in multiple types and + * combinations, whose behavior is as follows: + * + * @param {String|Element|TextNode|Array|Function} content + * - String: Normalized into a text node. + * - Element/TextNode: Passed through. + * - Array: A one-dimensional array of strings, elements, nodes, or functions + * (which return single strings, elements, or nodes). + * - Function: If the sole argument, is expected to produce a string, element, + * node, or array as defined above. + * + * @return {Array} + * All of the content that was passed in normalized. + */ +function normalizeContent(content) { + + // First, invoke content if it is a function. If it produces an array, + // that needs to happen before normalization. + if (typeof content === 'function') { + content = content(); + } + + // Next up, normalize to an array, so one or many items can be normalized, + // filtered, and returned. + return (Array.isArray(content) ? content : [content]).map(function (value) { + + // First, invoke value if it is a function to produce a new value, + // which will be subsequently normalized to a Node of some kind. + if (typeof value === 'function') { + value = value(); + } + + if (isEl(value) || isTextNode(value)) { + return value; + } + + if (typeof value === 'string' && /\S/.test(value)) { + return _document2['default'].createTextNode(value); + } + }).filter(function (value) { + return value; + }); +} + +/** + * Normalizes and appends content to an element. + * + * @param {Element} el + * Element to append normalized content to. + * + * + * @param {String|Element|TextNode|Array|Function} content + * See the `content` argument of {@link dom:normalizeContent} + * + * @return {Element} + * The element with appended normalized content. + */ +function appendContent(el, content) { + normalizeContent(content).forEach(function (node) { + return el.appendChild(node); + }); + return el; +} + +/** + * Normalizes and inserts content into an element; this is identical to + * `appendContent()`, except it empties the element first. + * + * @param {Element} el + * Element to insert normalized content into. + * + * @param {String|Element|TextNode|Array|Function} content + * See the `content` argument of {@link dom:normalizeContent} + * + * @return {Element} + * The element with inserted normalized content. + * + */ +function insertContent(el, content) { + return appendContent(emptyEl(el), content); +} + +/** + * Finds a single DOM element matching `selector` within the optional + * `context` of another DOM element (defaulting to `document`). + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelector`. + * + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. + * + * @return {Element|null} + * The element that was found or null. + */ +var $ = exports.$ = createQuerier('querySelector'); + +/** + * Finds a all DOM elements matching `selector` within the optional + * `context` of another DOM element (defaulting to `document`). + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelectorAll`. + * + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. + * + * @return {NodeList} + * A element list of elements that were found. Will be empty if none were found. + * + */ +var $$ = exports.$$ = createQuerier('querySelectorAll'); + +},{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.fixEvent = fixEvent; +exports.on = on; +exports.off = off; +exports.trigger = trigger; +exports.one = one; + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _guid = _dereq_(85); + +var Guid = _interopRequireWildcard(_guid); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +/** + * Clean up the listener cache and dispatchers + * + * @param {Element|Object} elem + * Element to clean up + * + * @param {string} type + * Type of event to clean up + */ +function _cleanUpEvents(elem, type) { + var data = Dom.getElData(elem); + + // Remove the events of a particular type if there are none left + if (data.handlers[type].length === 0) { + delete data.handlers[type]; + // data.handlers[type] = null; + // Setting to null was causing an error with data.handlers + + // Remove the meta-handler from the element + if (elem.removeEventListener) { + elem.removeEventListener(type, data.dispatcher, false); + } else if (elem.detachEvent) { + elem.detachEvent('on' + type, data.dispatcher); + } + } + + // Remove the events object if there are no types left + if (Object.getOwnPropertyNames(data.handlers).length <= 0) { + delete data.handlers; + delete data.dispatcher; + delete data.disabled; + } + + // Finally remove the element data if there is no data left + if (Object.getOwnPropertyNames(data).length === 0) { + Dom.removeElData(elem); + } +} + +/** + * Loops through an array of event types and calls the requested method for each type. + * + * @param {Function} fn + * The event method we want to use. + * + * @param {Element|Object} elem + * Element or object to bind listeners to + * + * @param {string} type + * Type of event to bind to. + * + * @param {EventTarget~EventListener} callback + * Event listener. + */ +/** + * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) + * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) + * This should work very similarly to jQuery's events, however it's based off the book version which isn't as + * robust as jquery's, so there's probably some differences. + * + * @module events + */ + +function _handleMultipleEvents(fn, elem, types, callback) { + types.forEach(function (type) { + // Call the event method for each one of the types + fn(elem, type, callback); + }); +} + +/** + * Fix a native event to have standard property values + * + * @param {Object} event + * Event object to fix. + * + * @return {Object} + * Fixed event object. + */ +function fixEvent(event) { + + function returnTrue() { + return true; + } + + function returnFalse() { + return false; + } + + // Test if fixing up is needed + // Used to check if !event.stopPropagation instead of isPropagationStopped + // But native events return true for stopPropagation, but don't have + // other expected methods like isPropagationStopped. Seems to be a problem + // with the Javascript Ninja code. So we're just overriding all events now. + if (!event || !event.isPropagationStopped) { + (function () { + var old = event || _window2['default'].event; + + event = {}; + // Clone the old object so that we can modify the values event = {}; + // IE8 Doesn't like when you mess with native event properties + // Firefox returns false for event.hasOwnProperty('type') and other props + // which makes copying more difficult. + // TODO: Probably best to create a whitelist of event props + for (var key in old) { + // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y + // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation + // and webkitMovementX/Y + if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { + // Chrome 32+ warns if you try to copy deprecated returnValue, but + // we still want to if preventDefault isn't supported (IE8). + if (!(key === 'returnValue' && old.preventDefault)) { + event[key] = old[key]; + } + } + } + + // The event occurred on this element + if (!event.target) { + event.target = event.srcElement || _document2['default']; + } + + // Handle which other element the event is related to + if (!event.relatedTarget) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } + + // Stop the default browser action + event.preventDefault = function () { + if (old.preventDefault) { + old.preventDefault(); + } + event.returnValue = false; + old.returnValue = false; + event.defaultPrevented = true; + }; + + event.defaultPrevented = false; + + // Stop the event from bubbling + event.stopPropagation = function () { + if (old.stopPropagation) { + old.stopPropagation(); + } + event.cancelBubble = true; + old.cancelBubble = true; + event.isPropagationStopped = returnTrue; + }; + + event.isPropagationStopped = returnFalse; + + // Stop the event from bubbling and executing other handlers + event.stopImmediatePropagation = function () { + if (old.stopImmediatePropagation) { + old.stopImmediatePropagation(); + } + event.isImmediatePropagationStopped = returnTrue; + event.stopPropagation(); + }; + + event.isImmediatePropagationStopped = returnFalse; + + // Handle mouse position + if (event.clientX !== null && event.clientX !== undefined) { + var doc = _document2['default'].documentElement; + var body = _document2['default'].body; + + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Handle key presses + event.which = event.charCode || event.keyCode; + + // Fix button for mouse clicks: + // 0 == left; 1 == middle; 2 == right + if (event.button !== null && event.button !== undefined) { + + // The following is disabled because it does not pass videojs-standard + // and... yikes. + /* eslint-disable */ + event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; + /* eslint-enable */ + } + })(); + } + + // Returns fixed-up instance + return event; +} + +/** + * Add an event listener to element + * It stores the handler function in a separate cache object + * and adds a generic handler to the element's event, + * along with a unique id (guid) to the element. + * + * @param {Element|Object} elem + * Element or object to bind listeners to + * + * @param {string|string[]} type + * Type of event to bind to. + * + * @param {EventTarget~EventListener} fn + * Event listener. + */ +function on(elem, type, fn) { + if (Array.isArray(type)) { + return _handleMultipleEvents(on, elem, type, fn); + } + + var data = Dom.getElData(elem); + + // We need a place to store all our handler data + if (!data.handlers) { + data.handlers = {}; + } + + if (!data.handlers[type]) { + data.handlers[type] = []; + } + + if (!fn.guid) { + fn.guid = Guid.newGUID(); + } + + data.handlers[type].push(fn); + + if (!data.dispatcher) { + data.disabled = false; + + data.dispatcher = function (event, hash) { + + if (data.disabled) { + return; + } + + event = fixEvent(event); + + var handlers = data.handlers[event.type]; + + if (handlers) { + // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. + var handlersCopy = handlers.slice(0); + + for (var m = 0, n = handlersCopy.length; m < n; m++) { + if (event.isImmediatePropagationStopped()) { + break; + } else { + try { + handlersCopy[m].call(elem, event, hash); + } catch (e) { + _log2['default'].error(e); + } + } + } + } + }; + } + + if (data.handlers[type].length === 1) { + if (elem.addEventListener) { + elem.addEventListener(type, data.dispatcher, false); + } else if (elem.attachEvent) { + elem.attachEvent('on' + type, data.dispatcher); + } + } +} + +/** + * Removes event listeners from an element + * + * @param {Element|Object} elem + * Object to remove listeners from. + * + * @param {string|string[]} [type] + * Type of listener to remove. Don't include to remove all events from element. + * + * @param {EventTarget~EventListener} [fn] + * Specific listener to remove. Don't include to remove listeners for an event + * type. + */ +function off(elem, type, fn) { + // Don't want to add a cache object through getElData if not needed + if (!Dom.hasElData(elem)) { + return; + } + + var data = Dom.getElData(elem); + + // If no events exist, nothing to unbind + if (!data.handlers) { + return; + } + + if (Array.isArray(type)) { + return _handleMultipleEvents(off, elem, type, fn); + } + + // Utility function + var removeType = function removeType(t) { + data.handlers[t] = []; + _cleanUpEvents(elem, t); + }; + + // Are we removing all bound events? + if (!type) { + for (var t in data.handlers) { + removeType(t); + } + return; + } + + var handlers = data.handlers[type]; + + // If no handlers exist, nothing to unbind + if (!handlers) { + return; + } + + // If no listener was provided, remove all listeners for type + if (!fn) { + removeType(type); + return; + } + + // We're only removing a single handler + if (fn.guid) { + for (var n = 0; n < handlers.length; n++) { + if (handlers[n].guid === fn.guid) { + handlers.splice(n--, 1); + } + } + } + + _cleanUpEvents(elem, type); +} + +/** + * Trigger an event for an element + * + * @param {Element|Object} elem + * Element to trigger an event on + * + * @param {EventTarget~Event|string} event + * A string (the type) or an event object with a type attribute + * + * @param {Object} [hash] + * data hash to pass along with the event + * + * @return {boolean|undefined} + * - Returns the opposite of `defaultPrevented` if default was prevented + * - Otherwise returns undefined + */ +function trigger(elem, event, hash) { + // Fetches element data and a reference to the parent (for bubbling). + // Don't want to add a data object to cache for every parent, + // so checking hasElData first. + var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {}; + var parent = elem.parentNode || elem.ownerDocument; + // type = event.type || event, + // handler; + + // If an event name was passed as a string, creates an event out of it + if (typeof event === 'string') { + event = { type: event, target: elem }; + } + // Normalizes the event properties. + event = fixEvent(event); + + // If the passed element has a dispatcher, executes the established handlers. + if (elemData.dispatcher) { + elemData.dispatcher.call(elem, event, hash); + } + + // Unless explicitly stopped or the event does not bubble (e.g. media events) + // recursively calls this function to bubble the event up the DOM. + if (parent && !event.isPropagationStopped() && event.bubbles === true) { + trigger.call(null, parent, event, hash); + + // If at the top of the DOM, triggers the default action unless disabled. + } else if (!parent && !event.defaultPrevented) { + var targetData = Dom.getElData(event.target); + + // Checks if the target has a default action for this event. + if (event.target[event.type]) { + // Temporarily disables event dispatching on the target as we have already executed the handler. + targetData.disabled = true; + // Executes the default action. + if (typeof event.target[event.type] === 'function') { + event.target[event.type](); + } + // Re-enables event dispatching. + targetData.disabled = false; + } + } + + // Inform the triggerer if the default was prevented by returning false + return !event.defaultPrevented; +} + +/** + * Trigger a listener only once for an event + * + * @param {Element|Object} elem + * Element or object to bind to. + * + * @param {string|string[]} type + * Name/type of event + * + * @param {Event~EventListener} fn + * Event Listener function + */ +function one(elem, type, fn) { + if (Array.isArray(type)) { + return _handleMultipleEvents(one, elem, type, fn); + } + var func = function func() { + off(elem, type, func); + fn.apply(this, arguments); + }; + + // copy the guid to the new function so it can removed using the original function's ID + func.guid = fn.guid = fn.guid || Guid.newGUID(); + on(elem, type, func); +} + +},{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.throttle = exports.bind = undefined; + +var _guid = _dereq_(85); + +/** + * Bind (a.k.a proxy or Context). A simple method for changing the context of a function + * It also stores a unique id on the function so it can be easily removed from events. + * + * @param {Mixed} context + * The object to bind as scope. + * + * @param {Function} fn + * The function to be bound to a scope. + * + * @param {number} [uid] + * An optional unique ID for the function to be set + * + * @return {Function} + * The new function that will be bound into the context given + */ +var bind = exports.bind = function bind(context, fn, uid) { + // Make sure the function has a unique ID + if (!fn.guid) { + fn.guid = (0, _guid.newGUID)(); + } + + // Create the new function that changes the context + var bound = function bound() { + return fn.apply(context, arguments); + }; + + // Allow for the ability to individualize this function + // Needed in the case where multiple objects might share the same prototype + // IF both items add an event listener with the same function, then you try to remove just one + // it will remove both because they both have the same guid. + // when using this, you need to use the bind method when you remove the listener as well. + // currently used in text tracks + bound.guid = uid ? uid + '_' + fn.guid : fn.guid; + + return bound; +}; + +/** + * Wraps the given function, `fn`, with a new function that only invokes `fn` + * at most once per every `wait` milliseconds. + * + * @param {Function} fn + * The function to be throttled. + * + * @param {Number} wait + * The number of milliseconds by which to throttle. + * + * @return {Function} + */ +/** + * @file fn.js + * @module fn + */ +var throttle = exports.throttle = function throttle(fn, wait) { + var last = Date.now(); + + var throttled = function throttled() { + var now = Date.now(); + + if (now - last >= wait) { + fn.apply(undefined, arguments); + last = now; + } + }; + + return throttled; +}; + +},{"85":85}],84:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +/** + * @file format-time.js + * @module Format-time + */ + +/** + * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds) + * will force a number of leading zeros to cover the length of the guide. + * + * @param {number} seconds + * Number of seconds to be turned into a string + * + * @param {number} guide + * Number (in seconds) to model the string after + * + * @return {string} + * Time formatted as H:MM:SS or M:SS + */ +function formatTime(seconds) { + var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds; + + seconds = seconds < 0 ? 0 : seconds; + var s = Math.floor(seconds % 60); + var m = Math.floor(seconds / 60 % 60); + var h = Math.floor(seconds / 3600); + var gm = Math.floor(guide / 60 % 60); + var gh = Math.floor(guide / 3600); + + // handle invalid times + if (isNaN(seconds) || seconds === Infinity) { + // '-' is false for all relational operators (e.g. <, >=) so this setting + // will add the minimum number of fields specified by the guide + h = m = s = '-'; + } + + // Check if we need to show hours + h = h > 0 || gh > 0 ? h + ':' : ''; + + // If hours are showing, we may need to add a leading zero. + // Always show at least one digit of minutes. + m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':'; + + // Check if leading zero is need for seconds + s = s < 10 ? '0' + s : s; + + return h + m + s; +} + +exports['default'] = formatTime; + +},{}],85:[function(_dereq_,module,exports){ +"use strict"; + +exports.__esModule = true; +exports.newGUID = newGUID; +/** + * @file guid.js + * @module guid + */ + +/** + * Unique ID for an element or function + * @type {Number} + */ +var _guid = 1; + +/** + * Get a unique auto-incrementing ID by number that has not been returned before. + * + * @return {number} + * A new unique ID. + */ +function newGUID() { + return _guid++; +} + +},{}],86:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.logByType = undefined; + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _browser = _dereq_(78); + +var _obj = _dereq_(88); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var log = void 0; + +/** + * Log messages to the console and history based on the type of message + * + * @param {string} type + * The name of the console method to use. + * + * @param {Array} args + * The arguments to be passed to the matching console method. + * + * @param {boolean} [stringify] + * By default, only old IEs should get console argument stringification, + * but this is exposed as a parameter to facilitate testing. + */ +/** + * @file log.js + * @module log + */ +var logByType = exports.logByType = function logByType(type, args) { + var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11; + + + if (type !== 'log') { + + // add the type to the front of the message when it's not "log" + args.unshift(type.toUpperCase() + ':'); + } + + // add to history + log.history.push(args); + + // add console prefix after adding to history + args.unshift('VIDEOJS:'); + + // If there's no console then don't try to output messages, but they will + // still be stored in `log.history`. + // + // Was setting these once outside of this function, but containing them + // in the function makes it easier to test cases where console doesn't exist + // when the module is executed. + var fn = _window2['default'].console && _window2['default'].console[type]; + + // Bail out if there's no console. + if (!fn) { + return; + } + + // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify + // objects and arrays for those less-capable browsers. + if (stringify) { + args = args.map(function (a) { + if ((0, _obj.isObject)(a) || Array.isArray(a)) { + try { + return JSON.stringify(a); + } catch (x) { + return String(a); + } + } + + // Cast to string before joining, so we get null and undefined explicitly + // included in output (as we would in a modern console). + return String(a); + }).join(' '); + } + + // Old IE versions do not allow .apply() for console methods (they are + // reported as objects rather than functions). + if (!fn.apply) { + fn(args); + } else { + fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args); + } +}; + +/** + * Log plain debug messages + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged. + */ +log = function log() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logByType('log', args); +}; + +/** + * Keep a history of log messages + * + * @type {Array} + */ +log.history = []; + +/** + * Log error messages + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as an error + */ +log.error = function () { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return logByType('error', args); +}; + +/** + * Log warning messages + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as a warning. + */ +log.warn = function () { + for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + return logByType('warn', args); +}; + +exports['default'] = log; + +},{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports['default'] = mergeOptions; + +var _obj = _dereq_(88); + +/** + * Deep-merge one or more options objects, recursively merging **only** plain + * object properties. + * + * @param {Object[]} sources + * One or more objects to merge into a new object. + * + * @returns {Object} + * A new object that is the merged result of all sources. + */ +function mergeOptions() { + var result = {}; + + for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { + sources[_key] = arguments[_key]; + } + + sources.forEach(function (source) { + if (!source) { + return; + } + + (0, _obj.each)(source, function (value, key) { + if (!(0, _obj.isPlain)(value)) { + result[key] = value; + return; + } + + if (!(0, _obj.isPlain)(result[key])) { + result[key] = {}; + } + + result[key] = mergeOptions(result[key], value); + }); + }); + + return result; +} /** + * @file merge-options.js + * @module merge-options + */ + +},{"88":88}],88:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.each = each; +exports.reduce = reduce; +exports.assign = assign; +exports.isObject = isObject; +exports.isPlain = isPlain; +/** + * @file obj.js + * @module obj + */ + +/** + * @callback obj:EachCallback + * + * @param {Mixed} value + * The current key for the object that is being iterated over. + * + * @param {string} key + * The current key-value for object that is being iterated over + */ + +/** + * @callback obj:ReduceCallback + * + * @param {Mixed} accum + * The value that is accumulating over the reduce loop. + * + * @param {Mixed} value + * The current key for the object that is being iterated over. + * + * @param {string} key + * The current key-value for object that is being iterated over + * + * @return {Mixed} + * The new accumulated value. + */ +var toString = Object.prototype.toString; + +/** + * Array-like iteration for objects. + * + * @param {Object} object + * The object to iterate over + * + * @param {obj:EachCallback} fn + * The callback function which is called for each key in the object. + */ +function each(object, fn) { + Object.keys(object).forEach(function (key) { + return fn(object[key], key); + }); +} + +/** + * Array-like reduce for objects. + * + * @param {Object} object + * The Object that you want to reduce. + * + * @param {Function} fn + * A callback function which is called for each key in the object. It + * receives the accumulated value and the per-iteration value and key + * as arguments. + * + * @param {Mixed} [initial = 0] + * Starting value + * + * @return {Mixed} + * The final accumulated value. + */ +function reduce(object, fn) { + var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + return Object.keys(object).reduce(function (accum, key) { + return fn(accum, object[key], key); + }, initial); +} + +/** + * Object.assign-style object shallow merge/extend. + * + * @param {Object} target + * @param {Object} ...sources + * @return {Object} + */ +function assign(target) { + for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (Object.assign) { + return Object.assign.apply(Object, [target].concat(sources)); + } + + sources.forEach(function (source) { + if (!source) { + return; + } + + each(source, function (value, key) { + target[key] = value; + }); + }); + + return target; +} + +/** + * Returns whether a value is an object of any kind - including DOM nodes, + * arrays, regular expressions, etc. Not functions, though. + * + * This avoids the gotcha where using `typeof` on a `null` value + * results in `'object'`. + * + * @param {Object} value + * @return {Boolean} + */ +function isObject(value) { + return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; +} + +/** + * Returns whether an object appears to be a "plain" object - that is, a + * direct instance of `Object`. + * + * @param {Object} value + * @return {Boolean} + */ +function isPlain(value) { + return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object; +} + +},{}],89:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.setTextContent = exports.createStyleElement = undefined; + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * Create a DOM syle element given a className for it. + * + * @param {string} className + * The className to add to the created style element. + * + * @return {Element} + * The element that was created. + */ +var createStyleElement = exports.createStyleElement = function createStyleElement(className) { + var style = _document2['default'].createElement('style'); + + style.className = className; + + return style; +}; + +/** + * Add text to a DOM element. + * + * @param {Element} el + * The Element to add text content to. + * + * @param {string} content + * The text to add to the element. + */ +/** + * @file stylesheet.js + * @module stylesheet + */ +var setTextContent = exports.setTextContent = function setTextContent(el, content) { + if (el.styleSheet) { + el.styleSheet.cssText = content; + } else { + el.textContent = content; + } +}; + +},{"94":94}],90:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.createTimeRange = undefined; +exports.createTimeRanges = createTimeRanges; + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * Returns the time for the specified index at the start or end + * of a TimeRange object. + * + * @function time-ranges:indexFunction + * + * @param {number} [index=0] + * The range number to return the time for. + * + * @return {number} + * The time that offset at the specified index. + * + * @depricated index must be set to a value, in the future this will throw an error. + */ + +/** + * An object that contains ranges of time for various reasons. + * + * @typedef {Object} TimeRange + * + * @property {number} length + * The number of time ranges represented by this Object + * + * @property {time-ranges:indexFunction} start + * Returns the time offset at which a specified time range begins. + * + * @property {time-ranges:indexFunction} end + * Returns the time offset at which a specified time range begins. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges + */ + +/** + * Check if any of the time ranges are over the maximum index. + * + * @param {string} fnName + * The function name to use for logging + * + * @param {number} index + * The index to check + * + * @param {number} maxIndex + * The maximum possible index + * + * @throws {Error} if the timeRanges provided are over the maxIndex + */ +function rangeCheck(fnName, index, maxIndex) { + if (index < 0 || index > maxIndex) { + throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').'); + } +} + +/** + * Check if any of the time ranges are over the maximum index. + * + * @param {string} fnName + * The function name to use for logging + * + * @param {string} valueIndex + * The proprety that should be used to get the time. should be 'start' or 'end' + * + * @param {Array} ranges + * An array of time ranges + * + * @param {Array} [rangeIndex=0] + * The index to start the search at + * + * @return {number} + * The time that offset at the specified index. + * + * + * @depricated rangeIndex must be set to a value, in the future this will throw an error. + * @throws {Error} if rangeIndex is more than the length of ranges + */ +/** + * @file time-ranges.js + * @module time-ranges + */ +function getRange(fnName, valueIndex, ranges, rangeIndex) { + if (rangeIndex === undefined) { + _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.'); + rangeIndex = 0; + } + rangeCheck(fnName, rangeIndex, ranges.length - 1); + return ranges[rangeIndex][valueIndex]; +} + +/** + * Create a time range object givent ranges of time. + * + * @param {Array} [ranges] + * An array of time ranges. + */ +function createTimeRangesObj(ranges) { + if (ranges === undefined || ranges.length === 0) { + return { + length: 0, + start: function start() { + throw new Error('This TimeRanges object is empty'); + }, + end: function end() { + throw new Error('This TimeRanges object is empty'); + } + }; + } + return { + length: ranges.length, + start: getRange.bind(null, 'start', 0, ranges), + end: getRange.bind(null, 'end', 1, ranges) + }; +} + +/** + * Should create a fake `TimeRange` object which mimics an HTML5 time range instance. + * + * @param {number|Array} start + * The start of a single range or an array of ranges + * + * @param {number} end + * The end of a single range. + * + * @private + */ +function createTimeRanges(start, end) { + if (Array.isArray(start)) { + return createTimeRangesObj(start); + } else if (start === undefined || end === undefined) { + return createTimeRangesObj(); + } + return createTimeRangesObj([[start, end]]); +} + +exports.createTimeRange = createTimeRanges; + +},{"86":86}],91:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +/** + * @file to-title-case.js + * @module to-title-case + */ + +/** + * Uppercase the first letter of a string. + * + * @param {string} string + * String to be uppercased + * + * @return {string} + * The string with an uppercased first letter + */ +function toTitleCase(string) { + if (typeof string !== 'string') { + return string; + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} + +exports['default'] = toTitleCase; + +},{}],92:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined; + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +/** + * @typedef {Object} url:URLObject + * + * @property {string} protocol + * The protocol of the url that was parsed. + * + * @property {string} hostname + * The hostname of the url that was parsed. + * + * @property {string} port + * The port of the url that was parsed. + * + * @property {string} pathname + * The pathname of the url that was parsed. + * + * @property {string} search + * The search query of the url that was parsed. + * + * @property {string} hash + * The hash of the url that was parsed. + * + * @property {string} host + * The host of the url that was parsed. + */ + +/** + * Resolve and parse the elements of a URL. + * + * @param {String} url + * The url to parse + * + * @return {url:URLObject} + * An object of url details + */ +/** + * @file url.js + * @module url + */ +var parseUrl = exports.parseUrl = function parseUrl(url) { + var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; + + // add the url to an anchor and let the browser parse the URL + var a = _document2['default'].createElement('a'); + + a.href = url; + + // IE8 (and 9?) Fix + // ie8 doesn't parse the URL correctly until the anchor is actually + // added to the body, and an innerHTML is needed to trigger the parsing + var addToBody = a.host === '' && a.protocol !== 'file:'; + var div = void 0; + + if (addToBody) { + div = _document2['default'].createElement('div'); + div.innerHTML = '<a href="' + url + '"></a>'; + a = div.firstChild; + // prevent the div from affecting layout + div.setAttribute('style', 'display:none; position:absolute;'); + _document2['default'].body.appendChild(div); + } + + // Copy the specific URL properties to a new object + // This is also needed for IE8 because the anchor loses its + // properties when it's removed from the dom + var details = {}; + + for (var i = 0; i < props.length; i++) { + details[props[i]] = a[props[i]]; + } + + // IE9 adds the port to the host property unlike everyone else. If + // a port identifier is added for standard ports, strip it. + if (details.protocol === 'http:') { + details.host = details.host.replace(/:80$/, ''); + } + + if (details.protocol === 'https:') { + details.host = details.host.replace(/:443$/, ''); + } + + if (addToBody) { + _document2['default'].body.removeChild(div); + } + + return details; +}; + +/** + * Get absolute version of relative URL. Used to tell flash correct URL. + * + * + * @param {string} url + * URL to make absolute + * + * @return {string} + * Absolute URL + * + * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue + */ +var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) { + // Check if absolute URL + if (!url.match(/^https?:\/\//)) { + // Convert to absolute URL. Flash hosted off-site needs an absolute URL. + var div = _document2['default'].createElement('div'); + + div.innerHTML = '<a href="' + url + '">x</a>'; + url = div.firstChild.href; + } + + return url; +}; + +/** + * Returns the extension of the passed file name. It will return an empty string + * if passed an invalid path. + * + * @param {string} path + * The fileName path like '/path/to/file.mp4' + * + * @returns {string} + * The extension in lower case or an empty string if no + * extension could be found. + */ +var getFileExtension = exports.getFileExtension = function getFileExtension(path) { + if (typeof path === 'string') { + var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; + var pathParts = splitPathRe.exec(path); + + if (pathParts) { + return pathParts.pop().toLowerCase(); + } + } + + return ''; +}; + +/** + * Returns whether the url passed is a cross domain request or not. + * + * @param {string} url + * The url to check. + * + * @return {boolean} + * Whether it is a cross domain request or not. + */ +var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) { + var winLoc = _window2['default'].location; + var urlInfo = parseUrl(url); + + // IE8 protocol relative urls will return ':' for protocol + var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; + + // Check if url is for another domain/origin + // IE8 doesn't know location.origin, so we won't rely on it here + var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; + + return crossOrigin; +}; + +},{"94":94,"95":95}],93:[function(_dereq_,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** + * @file video.js + * @module videojs + */ + +/* global define */ + +// Include the built-in techs + + +var _window = _dereq_(95); + +var _window2 = _interopRequireDefault(_window); + +var _document = _dereq_(94); + +var _document2 = _interopRequireDefault(_document); + +var _setup = _dereq_(56); + +var setup = _interopRequireWildcard(_setup); + +var _stylesheet = _dereq_(89); + +var stylesheet = _interopRequireWildcard(_stylesheet); + +var _component = _dereq_(5); + +var _component2 = _interopRequireDefault(_component); + +var _eventTarget = _dereq_(42); + +var _eventTarget2 = _interopRequireDefault(_eventTarget); + +var _events = _dereq_(82); + +var Events = _interopRequireWildcard(_events); + +var _player = _dereq_(51); + +var _player2 = _interopRequireDefault(_player); + +var _plugins = _dereq_(52); + +var _plugins2 = _interopRequireDefault(_plugins); + +var _mergeOptions2 = _dereq_(87); + +var _mergeOptions3 = _interopRequireDefault(_mergeOptions2); + +var _fn = _dereq_(83); + +var Fn = _interopRequireWildcard(_fn); + +var _textTrack = _dereq_(72); + +var _textTrack2 = _interopRequireDefault(_textTrack); + +var _audioTrack = _dereq_(64); + +var _audioTrack2 = _interopRequireDefault(_audioTrack); + +var _videoTrack = _dereq_(77); + +var _videoTrack2 = _interopRequireDefault(_videoTrack); + +var _timeRanges = _dereq_(90); + +var _formatTime = _dereq_(84); + +var _formatTime2 = _interopRequireDefault(_formatTime); + +var _log = _dereq_(86); + +var _log2 = _interopRequireDefault(_log); + +var _dom = _dereq_(81); + +var Dom = _interopRequireWildcard(_dom); + +var _browser = _dereq_(78); + +var browser = _interopRequireWildcard(_browser); + +var _url = _dereq_(92); + +var Url = _interopRequireWildcard(_url); + +var _obj = _dereq_(88); + +var _computedStyle = _dereq_(80); + +var _computedStyle2 = _interopRequireDefault(_computedStyle); + +var _extend = _dereq_(43); + +var _extend2 = _interopRequireDefault(_extend); + +var _xhr = _dereq_(99); + +var _xhr2 = _interopRequireDefault(_xhr); + +var _tech = _dereq_(62); + +var _tech2 = _interopRequireDefault(_tech); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +// HTML5 Element Shim for IE8 +if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) { + _document2['default'].createElement('video'); + _document2['default'].createElement('audio'); + _document2['default'].createElement('track'); +} + +/** + * Doubles as the main function for users to create a player instance and also + * the main library object. + * The `videojs` function can be used to initialize or retrieve a player. + * + * @param {string|Element} id + * Video element or video element ID + * + * @param {Object} [options] + * Optional options object for config/settings + * + * @param {Component~ReadyCallback} [ready] + * Optional ready callback + * + * @return {Player} + * A player instance + * + * @mixes videojs + */ +function videojs(id, options, ready) { + var tag = void 0; + + // Allow for element or ID to be passed in + // String ID + if (typeof id === 'string') { + + // Adjust for jQuery ID syntax + if (id.indexOf('#') === 0) { + id = id.slice(1); + } + + // If a player instance has already been created for this ID return it. + if (videojs.getPlayers()[id]) { + + // If options or ready funtion are passed, warn + if (options) { + _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); + } + + if (ready) { + videojs.getPlayers()[id].ready(ready); + } + + return videojs.getPlayers()[id]; + } + + // Otherwise get element for ID + tag = Dom.getEl(id); + + // ID is a media element + } else { + tag = id; + } + + // Check for a useable element + // re: nodeName, could be a box div also + if (!tag || !tag.nodeName) { + throw new TypeError('The element or ID supplied is not valid. (videojs)'); + } + + // Element may have a player attr referring to an already created player instance. + // If so return that otherwise set up a new player below + if (tag.player || _player2['default'].players[tag.playerId]) { + return tag.player || _player2['default'].players[tag.playerId]; + } + + options = options || {}; + + videojs.hooks('beforesetup').forEach(function (hookFunction) { + var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options)); + + if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) { + _log2['default'].error('please return an object in beforesetup hooks'); + return; + } + + options = (0, _mergeOptions3['default'])(options, opts); + }); + + var PlayerComponent = _component2['default'].getComponent('Player'); + // If not, set up a new player + var player = new PlayerComponent(tag, options, ready); + + videojs.hooks('setup').forEach(function (hookFunction) { + return hookFunction(player); + }); + + return player; +} + +/** + * An Object that contains lifecycle hooks as keys which point to an array + * of functions that are run when a lifecycle is triggered + */ +videojs.hooks_ = {}; + +/** + * Get a list of hooks for a specific lifecycle + * + * @param {string} type + * the lifecyle to get hooks from + * + * @param {Function} [fn] + * Optionally add a hook to the lifecycle that your are getting. + * + * @return {Array} + * an array of hooks, or an empty array if there are none. + */ +videojs.hooks = function (type, fn) { + videojs.hooks_[type] = videojs.hooks_[type] || []; + if (fn) { + videojs.hooks_[type] = videojs.hooks_[type].concat(fn); + } + return videojs.hooks_[type]; +}; + +/** + * Add a function hook to a specific videojs lifecycle. + * + * @param {string} type + * the lifecycle to hook the function to. + * + * @param {Function|Function[]} + * The function or array of functions to attach. + */ +videojs.hook = function (type, fn) { + videojs.hooks(type, fn); +}; + +/** + * Remove a hook from a specific videojs lifecycle. + * + * @param {string} type + * the lifecycle that the function hooked to + * + * @param {Function} fn + * The hooked function to remove + * + * @return {boolean} + * The function that was removed or undef + */ +videojs.removeHook = function (type, fn) { + var index = videojs.hooks(type).indexOf(fn); + + if (index <= -1) { + return false; + } + + videojs.hooks_[type] = videojs.hooks_[type].slice(); + videojs.hooks_[type].splice(index, 1); + + return true; +}; + +// Add default styles +if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) { + var style = Dom.$('.vjs-styles-defaults'); + + if (!style) { + style = stylesheet.createStyleElement('vjs-styles-defaults'); + var head = Dom.$('head'); + + if (head) { + head.insertBefore(style, head.firstChild); + } + stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); + } +} + +// Run Auto-load players +// You have to wait at least once in case this script is loaded after your +// video in the DOM (weird behavior only with minified version) +setup.autoSetupTimeout(1, videojs); + +/** + * Current software version. Follows semver. + * + * @type {string} + */ +videojs.VERSION = '5.15.1'; + +/** + * The global options object. These are the settings that take effect + * if no overrides are specified when the player is created. + * + * @type {Object} + */ +videojs.options = _player2['default'].prototype.options_; + +/** + * Get an object with the currently created players, keyed by player ID + * + * @return {Object} + * The created players + */ +videojs.getPlayers = function () { + return _player2['default'].players; +}; + +/** + * Expose players object. + * + * @memberOf videojs + * @property {Object} players + */ +videojs.players = _player2['default'].players; + +/** + * Get a component class object by name + * + * @borrows Component.getComponent as videojs.getComponent + */ +videojs.getComponent = _component2['default'].getComponent; + +/** + * Register a component so it can referred to by name. Used when adding to other + * components, either through addChild `component.addChild('myComponent')` or through + * default children options `{ children: ['myComponent'] }`. + * + * > NOTE: You could also just initialize the component before adding. + * `component.addChild(new MyComponent());` + * + * @param {string} name + * The class name of the component + * + * @param {Component} comp + * The component class + * + * @return {Component} + * The newly registered component + */ +videojs.registerComponent = function (name, comp) { + if (_tech2['default'].isTech(comp)) { + _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); + } + + _component2['default'].registerComponent.call(_component2['default'], name, comp); +}; + +/** + * Get a Tech class object by name + * + * @borrows Tech.getTech as videojs.getTech + */ +videojs.getTech = _tech2['default'].getTech; + +/** + * Register a Tech so it can referred to by name. + * This is used in the tech order for the player. + * + * @borrows Tech.registerTech as videojs.registerTech + */ +videojs.registerTech = _tech2['default'].registerTech; + +/** + * A suite of browser and device tests from {@link browser}. + * + * @type {Object} + * @private + */ +videojs.browser = browser; + +/** + * Whether or not the browser supports touch events. Included for backward + * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` + * instead going forward. + * + * @deprecated since version 5.0 + * @type {boolean} + */ +videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; + +/** + * Subclass an existing class + * Mimics ES6 subclassing with the `extend` keyword + * + * @borrows extend:extendFn as videojs.extend + */ +videojs.extend = _extend2['default']; + +/** + * Merge two options objects recursively + * Performs a deep merge like lodash.merge but **only merges plain objects** + * (not arrays, elements, anything else) + * Other values will be copied directly from the second object. + * + * @borrows merge-options:mergeOptions as videojs.mergeOptions + */ +videojs.mergeOptions = _mergeOptions3['default']; + +/** + * Change the context (this) of a function + * + * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native + * `function() {}.bind(newContext);` instead of this. + * + * @borrows fn:bind as videojs.bind + */ +videojs.bind = Fn.bind; + +/** + * Create a Video.js player plugin. + * Plugins are only initialized when options for the plugin are included + * in the player options, or the plugin function on the player instance is + * called. + * + * @borrows plugin:plugin as videojs.plugin + */ +videojs.plugin = _plugins2['default']; + +/** + * Adding languages so that they're available to all players. + * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });` + * + * @param {string} code + * The language code or dictionary property + * + * @param {Object} data + * The data values to be translated + * + * @return {Object} + * The resulting language dictionary object + */ +videojs.addLanguage = function (code, data) { + var _mergeOptions; + + code = ('' + code).toLowerCase(); + + videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions)); + + return videojs.options.languages[code]; +}; + +/** + * Log messages + * + * @borrows log:log as videojs.log + */ +videojs.log = _log2['default']; + +/** + * Creates an emulated TimeRange object. + * + * @borrows time-ranges:createTimeRanges as videojs.createTimeRange + */ +/** + * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges + */ +videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges; + +/** + * Format seconds as a time string, H:MM:SS or M:SS + * Supplying a guide (in seconds) will force a number of leading zeros + * to cover the length of the guide + * + * @borrows format-time:formatTime as videojs.formatTime + */ +videojs.formatTime = _formatTime2['default']; + +/** + * Resolve and parse the elements of a URL + * + * @borrows url:parseUrl as videojs.parseUrl + */ +videojs.parseUrl = Url.parseUrl; + +/** + * Returns whether the url passed is a cross domain request or not. + * + * @borrows url:isCrossOrigin as videojs.isCrossOrigin + */ +videojs.isCrossOrigin = Url.isCrossOrigin; + +/** + * Event target class. + * + * @borrows EventTarget as videojs.EventTarget + */ +videojs.EventTarget = _eventTarget2['default']; + +/** + * Add an event listener to element + * It stores the handler function in a separate cache object + * and adds a generic handler to the element's event, + * along with a unique id (guid) to the element. + * + * @borrows events:on as videojs.on + */ +videojs.on = Events.on; + +/** + * Trigger a listener only once for an event + * + * @borrows events:one as videojs.one + */ +videojs.one = Events.one; + +/** + * Removes event listeners from an element + * + * @borrows events:off as videojs.off + */ +videojs.off = Events.off; + +/** + * Trigger an event for an element + * + * @borrows events:trigger as videojs.trigger + */ +videojs.trigger = Events.trigger; + +/** + * A cross-browser XMLHttpRequest wrapper. Here's a simple example: + * + * @param {Object} options + * settings for the request. + * + * @return {XMLHttpRequest|XDomainRequest} + * The request object. + * + * @see https://github.com/Raynos/xhr + */ +videojs.xhr = _xhr2['default']; + +/** + * TextTrack class + * + * @borrows TextTrack as videojs.TextTrack + */ +videojs.TextTrack = _textTrack2['default']; + +/** + * export the AudioTrack class so that source handlers can create + * AudioTracks and then add them to the players AudioTrackList + * + * @borrows AudioTrack as videojs.AudioTrack + */ +videojs.AudioTrack = _audioTrack2['default']; + +/** + * export the VideoTrack class so that source handlers can create + * VideoTracks and then add them to the players VideoTrackList + * + * @borrows VideoTrack as videojs.VideoTrack + */ +videojs.VideoTrack = _videoTrack2['default']; + +/** + * Determines, via duck typing, whether or not a value is a DOM element. + * + * @borrows dom:isEl as videojs.isEl + */ +videojs.isEl = Dom.isEl; + +/** + * Determines, via duck typing, whether or not a value is a text node. + * + * @borrows dom:isTextNode as videojs.isTextNode + */ +videojs.isTextNode = Dom.isTextNode; + +/** + * Creates an element and applies properties. + * + * @borrows dom:createEl as videojs.createEl + */ +videojs.createEl = Dom.createEl; + +/** + * Check if an element has a CSS class + * + * @borrows dom:hasElClass as videojs.hasClass + */ +videojs.hasClass = Dom.hasElClass; + +/** + * Add a CSS class name to an element + * + * @borrows dom:addElClass as videojs.addClass + */ +videojs.addClass = Dom.addElClass; + +/** + * Remove a CSS class name from an element + * + * @borrows dom:removeElClass as videojs.removeClass + */ +videojs.removeClass = Dom.removeElClass; + +/** + * Adds or removes a CSS class name on an element depending on an optional + * condition or the presence/absence of the class name. + * + * @borrows dom:toggleElClass as videojs.toggleClass + */ +videojs.toggleClass = Dom.toggleElClass; + +/** + * Apply attributes to an HTML element. + * + * @borrows dom:setElAttributes as videojs.setAttribute + */ +videojs.setAttributes = Dom.setElAttributes; + +/** + * Get an element's attribute values, as defined on the HTML tag + * Attributes are not the same as properties. They're defined on the tag + * or with setAttribute (which shouldn't be used with HTML) + * This will return true or false for boolean attributes. + * + * @borrows dom:getElAttributes as videojs.getAttributes + */ +videojs.getAttributes = Dom.getElAttributes; + +/** + * Empties the contents of an element. + * + * @borrows dom:emptyEl as videojs.emptyEl + */ +videojs.emptyEl = Dom.emptyEl; + +/** + * Normalizes and appends content to an element. + * + * The content for an element can be passed in multiple types and + * combinations, whose behavior is as follows: + * + * - String + * Normalized into a text node. + * + * - Element, TextNode + * Passed through. + * + * - Array + * A one-dimensional array of strings, elements, nodes, or functions (which + * return single strings, elements, or nodes). + * + * - Function + * If the sole argument, is expected to produce a string, element, + * node, or array. + * + * @borrows dom:appendContents as videojs.appendContet + */ +videojs.appendContent = Dom.appendContent; + +/** + * Normalizes and inserts content into an element; this is identical to + * `appendContent()`, except it empties the element first. + * + * The content for an element can be passed in multiple types and + * combinations, whose behavior is as follows: + * + * - String + * Normalized into a text node. + * + * - Element, TextNode + * Passed through. + * + * - Array + * A one-dimensional array of strings, elements, nodes, or functions (which + * return single strings, elements, or nodes). + * + * - Function + * If the sole argument, is expected to produce a string, element, + * node, or array. + * + * @borrows dom:insertContent as videojs.insertContent + */ +videojs.insertContent = Dom.insertContent; + +/** + * A safe getComputedStyle with an IE8 fallback. + * + * This is because in Firefox, if the player is loaded in an iframe with `display:none`, + * then `getComputedStyle` returns `null`, so, we do a null-check to make sure + * that the player doesn't break in these cases. + * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details. + * + * @borrows computed-style:computedStyle as videojs.computedStyle + */ +videojs.computedStyle = _computedStyle2['default']; + +/* + * Custom Universal Module Definition (UMD) + * + * Video.js will never be a non-browser lib so we can simplify UMD a bunch and + * still support requirejs and browserify. This also needs to be closure + * compiler compatible, so string keys are used. + */ +if (typeof define === 'function' && define.amd) { + define('videojs', [], function () { + return videojs; + }); + + // checking that module is an object too because of umdjs/umd#35 +} else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { + module.exports = videojs; +} + +exports['default'] = videojs; + +},{"42":42,"43":43,"5":5,"51":51,"52":52,"56":56,"62":62,"64":64,"72":72,"77":77,"78":78,"80":80,"81":81,"82":82,"83":83,"84":84,"86":86,"87":87,"88":88,"89":89,"90":90,"92":92,"94":94,"95":95,"99":99}],94:[function(_dereq_,module,exports){ +(function (global){ +var topLevel = typeof global !== 'undefined' ? global : + typeof window !== 'undefined' ? window : {} +var minDoc = _dereq_(96); + +if (typeof document !== 'undefined') { + module.exports = document; +} else { + var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; + + if (!doccy) { + doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; + } + + module.exports = doccy; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"96":96}],95:[function(_dereq_,module,exports){ +(function (global){ +if (typeof window !== "undefined") { + module.exports = window; +} else if (typeof global !== "undefined") { + module.exports = global; +} else if (typeof self !== "undefined"){ + module.exports = self; +} else { + module.exports = {}; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],96:[function(_dereq_,module,exports){ + +},{}],97:[function(_dereq_,module,exports){ +module.exports = SafeParseTuple + +function SafeParseTuple(obj, reviver) { + var json + var error = null + + try { + json = JSON.parse(obj, reviver) + } catch (err) { + error = err + } + + return [error, json] +} + +},{}],98:[function(_dereq_,module,exports){ +function clean (s) { + return s.replace(/\n\r?\s*/g, '') +} + + +module.exports = function tsml (sa) { + var s = '' + , i = 0 + + for (; i < arguments.length; i++) + s += clean(sa[i]) + (arguments[i + 1] || '') + + return s +} +},{}],99:[function(_dereq_,module,exports){ +"use strict"; +var window = _dereq_(95) +var isFunction = _dereq_(100) +var parseHeaders = _dereq_(103) +var xtend = _dereq_(104) + +module.exports = createXHR +createXHR.XMLHttpRequest = window.XMLHttpRequest || noop +createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest + +forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { + createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { + options = initParams(uri, options, callback) + options.method = method.toUpperCase() + return _createXHR(options) + } +}) + +function forEachArray(array, iterator) { + for (var i = 0; i < array.length; i++) { + iterator(array[i]) + } +} + +function isEmpty(obj){ + for(var i in obj){ + if(obj.hasOwnProperty(i)) return false + } + return true +} + +function initParams(uri, options, callback) { + var params = uri + + if (isFunction(options)) { + callback = options + if (typeof uri === "string") { + params = {uri:uri} + } + } else { + params = xtend(options, {uri: uri}) + } + + params.callback = callback + return params +} + +function createXHR(uri, options, callback) { + options = initParams(uri, options, callback) + return _createXHR(options) +} + +function _createXHR(options) { + if(typeof options.callback === "undefined"){ + throw new Error("callback argument missing") + } + + var called = false + var callback = function cbOnce(err, response, body){ + if(!called){ + called = true + options.callback(err, response, body) + } + } + + function readystatechange() { + if (xhr.readyState === 4) { + loadFunc() + } + } + + function getBody() { + // Chrome with requestType=blob throws errors arround when even testing access to responseText + var body = undefined + + if (xhr.response) { + body = xhr.response + } else { + body = xhr.responseText || getXml(xhr) + } + + if (isJson) { + try { + body = JSON.parse(body) + } catch (e) {} + } + + return body + } + + var failureResponse = { + body: undefined, + headers: {}, + statusCode: 0, + method: method, + url: uri, + rawRequest: xhr + } + + function errorFunc(evt) { + clearTimeout(timeoutTimer) + if(!(evt instanceof Error)){ + evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) + } + evt.statusCode = 0 + return callback(evt, failureResponse) + } + + // will load the data & process the response in a special response object + function loadFunc() { + if (aborted) return + var status + clearTimeout(timeoutTimer) + if(options.useXDR && xhr.status===undefined) { + //IE8 CORS GET successful response doesn't have a status field, but body is fine + status = 200 + } else { + status = (xhr.status === 1223 ? 204 : xhr.status) + } + var response = failureResponse + var err = null + + if (status !== 0){ + response = { + body: getBody(), + statusCode: status, + method: method, + headers: {}, + url: uri, + rawRequest: xhr + } + if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE + response.headers = parseHeaders(xhr.getAllResponseHeaders()) + } + } else { + err = new Error("Internal XMLHttpRequest Error") + } + return callback(err, response, response.body) + } + + var xhr = options.xhr || null + + if (!xhr) { + if (options.cors || options.useXDR) { + xhr = new createXHR.XDomainRequest() + }else{ + xhr = new createXHR.XMLHttpRequest() + } + } + + var key + var aborted + var uri = xhr.url = options.uri || options.url + var method = xhr.method = options.method || "GET" + var body = options.body || options.data || null + var headers = xhr.headers = options.headers || {} + var sync = !!options.sync + var isJson = false + var timeoutTimer + + if ("json" in options) { + isJson = true + headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user + if (method !== "GET" && method !== "HEAD") { + headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user + body = JSON.stringify(options.json) + } + } + + xhr.onreadystatechange = readystatechange + xhr.onload = loadFunc + xhr.onerror = errorFunc + // IE9 must have onprogress be set to a unique function. + xhr.onprogress = function () { + // IE must die + } + xhr.ontimeout = errorFunc + xhr.open(method, uri, !sync, options.username, options.password) + //has to be after open + if(!sync) { + xhr.withCredentials = !!options.withCredentials + } + // Cannot set timeout with sync request + // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly + // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent + if (!sync && options.timeout > 0 ) { + timeoutTimer = setTimeout(function(){ + aborted=true//IE9 may still call readystatechange + xhr.abort("timeout") + var e = new Error("XMLHttpRequest timeout") + e.code = "ETIMEDOUT" + errorFunc(e) + }, options.timeout ) + } + + if (xhr.setRequestHeader) { + for(key in headers){ + if(headers.hasOwnProperty(key)){ + xhr.setRequestHeader(key, headers[key]) + } + } + } else if (options.headers && !isEmpty(options.headers)) { + throw new Error("Headers cannot be set on an XDomainRequest object") + } + + if ("responseType" in options) { + xhr.responseType = options.responseType + } + + if ("beforeSend" in options && + typeof options.beforeSend === "function" + ) { + options.beforeSend(xhr) + } + + xhr.send(body) + + return xhr + + +} + +function getXml(xhr) { + if (xhr.responseType === "document") { + return xhr.responseXML + } + var firefoxBugTakenEffect = xhr.status === 204 && xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" + if (xhr.responseType === "" && !firefoxBugTakenEffect) { + return xhr.responseXML + } + + return null +} + +function noop() {} + +},{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){ +module.exports = isFunction + +var toString = Object.prototype.toString + +function isFunction (fn) { + var string = toString.call(fn) + return string === '[object Function]' || + (typeof fn === 'function' && string !== '[object RegExp]') || + (typeof window !== 'undefined' && + // IE8 and below + (fn === window.setTimeout || + fn === window.alert || + fn === window.confirm || + fn === window.prompt)) +}; + +},{}],101:[function(_dereq_,module,exports){ +var isFunction = _dereq_(100) + +module.exports = forEach + +var toString = Object.prototype.toString +var hasOwnProperty = Object.prototype.hasOwnProperty + +function forEach(list, iterator, context) { + if (!isFunction(iterator)) { + throw new TypeError('iterator must be a function') + } + + if (arguments.length < 3) { + context = this + } + + if (toString.call(list) === '[object Array]') + forEachArray(list, iterator, context) + else if (typeof list === 'string') + forEachString(list, iterator, context) + else + forEachObject(list, iterator, context) +} + +function forEachArray(array, iterator, context) { + for (var i = 0, len = array.length; i < len; i++) { + if (hasOwnProperty.call(array, i)) { + iterator.call(context, array[i], i, array) + } + } +} + +function forEachString(string, iterator, context) { + for (var i = 0, len = string.length; i < len; i++) { + // no such thing as a sparse string. + iterator.call(context, string.charAt(i), i, string) + } +} + +function forEachObject(object, iterator, context) { + for (var k in object) { + if (hasOwnProperty.call(object, k)) { + iterator.call(context, object[k], k, object) + } + } +} + +},{"100":100}],102:[function(_dereq_,module,exports){ + +exports = module.exports = trim; + +function trim(str){ + return str.replace(/^\s*|\s*$/g, ''); +} + +exports.left = function(str){ + return str.replace(/^\s*/, ''); +}; + +exports.right = function(str){ + return str.replace(/\s*$/, ''); +}; + +},{}],103:[function(_dereq_,module,exports){ +var trim = _dereq_(102) + , forEach = _dereq_(101) + , isArray = function(arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; + } + +module.exports = function (headers) { + if (!headers) + return {} + + var result = {} + + forEach( + trim(headers).split('\n') + , function (row) { + var index = row.indexOf(':') + , key = trim(row.slice(0, index)).toLowerCase() + , value = trim(row.slice(index + 1)) + + if (typeof(result[key]) === 'undefined') { + result[key] = value + } else if (isArray(result[key])) { + result[key].push(value) + } else { + result[key] = [ result[key], value ] + } + } + ) + + return result +} +},{"101":101,"102":102}],104:[function(_dereq_,module,exports){ +module.exports = extend + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +function extend() { + var target = {} + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i] + + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key] + } + } + } + + return target +} + +},{}]},{},[93])(93) +}); +/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */ + +(function(root) { + var vttjs = root.vttjs = {}; + var cueShim = vttjs.VTTCue; + var regionShim = vttjs.VTTRegion; + var oldVTTCue = root.VTTCue; + var oldVTTRegion = root.VTTRegion; + + vttjs.shim = function() { + vttjs.VTTCue = cueShim; + vttjs.VTTRegion = regionShim; + }; + + vttjs.restore = function() { + vttjs.VTTCue = oldVTTCue; + vttjs.VTTRegion = oldVTTRegion; + }; +}(this)); + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(root, vttjs) { + + var autoKeyword = "auto"; + var directionSetting = { + "": true, + "lr": true, + "rl": true + }; + var alignSetting = { + "start": true, + "middle": true, + "end": true, + "left": true, + "right": true + }; + + function findDirectionSetting(value) { + if (typeof value !== "string") { + return false; + } + var dir = directionSetting[value.toLowerCase()]; + return dir ? value.toLowerCase() : false; + } + + function findAlignSetting(value) { + if (typeof value !== "string") { + return false; + } + var align = alignSetting[value.toLowerCase()]; + return align ? value.toLowerCase() : false; + } + + function extend(obj) { + var i = 1; + for (; i < arguments.length; i++) { + var cobj = arguments[i]; + for (var p in cobj) { + obj[p] = cobj[p]; + } + } + + return obj; + } + + function VTTCue(startTime, endTime, text) { + var cue = this; + var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); + var baseObj = {}; + + if (isIE8) { + cue = document.createElement('custom'); + } else { + baseObj.enumerable = true; + } + + /** + * Shim implementation specific properties. These properties are not in + * the spec. + */ + + // Lets us know when the VTTCue's data has changed in such a way that we need + // to recompute its display state. This lets us compute its display state + // lazily. + cue.hasBeenReset = false; + + /** + * VTTCue and TextTrackCue properties + * http://dev.w3.org/html5/webvtt/#vttcue-interface + */ + + var _id = ""; + var _pauseOnExit = false; + var _startTime = startTime; + var _endTime = endTime; + var _text = text; + var _region = null; + var _vertical = ""; + var _snapToLines = true; + var _line = "auto"; + var _lineAlign = "start"; + var _position = 50; + var _positionAlign = "middle"; + var _size = 50; + var _align = "middle"; + + Object.defineProperty(cue, + "id", extend({}, baseObj, { + get: function() { + return _id; + }, + set: function(value) { + _id = "" + value; + } + })); + + Object.defineProperty(cue, + "pauseOnExit", extend({}, baseObj, { + get: function() { + return _pauseOnExit; + }, + set: function(value) { + _pauseOnExit = !!value; + } + })); + + Object.defineProperty(cue, + "startTime", extend({}, baseObj, { + get: function() { + return _startTime; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("Start time must be set to a number."); + } + _startTime = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "endTime", extend({}, baseObj, { + get: function() { + return _endTime; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("End time must be set to a number."); + } + _endTime = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "text", extend({}, baseObj, { + get: function() { + return _text; + }, + set: function(value) { + _text = "" + value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "region", extend({}, baseObj, { + get: function() { + return _region; + }, + set: function(value) { + _region = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "vertical", extend({}, baseObj, { + get: function() { + return _vertical; + }, + set: function(value) { + var setting = findDirectionSetting(value); + // Have to check for false because the setting an be an empty string. + if (setting === false) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + _vertical = setting; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "snapToLines", extend({}, baseObj, { + get: function() { + return _snapToLines; + }, + set: function(value) { + _snapToLines = !!value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "line", extend({}, baseObj, { + get: function() { + return _line; + }, + set: function(value) { + if (typeof value !== "number" && value !== autoKeyword) { + throw new SyntaxError("An invalid number or illegal string was specified."); + } + _line = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "lineAlign", extend({}, baseObj, { + get: function() { + return _lineAlign; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + _lineAlign = setting; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "position", extend({}, baseObj, { + get: function() { + return _position; + }, + set: function(value) { + if (value < 0 || value > 100) { + throw new Error("Position must be between 0 and 100."); + } + _position = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "positionAlign", extend({}, baseObj, { + get: function() { + return _positionAlign; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + _positionAlign = setting; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "size", extend({}, baseObj, { + get: function() { + return _size; + }, + set: function(value) { + if (value < 0 || value > 100) { + throw new Error("Size must be between 0 and 100."); + } + _size = value; + this.hasBeenReset = true; + } + })); + + Object.defineProperty(cue, + "align", extend({}, baseObj, { + get: function() { + return _align; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + _align = setting; + this.hasBeenReset = true; + } + })); + + /** + * Other <track> spec defined properties + */ + + // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state + cue.displayState = undefined; + + if (isIE8) { + return cue; + } + } + + /** + * VTTCue methods + */ + + VTTCue.prototype.getCueAsHTML = function() { + // Assume WebVTT.convertCueToDOMTree is on the global. + return WebVTT.convertCueToDOMTree(window, this.text); + }; + + root.VTTCue = root.VTTCue || VTTCue; + vttjs.VTTCue = VTTCue; +}(this, (this.vttjs || {}))); + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(root, vttjs) { + + var scrollSetting = { + "": true, + "up": true + }; + + function findScrollSetting(value) { + if (typeof value !== "string") { + return false; + } + var scroll = scrollSetting[value.toLowerCase()]; + return scroll ? value.toLowerCase() : false; + } + + function isValidPercentValue(value) { + return typeof value === "number" && (value >= 0 && value <= 100); + } + + // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface + function VTTRegion() { + var _width = 100; + var _lines = 3; + var _regionAnchorX = 0; + var _regionAnchorY = 100; + var _viewportAnchorX = 0; + var _viewportAnchorY = 100; + var _scroll = ""; + + Object.defineProperties(this, { + "width": { + enumerable: true, + get: function() { + return _width; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("Width must be between 0 and 100."); + } + _width = value; + } + }, + "lines": { + enumerable: true, + get: function() { + return _lines; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("Lines must be set to a number."); + } + _lines = value; + } + }, + "regionAnchorY": { + enumerable: true, + get: function() { + return _regionAnchorY; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("RegionAnchorX must be between 0 and 100."); + } + _regionAnchorY = value; + } + }, + "regionAnchorX": { + enumerable: true, + get: function() { + return _regionAnchorX; + }, + set: function(value) { + if(!isValidPercentValue(value)) { + throw new Error("RegionAnchorY must be between 0 and 100."); + } + _regionAnchorX = value; + } + }, + "viewportAnchorY": { + enumerable: true, + get: function() { + return _viewportAnchorY; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("ViewportAnchorY must be between 0 and 100."); + } + _viewportAnchorY = value; + } + }, + "viewportAnchorX": { + enumerable: true, + get: function() { + return _viewportAnchorX; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("ViewportAnchorX must be between 0 and 100."); + } + _viewportAnchorX = value; + } + }, + "scroll": { + enumerable: true, + get: function() { + return _scroll; + }, + set: function(value) { + var setting = findScrollSetting(value); + // Have to check for false as an empty string is a legal value. + if (setting === false) { + throw new SyntaxError("An invalid or illegal string was specified."); + } + _scroll = setting; + } + } + }); + } + + root.VTTRegion = root.VTTRegion || VTTRegion; + vttjs.VTTRegion = VTTRegion; +}(this, (this.vttjs || {}))); + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + +(function(global) { + + var _objCreate = Object.create || (function() { + function F() {} + return function(o) { + if (arguments.length !== 1) { + throw new Error('Object.create shim only accepts one parameter.'); + } + F.prototype = o; + return new F(); + }; + })(); + + // Creates a new ParserError object from an errorData object. The errorData + // object should have default code and message properties. The default message + // property can be overriden by passing in a message parameter. + // See ParsingError.Errors below for acceptable errors. + function ParsingError(errorData, message) { + this.name = "ParsingError"; + this.code = errorData.code; + this.message = message || errorData.message; + } + ParsingError.prototype = _objCreate(Error.prototype); + ParsingError.prototype.constructor = ParsingError; + + // ParsingError metadata for acceptable ParsingErrors. + ParsingError.Errors = { + BadSignature: { + code: 0, + message: "Malformed WebVTT signature." + }, + BadTimeStamp: { + code: 1, + message: "Malformed time stamp." + } + }; + + // Try to parse input as a time stamp. + function parseTimeStamp(input) { + + function computeSeconds(h, m, s, f) { + return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; + } + + var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); + if (!m) { + return null; + } + + if (m[3]) { + // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] + return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); + } else if (m[1] > 59) { + // Timestamp takes the form of [hours]:[minutes].[milliseconds] + // First position is hours as it's over 59. + return computeSeconds(m[1], m[2], 0, m[4]); + } else { + // Timestamp takes the form of [minutes]:[seconds].[milliseconds] + return computeSeconds(0, m[1], m[2], m[4]); + } + } + + // A settings object holds key/value pairs and will ignore anything but the first + // assignment to a specific key. + function Settings() { + this.values = _objCreate(null); + } + + Settings.prototype = { + // Only accept the first assignment to any key. + set: function(k, v) { + if (!this.get(k) && v !== "") { + this.values[k] = v; + } + }, + // Return the value for a key, or a default value. + // If 'defaultKey' is passed then 'dflt' is assumed to be an object with + // a number of possible default values as properties where 'defaultKey' is + // the key of the property that will be chosen; otherwise it's assumed to be + // a single value. + get: function(k, dflt, defaultKey) { + if (defaultKey) { + return this.has(k) ? this.values[k] : dflt[defaultKey]; + } + return this.has(k) ? this.values[k] : dflt; + }, + // Check whether we have a value for a key. + has: function(k) { + return k in this.values; + }, + // Accept a setting if its one of the given alternatives. + alt: function(k, v, a) { + for (var n = 0; n < a.length; ++n) { + if (v === a[n]) { + this.set(k, v); + break; + } + } + }, + // Accept a setting if its a valid (signed) integer. + integer: function(k, v) { + if (/^-?\d+$/.test(v)) { // integer + this.set(k, parseInt(v, 10)); + } + }, + // Accept a setting if its a valid percentage. + percent: function(k, v) { + var m; + if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { + v = parseFloat(v); + if (v >= 0 && v <= 100) { + this.set(k, v); + return true; + } + } + return false; + } + }; + + // Helper function to parse input into groups separated by 'groupDelim', and + // interprete each group as a key/value pair separated by 'keyValueDelim'. + function parseOptions(input, callback, keyValueDelim, groupDelim) { + var groups = groupDelim ? input.split(groupDelim) : [input]; + for (var i in groups) { + if (typeof groups[i] !== "string") { + continue; + } + var kv = groups[i].split(keyValueDelim); + if (kv.length !== 2) { + continue; + } + var k = kv[0]; + var v = kv[1]; + callback(k, v); + } + } + + function parseCue(input, cue, regionList) { + // Remember the original input if we need to throw an error. + var oInput = input; + // 4.1 WebVTT timestamp + function consumeTimeStamp() { + var ts = parseTimeStamp(input); + if (ts === null) { + throw new ParsingError(ParsingError.Errors.BadTimeStamp, + "Malformed timestamp: " + oInput); + } + // Remove time stamp from input. + input = input.replace(/^[^\sa-zA-Z-]+/, ""); + return ts; + } + + // 4.4.2 WebVTT cue settings + function consumeCueSettings(input, cue) { + var settings = new Settings(); + + parseOptions(input, function (k, v) { + switch (k) { + case "region": + // Find the last region we parsed with the same region id. + for (var i = regionList.length - 1; i >= 0; i--) { + if (regionList[i].id === v) { + settings.set(k, regionList[i].region); + break; + } + } + break; + case "vertical": + settings.alt(k, v, ["rl", "lr"]); + break; + case "line": + var vals = v.split(","), + vals0 = vals[0]; + settings.integer(k, vals0); + settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; + settings.alt(k, vals0, ["auto"]); + if (vals.length === 2) { + settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); + } + break; + case "position": + vals = v.split(","); + settings.percent(k, vals[0]); + if (vals.length === 2) { + settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); + } + break; + case "size": + settings.percent(k, v); + break; + case "align": + settings.alt(k, v, ["start", "middle", "end", "left", "right"]); + break; + } + }, /:/, /\s/); + + // Apply default values for any missing fields. + cue.region = settings.get("region", null); + cue.vertical = settings.get("vertical", ""); + cue.line = settings.get("line", "auto"); + cue.lineAlign = settings.get("lineAlign", "start"); + cue.snapToLines = settings.get("snapToLines", true); + cue.size = settings.get("size", 100); + cue.align = settings.get("align", "middle"); + cue.position = settings.get("position", { + start: 0, + left: 0, + middle: 50, + end: 100, + right: 100 + }, cue.align); + cue.positionAlign = settings.get("positionAlign", { + start: "start", + left: "start", + middle: "middle", + end: "end", + right: "end" + }, cue.align); + } + + function skipWhitespace() { + input = input.replace(/^\s+/, ""); + } + + // 4.1 WebVTT cue timings. + skipWhitespace(); + cue.startTime = consumeTimeStamp(); // (1) collect cue start time + skipWhitespace(); + if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" + throw new ParsingError(ParsingError.Errors.BadTimeStamp, + "Malformed time stamp (time stamps must be separated by '-->'): " + + oInput); + } + input = input.substr(3); + skipWhitespace(); + cue.endTime = consumeTimeStamp(); // (5) collect cue end time + + // 4.1 WebVTT cue settings list. + skipWhitespace(); + consumeCueSettings(input, cue); + } + + var ESCAPE = { + "&": "&", + "<": "<", + ">": ">", + "‎": "\u200e", + "‏": "\u200f", + " ": "\u00a0" + }; + + var TAG_NAME = { + c: "span", + i: "i", + b: "b", + u: "u", + ruby: "ruby", + rt: "rt", + v: "span", + lang: "span" + }; + + var TAG_ANNOTATION = { + v: "title", + lang: "lang" + }; + + var NEEDS_PARENT = { + rt: "ruby" + }; + + // Parse content into a document fragment. + function parseContent(window, input) { + function nextToken() { + // Check for end-of-string. + if (!input) { + return null; + } + + // Consume 'n' characters from the input. + function consume(result) { + input = input.substr(result.length); + return result; + } + + var m = input.match(/^([^<]*)(<[^>]+>?)?/); + // If there is some text before the next tag, return it, otherwise return + // the tag. + return consume(m[1] ? m[1] : m[2]); + } + + // Unescape a string 's'. + function unescape1(e) { + return ESCAPE[e]; + } + function unescape(s) { + while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) { + s = s.replace(m[0], unescape1); + } + return s; + } + + function shouldAdd(current, element) { + return !NEEDS_PARENT[element.localName] || + NEEDS_PARENT[element.localName] === current.localName; + } + + // Create an element for this tag. + function createElement(type, annotation) { + var tagName = TAG_NAME[type]; + if (!tagName) { + return null; + } + var element = window.document.createElement(tagName); + element.localName = tagName; + var name = TAG_ANNOTATION[type]; + if (name && annotation) { + element[name] = annotation.trim(); + } + return element; + } + + var rootDiv = window.document.createElement("div"), + current = rootDiv, + t, + tagStack = []; + + while ((t = nextToken()) !== null) { + if (t[0] === '<') { + if (t[1] === "/") { + // If the closing tag matches, move back up to the parent node. + if (tagStack.length && + tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { + tagStack.pop(); + current = current.parentNode; + } + // Otherwise just ignore the end tag. + continue; + } + var ts = parseTimeStamp(t.substr(1, t.length - 2)); + var node; + if (ts) { + // Timestamps are lead nodes as well. + node = window.document.createProcessingInstruction("timestamp", ts); + current.appendChild(node); + continue; + } + var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); + // If we can't parse the tag, skip to the next tag. + if (!m) { + continue; + } + // Try to construct an element, and ignore the tag if we couldn't. + node = createElement(m[1], m[3]); + if (!node) { + continue; + } + // Determine if the tag should be added based on the context of where it + // is placed in the cuetext. + if (!shouldAdd(current, node)) { + continue; + } + // Set the class list (as a list of classes, separated by space). + if (m[2]) { + node.className = m[2].substr(1).replace('.', ' '); + } + // Append the node to the current node, and enter the scope of the new + // node. + tagStack.push(m[1]); + current.appendChild(node); + current = node; + continue; + } + + // Text nodes are leaf nodes. + current.appendChild(window.document.createTextNode(unescape(t))); + } + + return rootDiv; + } + + // This is a list of all the Unicode characters that have a strong + // right-to-left category. What this means is that these characters are + // written right-to-left for sure. It was generated by pulling all the strong + // right-to-left characters out of the Unicode data table. That table can + // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt + var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1, + 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, + 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, + 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1, + 0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F, + 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, + 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, + 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, + 0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643, + 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E, + 0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678, + 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681, + 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A, + 0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693, + 0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, + 0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, + 0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, + 0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7, + 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0, + 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9, + 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2, + 0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB, + 0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, + 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, + 0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718, + 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721, + 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A, + 0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750, + 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759, + 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762, + 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B, + 0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, + 0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, + 0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, + 0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F, + 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798, + 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1, + 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3, + 0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, + 0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, + 0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, + 0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7, + 0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802, + 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B, + 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, + 0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, + 0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, + 0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847, + 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850, + 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E, + 0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9, + 0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22, + 0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C, + 0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35, + 0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41, + 0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, + 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55, + 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E, + 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67, + 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, + 0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, + 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82, + 0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, + 0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94, + 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D, + 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6, + 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, + 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, + 0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, + 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB, + 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4, + 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED, + 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6, + 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF, + 0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08, + 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11, + 0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A, + 0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23, + 0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C, + 0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35, + 0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E, + 0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47, + 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50, + 0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59, + 0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62, + 0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B, + 0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74, + 0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, + 0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86, + 0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F, + 0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98, + 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1, + 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA, + 0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3, + 0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC, + 0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5, + 0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, + 0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7, + 0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0, + 0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9, + 0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2, + 0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB, + 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04, + 0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D, + 0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16, + 0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F, + 0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28, + 0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31, + 0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A, + 0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, + 0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E, + 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67, + 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70, + 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79, + 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82, + 0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B, + 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96, + 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F, + 0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8, + 0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1, + 0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA, + 0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3, + 0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4, + 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70, + 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, + 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83, + 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, + 0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, + 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, + 0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, + 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0, + 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, + 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2, + 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, + 0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, + 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, + 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, + 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF, + 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, + 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803, + 0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E, + 0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816, + 0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E, + 0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826, + 0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E, + 0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837, + 0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844, + 0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C, + 0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854, + 0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D, + 0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905, + 0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D, + 0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915, + 0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921, + 0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929, + 0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931, + 0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939, + 0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986, + 0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E, + 0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996, + 0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E, + 0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6, + 0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE, + 0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6, + 0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13, + 0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D, + 0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25, + 0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D, + 0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41, + 0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51, + 0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60, + 0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68, + 0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70, + 0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78, + 0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00, + 0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08, + 0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10, + 0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18, + 0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20, + 0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28, + 0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30, + 0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42, + 0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A, + 0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52, + 0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C, + 0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64, + 0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C, + 0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79, + 0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01, + 0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09, + 0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11, + 0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19, + 0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21, + 0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29, + 0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31, + 0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39, + 0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41, + 0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00, + 0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09, + 0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11, + 0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19, + 0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22, + 0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E, + 0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37, + 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E, + 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D, + 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A, + 0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74, + 0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E, + 0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87, + 0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90, + 0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98, + 0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6, + 0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF, + 0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7, + 0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD]; + + function determineBidi(cueDiv) { + var nodeStack = [], + text = "", + charCode; + + if (!cueDiv || !cueDiv.childNodes) { + return "ltr"; + } + + function pushNodes(nodeStack, node) { + for (var i = node.childNodes.length - 1; i >= 0; i--) { + nodeStack.push(node.childNodes[i]); + } + } + + function nextTextNode(nodeStack) { + if (!nodeStack || !nodeStack.length) { + return null; + } + + var node = nodeStack.pop(), + text = node.textContent || node.innerText; + if (text) { + // TODO: This should match all unicode type B characters (paragraph + // separator characters). See issue #115. + var m = text.match(/^.*(\n|\r)/); + if (m) { + nodeStack.length = 0; + return m[0]; + } + return text; + } + if (node.tagName === "ruby") { + return nextTextNode(nodeStack); + } + if (node.childNodes) { + pushNodes(nodeStack, node); + return nextTextNode(nodeStack); + } + } + + pushNodes(nodeStack, cueDiv); + while ((text = nextTextNode(nodeStack))) { + for (var i = 0; i < text.length; i++) { + charCode = text.charCodeAt(i); + for (var j = 0; j < strongRTLChars.length; j++) { + if (strongRTLChars[j] === charCode) { + return "rtl"; + } + } + } + } + return "ltr"; + } + + function computeLinePos(cue) { + if (typeof cue.line === "number" && + (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { + return cue.line; + } + if (!cue.track || !cue.track.textTrackList || + !cue.track.textTrackList.mediaElement) { + return -1; + } + var track = cue.track, + trackList = track.textTrackList, + count = 0; + for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { + if (trackList[i].mode === "showing") { + count++; + } + } + return ++count * -1; + } + + function StyleBox() { + } + + // Apply styles to a div. If there is no div passed then it defaults to the + // div on 'this'. + StyleBox.prototype.applyStyles = function(styles, div) { + div = div || this.div; + for (var prop in styles) { + if (styles.hasOwnProperty(prop)) { + div.style[prop] = styles[prop]; + } + } + }; + + StyleBox.prototype.formatStyle = function(val, unit) { + return val === 0 ? 0 : val + unit; + }; + + // Constructs the computed display state of the cue (a div). Places the div + // into the overlay which should be a block level element (usually a div). + function CueStyleBox(window, cue, styleOptions) { + var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); + var color = "rgba(255, 255, 255, 1)"; + var backgroundColor = "rgba(0, 0, 0, 0.8)"; + + if (isIE8) { + color = "rgb(255, 255, 255)"; + backgroundColor = "rgb(0, 0, 0)"; + } + + StyleBox.call(this); + this.cue = cue; + + // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will + // have inline positioning and will function as the cue background box. + this.cueDiv = parseContent(window, cue.text); + var styles = { + color: color, + backgroundColor: backgroundColor, + position: "relative", + left: 0, + right: 0, + top: 0, + bottom: 0, + display: "inline" + }; + + if (!isIE8) { + styles.writingMode = cue.vertical === "" ? "horizontal-tb" + : cue.vertical === "lr" ? "vertical-lr" + : "vertical-rl"; + styles.unicodeBidi = "plaintext"; + } + this.applyStyles(styles, this.cueDiv); + + // Create an absolutely positioned div that will be used to position the cue + // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS + // mirrors of them except "middle" which is "center" in CSS. + this.div = window.document.createElement("div"); + styles = { + textAlign: cue.align === "middle" ? "center" : cue.align, + font: styleOptions.font, + whiteSpace: "pre-line", + position: "absolute" + }; + + if (!isIE8) { + styles.direction = determineBidi(this.cueDiv); + styles.writingMode = cue.vertical === "" ? "horizontal-tb" + : cue.vertical === "lr" ? "vertical-lr" + : "vertical-rl". + stylesunicodeBidi = "plaintext"; + } + + this.applyStyles(styles); + + this.div.appendChild(this.cueDiv); + + // Calculate the distance from the reference edge of the viewport to the text + // position of the cue box. The reference edge will be resolved later when + // the box orientation styles are applied. + var textPos = 0; + switch (cue.positionAlign) { + case "start": + textPos = cue.position; + break; + case "middle": + textPos = cue.position - (cue.size / 2); + break; + case "end": + textPos = cue.position - cue.size; + break; + } + + // Horizontal box orientation; textPos is the distance from the left edge of the + // area to the left edge of the box and cue.size is the distance extending to + // the right from there. + if (cue.vertical === "") { + this.applyStyles({ + left: this.formatStyle(textPos, "%"), + width: this.formatStyle(cue.size, "%") + }); + // Vertical box orientation; textPos is the distance from the top edge of the + // area to the top edge of the box and cue.size is the height extending + // downwards from there. + } else { + this.applyStyles({ + top: this.formatStyle(textPos, "%"), + height: this.formatStyle(cue.size, "%") + }); + } + + this.move = function(box) { + this.applyStyles({ + top: this.formatStyle(box.top, "px"), + bottom: this.formatStyle(box.bottom, "px"), + left: this.formatStyle(box.left, "px"), + right: this.formatStyle(box.right, "px"), + height: this.formatStyle(box.height, "px"), + width: this.formatStyle(box.width, "px") + }); + }; + } + CueStyleBox.prototype = _objCreate(StyleBox.prototype); + CueStyleBox.prototype.constructor = CueStyleBox; + + // Represents the co-ordinates of an Element in a way that we can easily + // compute things with such as if it overlaps or intersects with another Element. + // Can initialize it with either a StyleBox or another BoxPosition. + function BoxPosition(obj) { + var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent); + + // Either a BoxPosition was passed in and we need to copy it, or a StyleBox + // was passed in and we need to copy the results of 'getBoundingClientRect' + // as the object returned is readonly. All co-ordinate values are in reference + // to the viewport origin (top left). + var lh, height, width, top; + if (obj.div) { + height = obj.div.offsetHeight; + width = obj.div.offsetWidth; + top = obj.div.offsetTop; + + var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && + rects.getClientRects && rects.getClientRects(); + obj = obj.div.getBoundingClientRect(); + // In certain cases the outter div will be slightly larger then the sum of + // the inner div's lines. This could be due to bold text, etc, on some platforms. + // In this case we should get the average line height and use that. This will + // result in the desired behaviour. + lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) + : 0; + + } + this.left = obj.left; + this.right = obj.right; + this.top = obj.top || top; + this.height = obj.height || height; + this.bottom = obj.bottom || (top + (obj.height || height)); + this.width = obj.width || width; + this.lineHeight = lh !== undefined ? lh : obj.lineHeight; + + if (isIE8 && !this.lineHeight) { + this.lineHeight = 13; + } + } + + // Move the box along a particular axis. Optionally pass in an amount to move + // the box. If no amount is passed then the default is the line height of the + // box. + BoxPosition.prototype.move = function(axis, toMove) { + toMove = toMove !== undefined ? toMove : this.lineHeight; + switch (axis) { + case "+x": + this.left += toMove; + this.right += toMove; + break; + case "-x": + this.left -= toMove; + this.right -= toMove; + break; + case "+y": + this.top += toMove; + this.bottom += toMove; + break; + case "-y": + this.top -= toMove; + this.bottom -= toMove; + break; + } + }; + + // Check if this box overlaps another box, b2. + BoxPosition.prototype.overlaps = function(b2) { + return this.left < b2.right && + this.right > b2.left && + this.top < b2.bottom && + this.bottom > b2.top; + }; + + // Check if this box overlaps any other boxes in boxes. + BoxPosition.prototype.overlapsAny = function(boxes) { + for (var i = 0; i < boxes.length; i++) { + if (this.overlaps(boxes[i])) { + return true; + } + } + return false; + }; + + // Check if this box is within another box. + BoxPosition.prototype.within = function(container) { + return this.top >= container.top && + this.bottom <= container.bottom && + this.left >= container.left && + this.right <= container.right; + }; + + // Check if this box is entirely within the container or it is overlapping + // on the edge opposite of the axis direction passed. For example, if "+x" is + // passed and the box is overlapping on the left edge of the container, then + // return true. + BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { + switch (axis) { + case "+x": + return this.left < container.left; + case "-x": + return this.right > container.right; + case "+y": + return this.top < container.top; + case "-y": + return this.bottom > container.bottom; + } + }; + + // Find the percentage of the area that this box is overlapping with another + // box. + BoxPosition.prototype.intersectPercentage = function(b2) { + var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), + y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), + intersectArea = x * y; + return intersectArea / (this.height * this.width); + }; + + // Convert the positions from this box to CSS compatible positions using + // the reference container's positions. This has to be done because this + // box's positions are in reference to the viewport origin, whereas, CSS + // values are in referecne to their respective edges. + BoxPosition.prototype.toCSSCompatValues = function(reference) { + return { + top: this.top - reference.top, + bottom: reference.bottom - this.bottom, + left: this.left - reference.left, + right: reference.right - this.right, + height: this.height, + width: this.width + }; + }; + + // Get an object that represents the box's position without anything extra. + // Can pass a StyleBox, HTMLElement, or another BoxPositon. + BoxPosition.getSimpleBoxPosition = function(obj) { + var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; + var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; + var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; + + obj = obj.div ? obj.div.getBoundingClientRect() : + obj.tagName ? obj.getBoundingClientRect() : obj; + var ret = { + left: obj.left, + right: obj.right, + top: obj.top || top, + height: obj.height || height, + bottom: obj.bottom || (top + (obj.height || height)), + width: obj.width || width + }; + return ret; + }; + + // Move a StyleBox to its specified, or next best, position. The containerBox + // is the box that contains the StyleBox, such as a div. boxPositions are + // a list of other boxes that the styleBox can't overlap with. + function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { + + // Find the best position for a cue box, b, on the video. The axis parameter + // is a list of axis, the order of which, it will move the box along. For example: + // Passing ["+x", "-x"] will move the box first along the x axis in the positive + // direction. If it doesn't find a good position for it there it will then move + // it along the x axis in the negative direction. + function findBestPosition(b, axis) { + var bestPosition, + specifiedPosition = new BoxPosition(b), + percentage = 1; // Highest possible so the first thing we get is better. + + for (var i = 0; i < axis.length; i++) { + while (b.overlapsOppositeAxis(containerBox, axis[i]) || + (b.within(containerBox) && b.overlapsAny(boxPositions))) { + b.move(axis[i]); + } + // We found a spot where we aren't overlapping anything. This is our + // best position. + if (b.within(containerBox)) { + return b; + } + var p = b.intersectPercentage(containerBox); + // If we're outside the container box less then we were on our last try + // then remember this position as the best position. + if (percentage > p) { + bestPosition = new BoxPosition(b); + percentage = p; + } + // Reset the box position to the specified position. + b = new BoxPosition(specifiedPosition); + } + return bestPosition || specifiedPosition; + } + + var boxPosition = new BoxPosition(styleBox), + cue = styleBox.cue, + linePos = computeLinePos(cue), + axis = []; + + // If we have a line number to align the cue to. + if (cue.snapToLines) { + var size; + switch (cue.vertical) { + case "": + axis = [ "+y", "-y" ]; + size = "height"; + break; + case "rl": + axis = [ "+x", "-x" ]; + size = "width"; + break; + case "lr": + axis = [ "-x", "+x" ]; + size = "width"; + break; + } + + var step = boxPosition.lineHeight, + position = step * Math.round(linePos), + maxPosition = containerBox[size] + step, + initialAxis = axis[0]; + + // If the specified intial position is greater then the max position then + // clamp the box to the amount of steps it would take for the box to + // reach the max position. + if (Math.abs(position) > maxPosition) { + position = position < 0 ? -1 : 1; + position *= Math.ceil(maxPosition / step) * step; + } + + // If computed line position returns negative then line numbers are + // relative to the bottom of the video instead of the top. Therefore, we + // need to increase our initial position by the length or width of the + // video, depending on the writing direction, and reverse our axis directions. + if (linePos < 0) { + position += cue.vertical === "" ? containerBox.height : containerBox.width; + axis = axis.reverse(); + } + + // Move the box to the specified position. This may not be its best + // position. + boxPosition.move(initialAxis, position); + + } else { + // If we have a percentage line value for the cue. + var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; + + switch (cue.lineAlign) { + case "middle": + linePos -= (calculatedPercentage / 2); + break; + case "end": + linePos -= calculatedPercentage; + break; + } + + // Apply initial line position to the cue box. + switch (cue.vertical) { + case "": + styleBox.applyStyles({ + top: styleBox.formatStyle(linePos, "%") + }); + break; + case "rl": + styleBox.applyStyles({ + left: styleBox.formatStyle(linePos, "%") + }); + break; + case "lr": + styleBox.applyStyles({ + right: styleBox.formatStyle(linePos, "%") + }); + break; + } + + axis = [ "+y", "-x", "+x", "-y" ]; + + // Get the box position again after we've applied the specified positioning + // to it. + boxPosition = new BoxPosition(styleBox); + } + + var bestPosition = findBestPosition(boxPosition, axis); + styleBox.move(bestPosition.toCSSCompatValues(containerBox)); + } + + function WebVTT() { + // Nothing + } + + // Helper to allow strings to be decoded instead of the default binary utf8 data. + WebVTT.StringDecoder = function() { + return { + decode: function(data) { + if (!data) { + return ""; + } + if (typeof data !== "string") { + throw new Error("Error - expected string data."); + } + return decodeURIComponent(encodeURIComponent(data)); + } + }; + }; + + WebVTT.convertCueToDOMTree = function(window, cuetext) { + if (!window || !cuetext) { + return null; + } + return parseContent(window, cuetext); + }; + + var FONT_SIZE_PERCENT = 0.05; + var FONT_STYLE = "sans-serif"; + var CUE_BACKGROUND_PADDING = "1.5%"; + + // Runs the processing model over the cues and regions passed to it. + // @param overlay A block level element (usually a div) that the computed cues + // and regions will be placed into. + WebVTT.processCues = function(window, cues, overlay) { + if (!window || !cues || !overlay) { + return null; + } + + // Remove all previous children. + while (overlay.firstChild) { + overlay.removeChild(overlay.firstChild); + } + + var paddedOverlay = window.document.createElement("div"); + paddedOverlay.style.position = "absolute"; + paddedOverlay.style.left = "0"; + paddedOverlay.style.right = "0"; + paddedOverlay.style.top = "0"; + paddedOverlay.style.bottom = "0"; + paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; + overlay.appendChild(paddedOverlay); + + // Determine if we need to compute the display states of the cues. This could + // be the case if a cue's state has been changed since the last computation or + // if it has not been computed yet. + function shouldCompute(cues) { + for (var i = 0; i < cues.length; i++) { + if (cues[i].hasBeenReset || !cues[i].displayState) { + return true; + } + } + return false; + } + + // We don't need to recompute the cues' display states. Just reuse them. + if (!shouldCompute(cues)) { + for (var i = 0; i < cues.length; i++) { + paddedOverlay.appendChild(cues[i].displayState); + } + return; + } + + var boxPositions = [], + containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), + fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; + var styleOptions = { + font: fontSize + "px " + FONT_STYLE + }; + + (function() { + var styleBox, cue; + + for (var i = 0; i < cues.length; i++) { + cue = cues[i]; + + // Compute the intial position and styles of the cue div. + styleBox = new CueStyleBox(window, cue, styleOptions); + paddedOverlay.appendChild(styleBox.div); + + // Move the cue div to it's correct line position. + moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); + + // Remember the computed div so that we don't have to recompute it later + // if we don't have too. + cue.displayState = styleBox.div; + + boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); + } + })(); + }; + + WebVTT.Parser = function(window, vttjs, decoder) { + if (!decoder) { + decoder = vttjs; + vttjs = {}; + } + if (!vttjs) { + vttjs = {}; + } + + this.window = window; + this.vttjs = vttjs; + this.state = "INITIAL"; + this.buffer = ""; + this.decoder = decoder || new TextDecoder("utf8"); + this.regionList = []; + }; + + WebVTT.Parser.prototype = { + // If the error is a ParsingError then report it to the consumer if + // possible. If it's not a ParsingError then throw it like normal. + reportOrThrowError: function(e) { + if (e instanceof ParsingError) { + this.onparsingerror && this.onparsingerror(e); + } else { + throw e; + } + }, + parse: function (data) { + var self = this; + + // If there is no data then we won't decode it, but will just try to parse + // whatever is in buffer already. This may occur in circumstances, for + // example when flush() is called. + if (data) { + // Try to decode the data that we received. + self.buffer += self.decoder.decode(data, {stream: true}); + } + + function collectNextLine() { + var buffer = self.buffer; + var pos = 0; + while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { + ++pos; + } + var line = buffer.substr(0, pos); + // Advance the buffer early in case we fail below. + if (buffer[pos] === '\r') { + ++pos; + } + if (buffer[pos] === '\n') { + ++pos; + } + self.buffer = buffer.substr(pos); + return line; + } + + // 3.4 WebVTT region and WebVTT region settings syntax + function parseRegion(input) { + var settings = new Settings(); + + parseOptions(input, function (k, v) { + switch (k) { + case "id": + settings.set(k, v); + break; + case "width": + settings.percent(k, v); + break; + case "lines": + settings.integer(k, v); + break; + case "regionanchor": + case "viewportanchor": + var xy = v.split(','); + if (xy.length !== 2) { + break; + } + // We have to make sure both x and y parse, so use a temporary + // settings object here. + var anchor = new Settings(); + anchor.percent("x", xy[0]); + anchor.percent("y", xy[1]); + if (!anchor.has("x") || !anchor.has("y")) { + break; + } + settings.set(k + "X", anchor.get("x")); + settings.set(k + "Y", anchor.get("y")); + break; + case "scroll": + settings.alt(k, v, ["up"]); + break; + } + }, /=/, /\s/); + + // Create the region, using default values for any values that were not + // specified. + if (settings.has("id")) { + var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); + region.width = settings.get("width", 100); + region.lines = settings.get("lines", 3); + region.regionAnchorX = settings.get("regionanchorX", 0); + region.regionAnchorY = settings.get("regionanchorY", 100); + region.viewportAnchorX = settings.get("viewportanchorX", 0); + region.viewportAnchorY = settings.get("viewportanchorY", 100); + region.scroll = settings.get("scroll", ""); + // Register the region. + self.onregion && self.onregion(region); + // Remember the VTTRegion for later in case we parse any VTTCues that + // reference it. + self.regionList.push({ + id: settings.get("id"), + region: region + }); + } + } + + // 3.2 WebVTT metadata header syntax + function parseHeader(input) { + parseOptions(input, function (k, v) { + switch (k) { + case "Region": + // 3.3 WebVTT region metadata header syntax + parseRegion(v); + break; + } + }, /:/); + } + + // 5.1 WebVTT file parsing. + try { + var line; + if (self.state === "INITIAL") { + // We can't start parsing until we have the first line. + if (!/\r\n|\n/.test(self.buffer)) { + return this; + } + + line = collectNextLine(); + + var m = line.match(/^WEBVTT([ \t].*)?$/); + if (!m || !m[0]) { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + + self.state = "HEADER"; + } + + var alreadyCollectedLine = false; + while (self.buffer) { + // We can't parse a line until we have the full line. + if (!/\r\n|\n/.test(self.buffer)) { + return this; + } + + if (!alreadyCollectedLine) { + line = collectNextLine(); + } else { + alreadyCollectedLine = false; + } + + switch (self.state) { + case "HEADER": + // 13-18 - Allow a header (metadata) under the WEBVTT line. + if (/:/.test(line)) { + parseHeader(line); + } else if (!line) { + // An empty line terminates the header and starts the body (cues). + self.state = "ID"; + } + continue; + case "NOTE": + // Ignore NOTE blocks. + if (!line) { + self.state = "ID"; + } + continue; + case "ID": + // Check for the start of NOTE blocks. + if (/^NOTE($|[ \t])/.test(line)) { + self.state = "NOTE"; + break; + } + // 19-29 - Allow any number of line terminators, then initialize new cue values. + if (!line) { + continue; + } + self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); + self.state = "CUE"; + // 30-39 - Check if self line contains an optional identifier or timing data. + if (line.indexOf("-->") === -1) { + self.cue.id = line; + continue; + } + // Process line as start of a cue. + /*falls through*/ + case "CUE": + // 40 - Collect cue timings and settings. + try { + parseCue(line, self.cue, self.regionList); + } catch (e) { + self.reportOrThrowError(e); + // In case of an error ignore rest of the cue. + self.cue = null; + self.state = "BADCUE"; + continue; + } + self.state = "CUETEXT"; + continue; + case "CUETEXT": + var hasSubstring = line.indexOf("-->") !== -1; + // 34 - If we have an empty line then report the cue. + // 35 - If we have the special substring '-->' then report the cue, + // but do not collect the line as we need to process the current + // one as a new cue. + if (!line || hasSubstring && (alreadyCollectedLine = true)) { + // We are done parsing self cue. + self.oncue && self.oncue(self.cue); + self.cue = null; + self.state = "ID"; + continue; + } + if (self.cue.text) { + self.cue.text += "\n"; + } + self.cue.text += line; + continue; + case "BADCUE": // BADCUE + // 54-62 - Collect and discard the remaining cue. + if (!line) { + self.state = "ID"; + } + continue; + } + } + } catch (e) { + self.reportOrThrowError(e); + + // If we are currently parsing a cue, report what we have. + if (self.state === "CUETEXT" && self.cue && self.oncue) { + self.oncue(self.cue); + } + self.cue = null; + // Enter BADWEBVTT state if header was not parsed correctly otherwise + // another exception occurred so enter BADCUE state. + self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; + } + return this; + }, + flush: function () { + var self = this; + try { + // Finish decoding the stream. + self.buffer += self.decoder.decode(); + // Synthesize the end of the current cue or region. + if (self.cue || self.state === "HEADER") { + self.buffer += "\n\n"; + self.parse(); + } + // If we've flushed, parsed, and we're still on the INITIAL state then + // that means we don't have enough of the stream to parse the first + // line. + if (self.state === "INITIAL") { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + } catch(e) { + self.reportOrThrowError(e); + } + self.onflush && self.onflush(); + return this; + } + }; + + global.WebVTT = WebVTT; + +}(this, (this.vttjs || {}))); diff --git a/addons/webinterface.default/lib/video-js/video.min.js b/addons/webinterface.default/lib/video-js/video.min.js new file mode 100644 index 0000000000..4741bb2546 --- /dev/null +++ b/addons/webinterface.default/lib/video-js/video.min.js @@ -0,0 +1,19 @@ +/** + * @license + * Video.js 5.15.1 <http://videojs.com/> + * Copyright Brightcove, Inc. <https://www.brightcove.com/> + * Available under Apache License Version 2.0 + * <https://github.com/videojs/video.js/blob/master/LICENSE> + * + * Includes vtt.js <https://github.com/mozilla/vtt.js> + * Available under Apache License Version 2.0 + * <https://github.com/mozilla/vtt.js/blob/master/LICENSE> + */ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.videojs=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};a[g][0].call(k.exports,function(b){var c=a[g][1][b];return e(c?c:b)},k,k.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(2),i=d(h),j=a(5),k=d(j),l=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-big-play-button"},b.prototype.handleClick=function(a){this.player_.play()},b}(i["default"]);l.prototype.controlText_="Play Video",k["default"].registerComponent("BigPlayButton",l),c["default"]=l},{2:2,5:5}],2:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(3),i=d(h),j=a(5),k=d(j),l=a(86),m=d(l),n=a(88),o=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"button",b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};b=(0,n.assign)({className:this.buildCSSClass()},b),"button"!==a&&(m["default"].warn("Creating a Button with an HTML element of "+a+" is deprecated; use ClickableComponent instead."),b=(0,n.assign)({tabIndex:0},b),c=(0,n.assign)({role:"button"},c)),c=(0,n.assign)({type:"button","aria-live":"polite"},c);var d=k["default"].prototype.createEl.call(this,a,b,c);return this.createControlTextEl(d),d},b.prototype.addChild=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=this.constructor.name;return m["default"].warn("Adding an actionable (user controllable) child to a Button ("+c+") is not supported; use a ClickableComponent instead."),k["default"].prototype.addChild.call(this,a,b)},b.prototype.enable=function(){a.prototype.enable.call(this),this.el_.removeAttribute("disabled")},b.prototype.disable=function(){a.prototype.disable.call(this),this.el_.setAttribute("disabled","disabled")},b.prototype.handleKeyPress=function(b){32!==b.which&&13!==b.which&&a.prototype.handleKeyPress.call(this,b)},b}(i["default"]);k["default"].registerComponent("Button",o),c["default"]=o},{3:3,5:5,86:86,88:88}],3:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(82),n=d(m),o=a(83),p=d(o),q=a(86),r=e(q),s=a(94),t=e(s),u=a(88),v=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.emitTapEvents(),e.enable(),e}return h(b,a),b.prototype.createEl=function(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},d=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};c=(0,u.assign)({className:this.buildCSSClass(),tabIndex:0},c),"button"===b&&r["default"].error("Creating a ClickableComponent with an HTML element of "+b+" is not supported; use a Button instead."),d=(0,u.assign)({role:"button","aria-live":"polite"},d),this.tabIndex_=c.tabIndex;var e=a.prototype.createEl.call(this,b,c,d);return this.createControlTextEl(e),e},b.prototype.createControlTextEl=function(a){return this.controlTextEl_=l.createEl("span",{className:"vjs-control-text"}),a&&a.appendChild(this.controlTextEl_),this.controlText(this.controlText_,a),this.controlTextEl_},b.prototype.controlText=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.el();if(!a)return this.controlText_||"Need Text";var c=this.localize(a);return this.controlText_=a,this.controlTextEl_.innerHTML=c,b.setAttribute("title",c),this},b.prototype.buildCSSClass=function(){return"vjs-control vjs-button "+a.prototype.buildCSSClass.call(this)},b.prototype.enable=function(){return this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),"undefined"!=typeof this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on("tap",this.handleClick),this.on("click",this.handleClick),this.on("focus",this.handleFocus),this.on("blur",this.handleBlur),this},b.prototype.disable=function(){return this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),"undefined"!=typeof this.tabIndex_&&this.el_.removeAttribute("tabIndex"),this.off("tap",this.handleClick),this.off("click",this.handleClick),this.off("focus",this.handleFocus),this.off("blur",this.handleBlur),this},b.prototype.handleClick=function(a){},b.prototype.handleFocus=function(a){n.on(t["default"],"keydown",p.bind(this,this.handleKeyPress))},b.prototype.handleKeyPress=function(b){32===b.which||13===b.which?(b.preventDefault(),this.handleClick(b)):a.prototype.handleKeyPress&&a.prototype.handleKeyPress.call(this,b)},b.prototype.handleBlur=function(a){n.off(t["default"],"keydown",p.bind(this,this.handleKeyPress))},b}(j["default"]);j["default"].registerComponent("ClickableComponent",v),c["default"]=v},{5:5,81:81,82:82,83:83,86:86,88:88,94:94}],4:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(2),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return g.controlText(d&&d.controlText||g.localize("Close")),g}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-close-button "+a.prototype.buildCSSClass.call(this)},b.prototype.handleClick=function(a){this.trigger({type:"close",bubbles:!1})},b}(i["default"]);k["default"].registerComponent("CloseButton",l),c["default"]=l},{2:2,5:5}],5:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var g=a(95),h=e(g),i=a(81),j=d(i),k=a(83),l=d(k),m=a(85),n=d(m),o=a(82),p=d(o),q=a(86),r=e(q),s=a(91),t=e(s),u=a(87),v=e(u),w=function(){function a(b,c,d){if(f(this,a),!b&&this.play?this.player_=b=this:this.player_=b,this.options_=(0,v["default"])({},this.options_),c=this.options_=(0,v["default"])(this.options_,c),this.id_=c.id||c.el&&c.el.id,!this.id_){var e=b&&b.id&&b.id()||"no_player";this.id_=e+"_component_"+n.newGUID()}this.name_=c.name||null,c.el?this.el_=c.el:c.createEl!==!1&&(this.el_=this.createEl()),this.children_=[],this.childIndex_={},this.childNameIndex_={},c.initChildren!==!1&&this.initChildren(),this.ready(d),c.reportTouchActivity!==!1&&this.enableTouchActivity()}return a.prototype.dispose=function(){if(this.trigger({type:"dispose",bubbles:!1}),this.children_)for(var a=this.children_.length-1;a>=0;a--)this.children_[a].dispose&&this.children_[a].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.off(),this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),j.removeElData(this.el_),this.el_=null},a.prototype.player=function(){return this.player_},a.prototype.options=function(a){return r["default"].warn("this.options() has been deprecated and will be moved to the constructor in 6.0"),a?(this.options_=(0,v["default"])(this.options_,a),this.options_):this.options_},a.prototype.el=function(){return this.el_},a.prototype.createEl=function(a,b,c){return j.createEl(a,b,c)},a.prototype.localize=function(a){var b=this.player_.language&&this.player_.language(),c=this.player_.languages&&this.player_.languages();if(!b||!c)return a;var d=c[b];if(d&&d[a])return d[a];var e=b.split("-")[0],f=c[e];return f&&f[a]?f[a]:a},a.prototype.contentEl=function(){return this.contentEl_||this.el_},a.prototype.id=function(){return this.id_},a.prototype.name=function(){return this.name_},a.prototype.children=function(){return this.children_},a.prototype.getChildById=function(a){return this.childIndex_[a]},a.prototype.getChild=function(a){if(a)return a=(0,t["default"])(a),this.childNameIndex_[a]},a.prototype.addChild=function(b){var c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},d=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.children_.length,e=void 0,f=void 0;if("string"==typeof b){f=(0,t["default"])(b),c||(c={}),c===!0&&(r["default"].warn("Initializing a child component with `true` is deprecated.Children should be defined in an array when possible, but if necessary use an object instead of `true`."),c={});var g=c.componentClass||f;c.name=f;var h=a.getComponent(g);if(!h)throw new Error("Component "+g+" does not exist");if("function"!=typeof h)return null;e=new h(this.player_||this,c)}else e=b;if(this.children_.splice(d,0,e),"function"==typeof e.id&&(this.childIndex_[e.id()]=e),f=f||e.name&&e.name(),f&&(this.childNameIndex_[f]=e),"function"==typeof e.el&&e.el()){var i=this.contentEl().children,j=i[d]||null;this.contentEl().insertBefore(e.el(),j)}return e},a.prototype.removeChild=function(a){if("string"==typeof a&&(a=this.getChild(a)),a&&this.children_){for(var b=!1,c=this.children_.length-1;c>=0;c--)if(this.children_[c]===a){b=!0,this.children_.splice(c,1);break}if(b){this.childIndex_[a.id()]=null,this.childNameIndex_[a.name()]=null;var d=a.el();d&&d.parentNode===this.contentEl()&&this.contentEl().removeChild(a.el())}}},a.prototype.initChildren=function(){var b=this,c=this.options_.children;c&&!function(){var d=b.options_,e=function(a){var c=a.name,e=a.opts;if(void 0!==d[c]&&(e=d[c]),e!==!1){e===!0&&(e={}),e.playerOptions=b.options_.playerOptions;var f=b.addChild(c,e);f&&(b[c]=f)}},f=void 0,g=a.getComponent("Tech");f=Array.isArray(c)?c:Object.keys(c),f.concat(Object.keys(b.options_).filter(function(a){return!f.some(function(b){return"string"==typeof b?a===b:a===b.name})})).map(function(a){var d=void 0,e=void 0;return"string"==typeof a?(d=a,e=c[d]||b.options_[d]||{}):(d=a.name,e=a),{name:d,opts:e}}).filter(function(b){var c=a.getComponent(b.opts.componentClass||(0,t["default"])(b.name));return c&&!g.isTech(c)}).forEach(e)}()},a.prototype.buildCSSClass=function(){return""},a.prototype.on=function(a,b,c){var d=this;return"string"==typeof a||Array.isArray(a)?p.on(this.el_,a,l.bind(this,b)):!function(){var e=a,f=b,g=l.bind(d,c),h=function(){return d.off(e,f,g)};h.guid=g.guid,d.on("dispose",h);var i=function(){return d.off("dispose",h)};i.guid=g.guid,a.nodeName?(p.on(e,f,g),p.on(e,"dispose",i)):"function"==typeof a.on&&(e.on(f,g),e.on("dispose",i))}(),this},a.prototype.off=function(a,b,c){if(!a||"string"==typeof a||Array.isArray(a))p.off(this.el_,a,b);else{var d=a,e=b,f=l.bind(this,c);this.off("dispose",f),a.nodeName?(p.off(d,e,f),p.off(d,"dispose",f)):(d.off(e,f),d.off("dispose",f))}return this},a.prototype.one=function(a,b,c){var d=this,e=arguments;return"string"==typeof a||Array.isArray(a)?p.one(this.el_,a,l.bind(this,b)):!function(){var f=a,g=b,h=l.bind(d,c),i=function j(){d.off(f,g,j),h.apply(null,e)};i.guid=h.guid,d.on(f,g,i)}(),this},a.prototype.trigger=function(a,b){return p.trigger(this.el_,a,b),this},a.prototype.ready=function(a){var b=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return a&&(this.isReady_?b?a.call(this):this.setTimeout(a,1):(this.readyQueue_=this.readyQueue_||[],this.readyQueue_.push(a))),this},a.prototype.triggerReady=function(){this.isReady_=!0,this.setTimeout(function(){var a=this.readyQueue_;this.readyQueue_=[],a&&a.length>0&&a.forEach(function(a){a.call(this)},this),this.trigger("ready")},1)},a.prototype.$=function(a,b){return j.$(a,b||this.contentEl())},a.prototype.$$=function(a,b){return j.$$(a,b||this.contentEl())},a.prototype.hasClass=function(a){return j.hasElClass(this.el_,a)},a.prototype.addClass=function(a){return j.addElClass(this.el_,a),this},a.prototype.removeClass=function(a){return j.removeElClass(this.el_,a),this},a.prototype.toggleClass=function(a,b){return j.toggleElClass(this.el_,a,b),this},a.prototype.show=function(){return this.removeClass("vjs-hidden"),this},a.prototype.hide=function(){return this.addClass("vjs-hidden"),this},a.prototype.lockShowing=function(){return this.addClass("vjs-lock-showing"),this},a.prototype.unlockShowing=function(){return this.removeClass("vjs-lock-showing"),this},a.prototype.getAttribute=function(a){return j.getAttribute(this.el_,a)},a.prototype.setAttribute=function(a,b){return j.setAttribute(this.el_,a,b),this},a.prototype.removeAttribute=function(a){return j.removeAttribute(this.el_,a),this},a.prototype.width=function(a,b){return this.dimension("width",a,b)},a.prototype.height=function(a,b){return this.dimension("height",a,b)},a.prototype.dimensions=function(a,b){return this.width(a,!0).height(b)},a.prototype.dimension=function(a,b,c){if(void 0!==b)return null!==b&&b===b||(b=0),(""+b).indexOf("%")!==-1||(""+b).indexOf("px")!==-1?this.el_.style[a]=b:"auto"===b?this.el_.style[a]="":this.el_.style[a]=b+"px",c||this.trigger("resize"),this;if(!this.el_)return 0;var d=this.el_.style[a],e=d.indexOf("px");return e!==-1?parseInt(d.slice(0,e),10):parseInt(this.el_["offset"+(0,t["default"])(a)],10)},a.prototype.currentDimension=function(a){var b=0;if("width"!==a&&"height"!==a)throw new Error("currentDimension only accepts width or height value");if("function"==typeof h["default"].getComputedStyle){var c=h["default"].getComputedStyle(this.el_);b=c.getPropertyValue(a)||c[a]}if(b=parseFloat(b),0===b){var d="offset"+(0,t["default"])(a);b=this.el_[d]}return b},a.prototype.currentDimensions=function(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}},a.prototype.currentWidth=function(){return this.currentDimension("width")},a.prototype.currentHeight=function(){return this.currentDimension("height")},a.prototype.emitTapEvents=function(){var a=0,b=null,c=10,d=200,e=void 0;this.on("touchstart",function(c){1===c.touches.length&&(b={pageX:c.touches[0].pageX,pageY:c.touches[0].pageY},a=(new Date).getTime(),e=!0)}),this.on("touchmove",function(a){if(a.touches.length>1)e=!1;else if(b){var d=a.touches[0].pageX-b.pageX,f=a.touches[0].pageY-b.pageY,g=Math.sqrt(d*d+f*f);g>c&&(e=!1)}});var f=function(){e=!1};this.on("touchleave",f),this.on("touchcancel",f),this.on("touchend",function(c){if(b=null,e===!0){var f=(new Date).getTime()-a;f<d&&(c.preventDefault(),this.trigger("tap"))}})},a.prototype.enableTouchActivity=function(){if(this.player()&&this.player().reportUserActivity){var a=l.bind(this.player(),this.player().reportUserActivity),b=void 0;this.on("touchstart",function(){a(),this.clearInterval(b),b=this.setInterval(a,250)});var c=function(c){a(),this.clearInterval(b)};this.on("touchmove",a),this.on("touchend",c),this.on("touchcancel",c)}},a.prototype.setTimeout=function(a,b){a=l.bind(this,a);var c=h["default"].setTimeout(a,b),d=function(){this.clearTimeout(c)};return d.guid="vjs-timeout-"+c,this.on("dispose",d),c},a.prototype.clearTimeout=function(a){h["default"].clearTimeout(a);var b=function(){};return b.guid="vjs-timeout-"+a,this.off("dispose",b),a},a.prototype.setInterval=function(a,b){a=l.bind(this,a);var c=h["default"].setInterval(a,b),d=function(){this.clearInterval(c)};return d.guid="vjs-interval-"+c,this.on("dispose",d),c},a.prototype.clearInterval=function(a){h["default"].clearInterval(a);var b=function(){};return b.guid="vjs-interval-"+a,this.off("dispose",b),a},a.registerComponent=function(b,c){if(b)return b=(0,t["default"])(b),a.components_||(a.components_={}),"Player"===b&&a.components_[b]&&!function(){var c=a.components_[b];if(c.players&&Object.keys(c.players).length>0&&Object.keys(c.players).map(function(a){return c.players[a]}).every(Boolean))throw new Error("Can not register Player component after player has been created")}(),a.components_[b]=c,c},a.getComponent=function(b){if(b)return b=(0,t["default"])(b),a.components_&&a.components_[b]?a.components_[b]:h["default"]&&h["default"].videojs&&h["default"].videojs[b]?(r["default"].warn("The "+b+" component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)"),h["default"].videojs[b]):void 0},a.extend=function(b){b=b||{},r["default"].warn("Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead");var c=b.init||b.init||this.prototype.init||this.prototype.init||function(){},d=function(){c.apply(this,arguments)};d.prototype=Object.create(this.prototype),d.prototype.constructor=d,d.extend=a.extend;for(var e in b)b.hasOwnProperty(e)&&(d.prototype[e]=b[e]);return d},a}();w.registerComponent("Component",w),c["default"]=w},{81:81,82:82,83:83,85:85,86:86,87:87,91:91,95:95}],6:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(36),i=d(h),j=a(5),k=d(j),l=a(7),m=d(l),n=function(a){function b(c){var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,b),d.tracks=c.audioTracks&&c.audioTracks();var g=f(this,a.call(this,c,d));return g.el_.setAttribute("aria-label","Audio Menu"),g}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-audio-button "+a.prototype.buildCSSClass.call(this)},b.prototype.createItems=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],b=this.player_.audioTracks&&this.player_.audioTracks();if(!b)return a;for(var c=0;c<b.length;c++){var d=b[c];a.push(new m["default"](this.player_,{track:d,selectable:!0}))}return a},b}(i["default"]);n.prototype.controlText_="Audio Track",k["default"].registerComponent("AudioTrackButton",n),c["default"]=n},{36:36,5:5,7:7}],7:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(48),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=function(a){function b(c,d){f(this,b);var e=d.track,h=c.audioTracks();d.label=e.label||e.language||"Unknown",d.selected=e.enabled;var i=g(this,a.call(this,c,d));return i.track=e,h&&!function(){var a=n.bind(i,i.handleTracksChange);h.addEventListener("change",a),i.on("dispose",function(){h.removeEventListener("change",a)})}(),i}return h(b,a),b.prototype.handleClick=function(b){var c=this.player_.audioTracks();if(a.prototype.handleClick.call(this,b),c)for(var d=0;d<c.length;d++){var e=c[d];e.enabled=e===this.track}},b.prototype.handleTracksChange=function(a){this.selected(this.track.enabled)},b}(j["default"]);l["default"].registerComponent("AudioTrackMenuItem",o),c["default"]=o},{48:48,5:5,83:83}],8:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h);a(12),a(32),a(33),a(35),a(34),a(10),a(18),a(9),a(38),a(40),a(11),a(25),a(27),a(29),a(24),a(6),a(13),a(21);var j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-control-bar",dir:"ltr"},{role:"group"})},b}(i["default"]);j.prototype.options_={children:["playToggle","volumeMenuButton","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subtitlesButton","captionsButton","audioTrackButton","fullscreenToggle"]},i["default"].registerComponent("ControlBar",j),c["default"]=j},{10:10,11:11,12:12,13:13,18:18,21:21,24:24,25:25,27:27,29:29,32:32,33:33,34:34,35:35,38:38,40:40,5:5,6:6,9:9}],9:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(2),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return g.on(c,"fullscreenchange",g.handleFullscreenChange),g}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-fullscreen-control "+a.prototype.buildCSSClass.call(this)},b.prototype.handleFullscreenChange=function(a){this.player_.isFullscreen()?this.controlText("Non-Fullscreen"):this.controlText("Fullscreen")},b.prototype.handleClick=function(a){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()},b}(i["default"]);l.prototype.controlText_="Fullscreen",k["default"].registerComponent("FullscreenToggle",l),c["default"]=l},{2:2,5:5}],10:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.updateShowing(),e.on(e.player(),"durationchange",e.updateShowing),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,"div",{className:"vjs-live-control vjs-control"});return this.contentEl_=l.createEl("div",{className:"vjs-live-display",innerHTML:'<span class="vjs-control-text">'+this.localize("Stream Type")+"</span>"+this.localize("LIVE")},{"aria-live":"off"}),b.appendChild(this.contentEl_),b},b.prototype.updateShowing=function(a){this.player().duration()===1/0?this.show():this.hide()},b}(j["default"]);j["default"].registerComponent("LiveDisplay",m),c["default"]=m},{5:5,81:81}],11:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(2),j=e(i),k=a(5),l=e(k),m=a(81),n=d(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"volumechange",e.update),c.tech_&&c.tech_.featuresVolumeControl===!1&&e.addClass("vjs-hidden"),e.on(c,"loadstart",function(){this.update(),c.tech_.featuresVolumeControl===!1?this.addClass("vjs-hidden"):this.removeClass("vjs-hidden")}),e}return h(b,a),b.prototype.buildCSSClass=function(){return"vjs-mute-control "+a.prototype.buildCSSClass.call(this)},b.prototype.handleClick=function(a){this.player_.muted(!this.player_.muted())},b.prototype.update=function(a){var b=this.player_.volume(),c=3;0===b||this.player_.muted()?c=0:b<.33?c=1:b<.67&&(c=2);var d=this.player_.muted()?"Unmute":"Mute";this.controlText()!==d&&this.controlText(d);for(var e=0;e<4;e++)n.removeElClass(this.el_,"vjs-vol-"+e);n.addElClass(this.el_,"vjs-vol-"+c)},b}(j["default"]);o.prototype.controlText_="Mute",l["default"].registerComponent("MuteToggle",o),c["default"]=o},{2:2,5:5,81:81}],12:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(2),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return g.on(c,"play",g.handlePlay),g.on(c,"pause",g.handlePause),g}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-play-control "+a.prototype.buildCSSClass.call(this)},b.prototype.handleClick=function(a){this.player_.paused()?this.player_.play():this.player_.pause()},b.prototype.handlePlay=function(a){this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")},b.prototype.handlePause=function(a){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")},b}(i["default"]);l.prototype.controlText_="Play",k["default"].registerComponent("PlayToggle",l),c["default"]=l},{2:2,5:5}],13:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(47),j=e(i),k=a(49),l=e(k),m=a(14),n=e(m),o=a(5),p=e(o),q=a(81),r=d(q),s=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.updateVisibility(),e.updateLabel(),e.on(c,"loadstart",e.updateVisibility),e.on(c,"ratechange",e.updateLabel),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this);return this.labelEl_=r.createEl("div",{className:"vjs-playback-rate-value",innerHTML:1}),b.appendChild(this.labelEl_),b},b.prototype.buildCSSClass=function(){return"vjs-playback-rate "+a.prototype.buildCSSClass.call(this)},b.prototype.createMenu=function(){var a=new l["default"](this.player()),b=this.playbackRates();if(b)for(var c=b.length-1;c>=0;c--)a.addChild(new n["default"](this.player(),{rate:b[c]+"x"}));return a},b.prototype.updateARIAAttributes=function(){this.el().setAttribute("aria-valuenow",this.player().playbackRate())},b.prototype.handleClick=function(a){for(var b=this.player().playbackRate(),c=this.playbackRates(),d=c[0],e=0;e<c.length;e++)if(c[e]>b){ +d=c[e];break}this.player().playbackRate(d)},b.prototype.playbackRates=function(){return this.options_.playbackRates||this.options_.playerOptions&&this.options_.playerOptions.playbackRates},b.prototype.playbackRateSupported=function(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&this.playbackRates().length>0},b.prototype.updateVisibility=function(a){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")},b.prototype.updateLabel=function(a){this.playbackRateSupported()&&(this.labelEl_.innerHTML=this.player().playbackRate()+"x")},b}(j["default"]);s.prototype.controlText_="Playback Rate",p["default"].registerComponent("PlaybackRateMenuButton",s),c["default"]=s},{14:14,47:47,49:49,5:5,81:81}],14:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(48),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b);var g=d.rate,h=parseFloat(g,10);d.label=g,d.selected=1===h;var i=f(this,a.call(this,c,d));return i.label=g,i.rate=h,i.on(c,"ratechange",i.update),i}return g(b,a),b.prototype.handleClick=function(b){a.prototype.handleClick.call(this),this.player().playbackRate(this.rate)},b.prototype.update=function(a){this.selected(this.player().playbackRate()===this.rate)},b}(i["default"]);l.prototype.contentElType="button",k["default"].registerComponent("PlaybackRateMenuItem",l),c["default"]=l},{48:48,5:5}],15:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.partEls_=[],e.on(c,"progress",e.update),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text"><span>'+this.localize("Loaded")+"</span>: 0%</span>"})},b.prototype.update=function(a){var b=this.player_.buffered(),c=this.player_.duration(),d=this.player_.bufferedEnd(),e=this.partEls_,f=function(a,b){var c=a/b||0;return 100*(c>=1?1:c)+"%"};this.el_.style.width=f(d,c);for(var g=0;g<b.length;g++){var h=b.start(g),i=b.end(g),j=e[g];j||(j=this.el_.appendChild(l.createEl()),e[g]=j),j.style.left=f(h,d),j.style.width=f(i-h,d)}for(var k=e.length;k>b.length;k--)this.el_.removeChild(e[k-1]);e.length=b.length},b}(j["default"]);j["default"].registerComponent("LoadProgressBar",m),c["default"]=m},{5:5,81:81}],16:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(83),n=d(m),o=a(84),p=e(o),q=a(80),r=e(q),s=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return d.playerOptions&&d.playerOptions.controlBar&&d.playerOptions.controlBar.progressControl&&d.playerOptions.controlBar.progressControl.keepTooltipsInside&&(e.keepTooltipsInside=d.playerOptions.controlBar.progressControl.keepTooltipsInside),e.keepTooltipsInside&&(e.tooltip=l.createEl("div",{className:"vjs-time-tooltip"}),e.el().appendChild(e.tooltip),e.addClass("vjs-keep-tooltips-inside")),e.update(0,0),c.on("ready",function(){e.on(c.controlBar.progressControl.el(),"mousemove",n.throttle(n.bind(e,e.handleMouseMove),25))}),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},b.prototype.handleMouseMove=function(a){var b=this.player_.duration(),c=this.calculateDistance(a)*b,d=a.pageX-l.findElPosition(this.el().parentNode).left;this.update(c,d)},b.prototype.update=function(a,b){var c=(0,p["default"])(a,this.player_.duration());if(this.el().style.left=b+"px",this.el().setAttribute("data-current-time",c),this.keepTooltipsInside){var d=this.clampPosition_(b),e=b-d+1,f=parseFloat((0,r["default"])(this.tooltip,"width")),g=f/2;this.tooltip.innerHTML=c,this.tooltip.style.right="-"+(g-e)+"px"}},b.prototype.calculateDistance=function(a){return l.getPointerPosition(this.el().parentNode,a).x},b.prototype.clampPosition_=function(a){if(!this.keepTooltipsInside)return a;var b=parseFloat((0,r["default"])(this.player().el(),"width")),c=parseFloat((0,r["default"])(this.tooltip,"width")),d=c/2,e=a;return a<d?e=Math.ceil(d):a>b-d&&(e=Math.floor(b-d)),e},b}(j["default"]);j["default"].registerComponent("MouseTimeDisplay",s),c["default"]=s},{5:5,80:80,81:81,83:83,84:84}],17:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(83),l=d(k),m=a(84),n=e(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.updateDataAttr(),e.on(c,"timeupdate",e.updateDataAttr),c.ready(l.bind(e,e.updateDataAttr)),d.playerOptions&&d.playerOptions.controlBar&&d.playerOptions.controlBar.progressControl&&d.playerOptions.controlBar.progressControl.keepTooltipsInside&&(e.keepTooltipsInside=d.playerOptions.controlBar.progressControl.keepTooltipsInside),e.keepTooltipsInside&&e.addClass("vjs-keep-tooltips-inside"),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-play-progress vjs-slider-bar",innerHTML:'<span class="vjs-control-text"><span>'+this.localize("Progress")+"</span>: 0%</span>"})},b.prototype.updateDataAttr=function(a){var b=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();this.el_.setAttribute("data-current-time",(0,n["default"])(b,this.player_.duration()))},b}(j["default"]);j["default"].registerComponent("PlayProgressBar",o),c["default"]=o},{5:5,83:83,84:84}],18:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h);a(19),a(16);var j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-progress-control vjs-control"})},b}(i["default"]);j.prototype.options_={children:["seekBar"]},i["default"].registerComponent("ProgressControl",j),c["default"]=j},{16:16,19:19,5:5}],19:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(57),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=a(84),p=e(o),q=a(80),r=e(q);a(15),a(17),a(20);var s=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"timeupdate",e.updateProgress),e.on(c,"ended",e.updateProgress),c.ready(n.bind(e,e.updateProgress)),d.playerOptions&&d.playerOptions.controlBar&&d.playerOptions.controlBar.progressControl&&d.playerOptions.controlBar.progressControl.keepTooltipsInside&&(e.keepTooltipsInside=d.playerOptions.controlBar.progressControl.keepTooltipsInside),e.keepTooltipsInside&&(e.tooltipProgressBar=e.addChild("TooltipProgressBar")),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-progress-holder"},{"aria-label":"progress bar"})},b.prototype.updateProgress=function(a){if(this.updateAriaAttributes(this.el_),this.keepTooltipsInside){this.updateAriaAttributes(this.tooltipProgressBar.el_),this.tooltipProgressBar.el_.style.width=this.bar.el_.style.width;var b=parseFloat((0,r["default"])(this.player().el(),"width")),c=parseFloat((0,r["default"])(this.tooltipProgressBar.tooltip,"width")),d=this.tooltipProgressBar.el().style;d.maxWidth=Math.floor(b-c/2)+"px",d.minWidth=Math.ceil(c/2)+"px",d.right="-"+c/2+"px"}},b.prototype.updateAriaAttributes=function(a){var b=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();a.setAttribute("aria-valuenow",(100*this.getPercent()).toFixed(2)),a.setAttribute("aria-valuetext",(0,p["default"])(b,this.player_.duration()))},b.prototype.getPercent=function(){var a=this.player_.currentTime()/this.player_.duration();return a>=1?1:a},b.prototype.handleMouseDown=function(b){a.prototype.handleMouseDown.call(this,b),this.player_.scrubbing(!0),this.videoWasPlaying=!this.player_.paused(),this.pauseTimer_=this.setTimeout(function(){this.player_.pause()},100)},b.prototype.handleMouseMove=function(a){var b=this.calculateDistance(a)*this.player_.duration();b===this.player_.duration()&&(b-=.1),this.player_.currentTime(b),"mousemove"===a.type&&(this.clearTimeout(this.pauseTimer_),this.player_.pause())},b.prototype.handleMouseUp=function(b){a.prototype.handleMouseUp.call(this,b),this.clearTimeout(this.pauseTimer_),this.player_.scrubbing(!1),this.videoWasPlaying&&this.player_.play()},b.prototype.stepForward=function(){this.player_.currentTime(this.player_.currentTime()+5)},b.prototype.stepBack=function(){this.player_.currentTime(this.player_.currentTime()-5)},b}(j["default"]);s.prototype.options_={children:["loadProgressBar","mouseTimeDisplay","playProgressBar"],barName:"playProgressBar"},s.prototype.playerEvent="timeupdate",l["default"].registerComponent("SeekBar",s),c["default"]=s},{15:15,17:17,20:20,5:5,57:57,80:80,83:83,84:84}],20:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(83),l=d(k),m=a(84),n=e(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.updateDataAttr(),e.on(c,"timeupdate",e.updateDataAttr),c.ready(l.bind(e,e.updateDataAttr)),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,"div",{className:"vjs-tooltip-progress-bar vjs-slider-bar",innerHTML:'<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>'+this.localize("Progress")+"</span>: 0%</span>"});return this.tooltip=b.querySelector(".vjs-time-tooltip"),b},b.prototype.updateDataAttr=function(a){var b=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),c=(0,n["default"])(b,this.player_.duration());this.el_.setAttribute("data-current-time",c),this.tooltip.innerHTML=c},b}(j["default"]);j["default"].registerComponent("TooltipProgressBar",o),c["default"]=o},{5:5,83:83,84:84}],21:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(22),i=d(h),j=a(5),k=d(j),l=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-custom-control-spacer "+a.prototype.buildCSSClass.call(this)},b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,{className:this.buildCSSClass()});return b.innerHTML=" ",b},b}(i["default"]);k["default"].registerComponent("CustomControlSpacer",l),c["default"]=l},{22:22,5:5}],22:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-spacer "+a.prototype.buildCSSClass.call(this)},b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:this.buildCSSClass()})},b}(i["default"]);i["default"].registerComponent("Spacer",j),c["default"]=j},{5:5}],23:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(31),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b),d.track={player:c,kind:d.kind,label:d.kind+" settings",selectable:!1,"default":!1,mode:"disabled"},d.selectable=!1;var g=f(this,a.call(this,c,d));return g.addClass("vjs-texttrack-settings"),g.controlText(", opens "+d.kind+" settings dialog"),g}return g(b,a),b.prototype.handleClick=function(a){this.player().getChild("textTrackSettings").show(),this.player().getChild("textTrackSettings").el_.focus()},b}(i["default"]);k["default"].registerComponent("CaptionSettingsMenuItem",l),c["default"]=l},{31:31,5:5}],24:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(30),i=d(h),j=a(5),k=d(j),l=a(23),m=d(l),n=function(a){function b(c,d,g){e(this,b);var h=f(this,a.call(this,c,d,g));return h.el_.setAttribute("aria-label","Captions Menu"),h}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-captions-button "+a.prototype.buildCSSClass.call(this)},b.prototype.update=function(b){var c=2;a.prototype.update.call(this),this.player().tech_&&this.player().tech_.featuresNativeTextTracks&&(c=1),this.items&&this.items.length>c?this.show():this.hide()},b.prototype.createItems=function(){var b=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||b.push(new m["default"](this.player_,{kind:this.kind_})),a.prototype.createItems.call(this,b)},b}(i["default"]);n.prototype.kind_="captions",n.prototype.controlText_="Captions",k["default"].registerComponent("CaptionsButton",n),c["default"]=n},{23:23,30:30,5:5}],25:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(30),i=d(h),j=a(5),k=d(j),l=a(26),m=d(l),n=a(91),o=d(n),p=function(a){function b(c,d,g){e(this,b);var h=f(this,a.call(this,c,d,g));return h.el_.setAttribute("aria-label","Chapters Menu"),h}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-chapters-button "+a.prototype.buildCSSClass.call(this)},b.prototype.update=function(b){this.track_&&(!b||"addtrack"!==b.type&&"removetrack"!==b.type)||this.setTrack(this.findChaptersTrack()),a.prototype.update.call(this)},b.prototype.setTrack=function(a){if(this.track_!==a){if(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_){var b=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);b&&b.removeEventListener("load",this.updateHandler_),this.track_=null}if(this.track_=a,this.track_){this.track_.mode="hidden";var c=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);c&&c.addEventListener("load",this.updateHandler_)}}},b.prototype.findChaptersTrack=function(){for(var a=this.player_.textTracks()||[],b=a.length-1;b>=0;b--){var c=a[b];if(c.kind===this.kind_)return c}},b.prototype.getMenuCaption=function(){return this.track_&&this.track_.label?this.track_.label:this.localize((0,o["default"])(this.kind_))},b.prototype.createMenu=function(){return this.options_.title=this.getMenuCaption(),a.prototype.createMenu.call(this)},b.prototype.createItems=function(){var a=[];if(!this.track_)return a;var b=this.track_.cues;if(!b)return a;for(var c=0,d=b.length;c<d;c++){var e=b[c],f=new m["default"](this.player_,{track:this.track_,cue:e});a.push(f)}return a},b}(i["default"]);p.prototype.kind_="chapters",p.prototype.controlText_="Chapters",k["default"].registerComponent("ChaptersButton",p),c["default"]=p},{26:26,30:30,5:5,91:91}],26:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(48),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=function(a){function b(c,d){f(this,b);var e=d.track,h=d.cue,i=c.currentTime();d.selectable=!0,d.label=h.text,d.selected=h.startTime<=i&&i<h.endTime;var j=g(this,a.call(this,c,d));return j.track=e,j.cue=h,e.addEventListener("cuechange",n.bind(j,j.update)),j}return h(b,a),b.prototype.handleClick=function(b){a.prototype.handleClick.call(this),this.player_.currentTime(this.cue.startTime),this.update(this.cue.startTime)},b.prototype.update=function(a){var b=this.cue,c=this.player_.currentTime();this.selected(b.startTime<=c&&c<b.endTime)},b}(j["default"]);l["default"].registerComponent("ChaptersTrackMenuItem",o),c["default"]=o},{48:48,5:5,83:83}],27:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(30),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=function(a){function b(c,d,e){f(this,b);var h=g(this,a.call(this,c,d,e));h.el_.setAttribute("aria-label","Descriptions Menu");var i=c.textTracks();return i&&!function(){var a=n.bind(h,h.handleTracksChange);i.addEventListener("change",a),h.on("dispose",function(){i.removeEventListener("change",a)})}(),h}return h(b,a),b.prototype.handleTracksChange=function(a){for(var b=this.player().textTracks(),c=!1,d=0,e=b.length;d<e;d++){var f=b[d];if(f.kind!==this.kind_&&"showing"===f.mode){c=!0;break}}c?this.disable():this.enable()},b.prototype.buildCSSClass=function(){return"vjs-descriptions-button "+a.prototype.buildCSSClass.call(this)},b}(j["default"]);o.prototype.kind_="descriptions",o.prototype.controlText_="Descriptions",l["default"].registerComponent("DescriptionsButton",o),c["default"]=o},{30:30,5:5,83:83}],28:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(31),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d){e(this,b),d.track={player:c,kind:d.kind,label:d.kind+" off","default":!1,mode:"disabled"},d.selectable=!0;var g=f(this,a.call(this,c,d));return g.selected(!0),g}return g(b,a),b.prototype.handleTracksChange=function(a){for(var b=this.player().textTracks(),c=!0,d=0,e=b.length;d<e;d++){var f=b[d];if(f.kind===this.track.kind&&"showing"===f.mode){c=!1;break}}this.selected(c)},b}(i["default"]);k["default"].registerComponent("OffTextTrackMenuItem",l),c["default"]=l},{31:31,5:5}],29:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(30),i=d(h),j=a(5),k=d(j),l=function(a){function b(c,d,g){e(this,b);var h=f(this,a.call(this,c,d,g));return h.el_.setAttribute("aria-label","Subtitles Menu"),h}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-subtitles-button "+a.prototype.buildCSSClass.call(this)},b}(i["default"]);l.prototype.kind_="subtitles",l.prototype.controlText_="Subtitles",k["default"].registerComponent("SubtitlesButton",l),c["default"]=l},{30:30,5:5}],30:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(36),i=d(h),j=a(5),k=d(j),l=a(31),m=d(l),n=a(28),o=d(n),p=function(a){function b(c){var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e(this,b),d.tracks=c.textTracks(),f(this,a.call(this,c,d))}return g(b,a),b.prototype.createItems=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];a.push(new o["default"](this.player_,{kind:this.kind_}));var b=this.player_.textTracks();if(!b)return a;for(var c=0;c<b.length;c++){var d=b[c];d.kind===this.kind_&&a.push(new m["default"](this.player_,{track:d,selectable:!0}))}return a},b}(i["default"]);k["default"].registerComponent("TextTrackButton",p),c["default"]=p},{28:28,31:31,36:36,5:5}],31:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},j=a(48),k=e(j),l=a(5),m=e(l),n=a(83),o=d(n),p=a(95),q=e(p),r=a(94),s=e(r),t=function(a){function b(c,d){f(this,b);var e=d.track,h=c.textTracks();d.label=e.label||e.language||"Unknown",d.selected=e["default"]||"showing"===e.mode;var j=g(this,a.call(this,c,d));return j.track=e,h&&!function(){var a=o.bind(j,j.handleTracksChange);h.addEventListener("change",a),j.on("dispose",function(){h.removeEventListener("change",a)})}(),h&&void 0===h.onchange&&!function(){var a=void 0;j.on(["tap","click"],function(){if("object"!==i(q["default"].Event))try{a=new q["default"].Event("change")}catch(b){}a||(a=s["default"].createEvent("Event"),a.initEvent("change",!0,!0)),h.dispatchEvent(a)})}(),j}return h(b,a),b.prototype.handleClick=function(b){var c=this.track.kind,d=this.player_.textTracks();if(a.prototype.handleClick.call(this,b),d)for(var e=0;e<d.length;e++){var f=d[e];f.kind===c&&(f===this.track?f.mode="showing":f.mode="disabled")}},b.prototype.handleTracksChange=function(a){this.selected("showing"===this.track.mode)},b}(k["default"]);m["default"].registerComponent("TextTrackMenuItem",t),c["default"]=t},{48:48,5:5,83:83,94:94,95:95}],32:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}), +b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(84),n=e(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"timeupdate",e.updateContent),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,"div",{className:"vjs-current-time vjs-time-control vjs-control"});return this.contentEl_=l.createEl("div",{className:"vjs-current-time-display",innerHTML:'<span class="vjs-control-text">Current Time </span>0:00'},{"aria-live":"off"}),b.appendChild(this.contentEl_),b},b.prototype.updateContent=function(a){var b=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),c=this.localize("Current Time"),d=(0,n["default"])(b,this.player_.duration());d!==this.formattedTime_&&(this.formattedTime_=d,this.contentEl_.innerHTML='<span class="vjs-control-text">'+c+"</span> "+d)},b}(j["default"]);j["default"].registerComponent("CurrentTimeDisplay",o),c["default"]=o},{5:5,81:81,84:84}],33:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(84),n=e(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"durationchange",e.updateContent),e.on(c,"timeupdate",e.updateContent),e.on(c,"loadedmetadata",e.updateContent),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,"div",{className:"vjs-duration vjs-time-control vjs-control"});return this.contentEl_=l.createEl("div",{className:"vjs-duration-display",innerHTML:'<span class="vjs-control-text">'+this.localize("Duration Time")+"</span> 0:00"},{"aria-live":"off"}),b.appendChild(this.contentEl_),b},b.prototype.updateContent=function(a){var b=this.player_.duration();if(b&&this.duration_!==b){this.duration_=b;var c=this.localize("Duration Time"),d=(0,n["default"])(b);this.contentEl_.innerHTML='<span class="vjs-control-text">'+c+"</span> "+d}},b}(j["default"]);j["default"].registerComponent("DurationDisplay",o),c["default"]=o},{5:5,81:81,84:84}],34:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(84),n=e(m),o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"timeupdate",e.updateContent),e.on(c,"durationchange",e.updateContent),e}return h(b,a),b.prototype.createEl=function(){var b=a.prototype.createEl.call(this,"div",{className:"vjs-remaining-time vjs-time-control vjs-control"});return this.contentEl_=l.createEl("div",{className:"vjs-remaining-time-display",innerHTML:'<span class="vjs-control-text">'+this.localize("Remaining Time")+"</span> -0:00"},{"aria-live":"off"}),b.appendChild(this.contentEl_),b},b.prototype.updateContent=function(a){if(this.player_.duration()){var b=this.localize("Remaining Time"),c=(0,n["default"])(this.player_.remainingTime());c!==this.formattedTime_&&(this.formattedTime_=c,this.contentEl_.innerHTML='<span class="vjs-control-text">'+b+"</span> -"+c)}},b}(j["default"]);j["default"].registerComponent("RemainingTimeDisplay",o),c["default"]=o},{5:5,81:81,84:84}],35:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-time-control vjs-time-divider",innerHTML:"<div><span>/</span></div>"})},b}(i["default"]);i["default"].registerComponent("TimeDivider",j),c["default"]=j},{5:5}],36:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(47),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=function(a){function b(c,d){f(this,b);var e=d.tracks,h=g(this,a.call(this,c,d));if(h.items.length<=1&&h.hide(),!e)return g(h);var i=n.bind(h,h.update);return e.addEventListener("removetrack",i),e.addEventListener("addtrack",i),h.player_.on("dispose",function(){e.removeEventListener("removetrack",i),e.removeEventListener("addtrack",i)}),h}return h(b,a),b}(j["default"]);l["default"].registerComponent("TrackButton",o),c["default"]=o},{47:47,5:5,83:83}],37:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(57),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m);a(39);var o=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.on(c,"volumechange",e.updateARIAAttributes),c.ready(n.bind(e,e.updateARIAAttributes)),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":"volume level"})},b.prototype.handleMouseMove=function(a){this.checkMuted(),this.player_.volume(this.calculateDistance(a))},b.prototype.checkMuted=function(){this.player_.muted()&&this.player_.muted(!1)},b.prototype.getPercent=function(){return this.player_.muted()?0:this.player_.volume()},b.prototype.stepForward=function(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)},b.prototype.stepBack=function(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)},b.prototype.updateARIAAttributes=function(a){var b=(100*this.player_.volume()).toFixed(2);this.el_.setAttribute("aria-valuenow",b),this.el_.setAttribute("aria-valuetext",b+"%")},b}(j["default"]);o.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},o.prototype.playerEvent="volumechange",l["default"].registerComponent("VolumeBar",o),c["default"]=o},{39:39,5:5,57:57,83:83}],38:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h);a(37);var j=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return c.tech_&&c.tech_.featuresVolumeControl===!1&&g.addClass("vjs-hidden"),g.on(c,"loadstart",function(){c.tech_.featuresVolumeControl===!1?this.addClass("vjs-hidden"):this.removeClass("vjs-hidden")}),g}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-volume-control vjs-control"})},b}(i["default"]);j.prototype.options_={children:["volumeBar"]},i["default"].registerComponent("VolumeControl",j),c["default"]=j},{37:37,5:5}],39:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})},b}(i["default"]);i["default"].registerComponent("VolumeLevel",j),c["default"]=j},{5:5}],40:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(83),j=e(i),k=a(5),l=d(k),m=a(54),n=d(m),o=a(53),p=d(o),q=a(11),r=d(q),s=a(37),t=d(s),u=function(a){function b(c){function d(){c.tech_&&c.tech_.featuresVolumeControl===!1?this.addClass("vjs-hidden"):this.removeClass("vjs-hidden")}var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};f(this,b),void 0===e.inline&&(e.inline=!0),void 0===e.vertical&&(e.inline?e.vertical=!1:e.vertical=!0),e.volumeBar=e.volumeBar||{},e.volumeBar.vertical=!!e.vertical;var h=g(this,a.call(this,c,e));return h.on(c,"volumechange",h.volumeUpdate),h.on(c,"loadstart",h.volumeUpdate),d.call(h),h.on(c,"loadstart",d),h.on(h.volumeBar,["slideractive","focus"],function(){this.addClass("vjs-slider-active")}),h.on(h.volumeBar,["sliderinactive","blur"],function(){this.removeClass("vjs-slider-active")}),h.on(h.volumeBar,["focus"],function(){this.addClass("vjs-lock-showing")}),h.on(h.volumeBar,["blur"],function(){this.removeClass("vjs-lock-showing")}),h}return h(b,a),b.prototype.buildCSSClass=function(){var b="";return b=this.options_.vertical?"vjs-volume-menu-button-vertical":"vjs-volume-menu-button-horizontal","vjs-volume-menu-button "+a.prototype.buildCSSClass.call(this)+" "+b},b.prototype.createPopup=function(){var a=new n["default"](this.player_,{contentElType:"div"}),b=new t["default"](this.player_,this.options_.volumeBar);return a.addChild(b),this.menuContent=a,this.volumeBar=b,this.attachVolumeBarEvents(),a},b.prototype.handleClick=function(b){r["default"].prototype.handleClick.call(this),a.prototype.handleClick.call(this)},b.prototype.attachVolumeBarEvents=function(){this.menuContent.on(["mousedown","touchdown"],j.bind(this,this.handleMouseDown))},b.prototype.handleMouseDown=function(a){this.on(["mousemove","touchmove"],j.bind(this.volumeBar,this.volumeBar.handleMouseMove)),this.on(this.el_.ownerDocument,["mouseup","touchend"],this.handleMouseUp)},b.prototype.handleMouseUp=function(a){this.off(["mousemove","touchmove"],j.bind(this.volumeBar,this.volumeBar.handleMouseMove))},b}(p["default"]);u.prototype.volumeUpdate=r["default"].prototype.update,u.prototype.controlText_="Mute",l["default"].registerComponent("VolumeMenuButton",u),c["default"]=u},{11:11,37:37,5:5,53:53,54:54,83:83}],41:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=a(50),k=d(j),l=a(87),m=d(l),n=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return g.on(c,"error",g.open),g}return g(b,a),b.prototype.buildCSSClass=function(){return"vjs-error-display "+a.prototype.buildCSSClass.call(this)},b.prototype.content=function(){var a=this.player().error();return a?this.localize(a.message):""},b}(k["default"]);n.prototype.options_=(0,m["default"])(k["default"].prototype.options_,{fillAlways:!0,temporary:!1,uncloseable:!0}),i["default"].registerComponent("ErrorDisplay",n),c["default"]=n},{5:5,50:50,87:87}],42:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}c.__esModule=!0;var e=a(82),f=d(e),g=function(){};g.prototype.allowedEvents_={},g.prototype.on=function(a,b){var c=this.addEventListener;this.addEventListener=function(){},f.on(this,a,b),this.addEventListener=c},g.prototype.addEventListener=g.prototype.on,g.prototype.off=function(a,b){f.off(this,a,b)},g.prototype.removeEventListener=g.prototype.off,g.prototype.one=function(a,b){var c=this.addEventListener;this.addEventListener=function(){},f.one(this,a,b),this.addEventListener=c},g.prototype.trigger=function(a){var b=a.type||a;"string"==typeof a&&(a={type:b}),a=f.fixEvent(a),this.allowedEvents_[b]&&this["on"+b]&&this["on"+b](a),f.trigger(this,a)},g.prototype.dispatchEvent=g.prototype.trigger,c["default"]=g},{82:82}],43:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},f=a(86),g=d(f),h=a(88),i=function(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+("undefined"==typeof b?"undefined":e(b)));a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(a.super_=b)},j=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=function(){a.apply(this,arguments)},d={};(0,h.isObject)(b)?("function"==typeof b.init&&(g["default"].warn("Constructor logic via init() is deprecated; please use constructor() instead."),b.constructor=b.init),b.constructor!==Object.prototype.constructor&&(c=b.constructor),d=b):"function"==typeof b&&(c=b),i(c,a);for(var e in d)d.hasOwnProperty(e)&&(c.prototype[e]=d[e]);return c};c["default"]=j},{86:86,88:88}],44:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0;for(var e=a(94),f=d(e),g={},h=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],i=h[0],j=void 0,k=0;k<h.length;k++)if(h[k][1]in f["default"]){j=h[k];break}if(j)for(var l=0;l<j.length;l++)g[i[l]]=j[l];c["default"]=g},{94:94}],45:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=function(a){function b(){return e(this,b),f(this,a.apply(this,arguments))}return g(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-loading-spinner",dir:"ltr"})},b}(i["default"]);i["default"].registerComponent("LoadingSpinner",j),c["default"]=j},{5:5}],46:[function(a,b,c){"use strict";function d(a){return a instanceof d?a:("number"==typeof a?this.code=a:"string"==typeof a?this.message=a:(0,e.isObject)(a)&&("number"==typeof a.code&&(this.code=a.code),(0,e.assign)(this,a)),void(this.message||(this.message=d.defaultMessages[this.code]||"")))}c.__esModule=!0;var e=a(88);d.prototype.code=0,d.prototype.message="",d.prototype.status=null,d.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],d.defaultMessages={1:"You aborted the media playback",2:"A network error caused the media download to fail part-way.",3:"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",4:"The media could not be loaded, either because the server or network failed or because the format is not supported.",5:"The media is encrypted and we do not have the keys to decrypt it."};for(var f=0;f<d.errorTypes.length;f++)d[d.errorTypes[f]]=f,d.prototype[d.errorTypes[f]]=f;c["default"]=d},{88:88}],47:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(3),j=e(i),k=a(5),l=e(k),m=a(49),n=e(m),o=a(81),p=d(o),q=a(83),r=d(q),s=a(91),t=e(s),u=function(a){function b(c){var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};f(this,b);var e=g(this,a.call(this,c,d));return e.update(),e.enabled_=!0,e.el_.setAttribute("aria-haspopup","true"),e.el_.setAttribute("role","menuitem"),e.on("keydown",e.handleSubmenuKeyPress),e}return h(b,a),b.prototype.update=function(){var a=this.createMenu();this.menu&&this.removeChild(this.menu),this.menu=a,this.addChild(a),this.buttonPressed_=!1,this.el_.setAttribute("aria-expanded","false"),this.items&&0===this.items.length?this.hide():this.items&&this.items.length>1&&this.show()},b.prototype.createMenu=function(){var a=new n["default"](this.player_);if(this.options_.title){var b=p.createEl("li",{className:"vjs-menu-title",innerHTML:(0,t["default"])(this.options_.title),tabIndex:-1});a.children_.unshift(b),p.insertElFirst(b,a.contentEl())}if(this.items=this.createItems(),this.items)for(var c=0;c<this.items.length;c++)a.addItem(this.items[c]);return a},b.prototype.createItems=function(){},b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:this.buildCSSClass()})},b.prototype.buildCSSClass=function(){var b="vjs-menu-button";return b+=this.options_.inline===!0?"-inline":"-popup","vjs-menu-button "+b+" "+a.prototype.buildCSSClass.call(this)},b.prototype.handleClick=function(a){this.one(this.menu.contentEl(),"mouseleave",r.bind(this,function(a){this.unpressButton(),this.el_.blur()})),this.buttonPressed_?this.unpressButton():this.pressButton()},b.prototype.handleKeyPress=function(b){27===b.which||9===b.which?(this.buttonPressed_&&this.unpressButton(),9!==b.which&&b.preventDefault()):38===b.which||40===b.which?this.buttonPressed_||(this.pressButton(),b.preventDefault()):a.prototype.handleKeyPress.call(this,b)},b.prototype.handleSubmenuKeyPress=function(a){27!==a.which&&9!==a.which||(this.buttonPressed_&&this.unpressButton(),9!==a.which&&a.preventDefault())},b.prototype.pressButton=function(){this.enabled_&&(this.buttonPressed_=!0,this.menu.lockShowing(),this.el_.setAttribute("aria-expanded","true"),this.menu.focus())},b.prototype.unpressButton=function(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.el_.setAttribute("aria-expanded","false"),this.el_.focus())},b.prototype.disable=function(){return this.buttonPressed_=!1,this.menu.unlockShowing(),this.el_.setAttribute("aria-expanded","false"),this.enabled_=!1,a.prototype.disable.call(this)},b.prototype.enable=function(){return this.enabled_=!0,a.prototype.enable.call(this)},b}(j["default"]);l["default"].registerComponent("MenuButton",u),c["default"]=u},{3:3,49:49,5:5,81:81,83:83,91:91}],48:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(3),i=d(h),j=a(5),k=d(j),l=a(88),m=function(a){function b(c,d){e(this,b);var g=f(this,a.call(this,c,d));return g.selectable=d.selectable,g.selected(d.selected),g.selectable?g.el_.setAttribute("role","menuitemcheckbox"):g.el_.setAttribute("role","menuitem"),g}return g(b,a),b.prototype.createEl=function(b,c,d){return a.prototype.createEl.call(this,"li",(0,l.assign)({className:"vjs-menu-item",innerHTML:this.localize(this.options_.label),tabIndex:-1},c),d)},b.prototype.handleClick=function(a){this.selected(!0)},b.prototype.selected=function(a){this.selectable&&(a?(this.addClass("vjs-selected"),this.el_.setAttribute("aria-checked","true"),this.controlText(", selected")):(this.removeClass("vjs-selected"),this.el_.setAttribute("aria-checked","false"),this.controlText(" ")))},b}(i["default"]);k["default"].registerComponent("MenuItem",m),c["default"]=m},{3:3,5:5,88:88}],49:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(83),n=d(m),o=a(82),p=d(o),q=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.focusedChild_=-1,e.on("keydown",e.handleKeyPress),e}return h(b,a),b.prototype.addItem=function(a){this.addChild(a),a.on("click",n.bind(this,function(a){this.unlockShowing()}))},b.prototype.createEl=function(){var b=this.options_.contentElType||"ul";this.contentEl_=l.createEl(b,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");var c=a.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return c.setAttribute("role","presentation"),c.appendChild(this.contentEl_),p.on(c,"click",function(a){a.preventDefault(),a.stopImmediatePropagation()}),c},b.prototype.handleKeyPress=function(a){37===a.which||40===a.which?(a.preventDefault(),this.stepForward()):38!==a.which&&39!==a.which||(a.preventDefault(),this.stepBack())},b.prototype.stepForward=function(){var a=0;void 0!==this.focusedChild_&&(a=this.focusedChild_+1),this.focus(a)},b.prototype.stepBack=function(){var a=0;void 0!==this.focusedChild_&&(a=this.focusedChild_-1),this.focus(a)},b.prototype.focus=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,b=this.children().slice(),c=b.length&&b[0].className&&/vjs-menu-title/.test(b[0].className);c&&b.shift(),b.length>0&&(a<0?a=0:a>=b.length&&(a=b.length-1),this.focusedChild_=a,b[a].el_.focus())},b}(j["default"]);j["default"].registerComponent("Menu",q),c["default"]=q},{5:5,81:81,82:82,83:83}],50:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(81),j=e(i),k=a(83),l=e(k),m=a(5),n=d(m),o="vjs-modal-dialog",p=27,q=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.opened_=e.hasBeenOpened_=e.hasBeenFilled_=!1,e.closeable(!e.options_.uncloseable),e.content(e.options_.content),e.contentEl_=j.createEl("div",{className:o+"-content"},{role:"document"}),e.descEl_=j.createEl("p",{className:o+"-description vjs-offscreen",id:e.el().getAttribute("aria-describedby")}),j.textContent(e.descEl_,e.description()),e.el_.appendChild(e.descEl_),e.el_.appendChild(e.contentEl_),e}return h(b,a),b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":this.id()+"_description","aria-hidden":"true","aria-label":this.label(),role:"dialog"})},b.prototype.buildCSSClass=function(){return o+" vjs-hidden "+a.prototype.buildCSSClass.call(this)},b.prototype.handleKeyPress=function(a){a.which===p&&this.closeable()&&this.close()},b.prototype.label=function(){return this.options_.label||this.localize("Modal Window")},b.prototype.description=function(){var a=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(a+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),a},b.prototype.open=function(){if(!this.opened_){var a=this.player();this.trigger("beforemodalopen"),this.opened_=!0,(this.options_.fillAlways||!this.hasBeenOpened_&&!this.hasBeenFilled_)&&this.fill(),this.wasPlaying_=!a.paused(),this.wasPlaying_&&a.pause(),this.closeable()&&this.on(this.el_.ownerDocument,"keydown",l.bind(this,this.handleKeyPress)),a.controls(!1),this.show(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0}return this},b.prototype.opened=function(a){return"boolean"==typeof a&&this[a?"open":"close"](),this.opened_},b.prototype.close=function(){if(this.opened_){var a=this.player();this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&a.play(),this.closeable()&&this.off(this.el_.ownerDocument,"keydown",l.bind(this,this.handleKeyPress)),a.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.options_.temporary&&this.dispose()}return this},b.prototype.closeable=function c(a){if("boolean"==typeof a){var c=this.closeable_=!!a,b=this.getChild("closeButton");if(c&&!b){var d=this.contentEl_;this.contentEl_=this.el_,b=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=d,this.on(b,"close",this.close)}!c&&b&&(this.off(b,"close",this.close),this.removeChild(b),b.dispose())}return this.closeable_},b.prototype.fill=function(){return this.fillWith(this.content())},b.prototype.fillWith=function(a){var b=this.contentEl(),c=b.parentNode,d=b.nextSibling;return this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,c.removeChild(b),this.empty(),j.insertContent(b,a),this.trigger("modalfill"), +d?c.insertBefore(b,d):c.appendChild(b),this},b.prototype.empty=function(){return this.trigger("beforemodalempty"),j.emptyEl(this.contentEl()),this.trigger("modalempty"),this},b.prototype.content=function(a){return"undefined"!=typeof a&&(this.content_=a),this.content_},b}(n["default"]);q.prototype.options_={temporary:!0},n["default"].registerComponent("ModalDialog",q),c["default"]=q},{5:5,81:81,83:83}],51:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(94),l=e(k),m=a(95),n=e(m),o=a(82),p=d(o),q=a(81),r=d(q),s=a(83),t=d(s),u=a(85),v=d(u),w=a(78),x=d(w),y=a(86),z=e(y),A=a(91),B=e(A),C=a(90),D=a(79),E=a(89),F=d(E),G=a(44),H=e(G),I=a(46),J=e(I),K=a(97),L=e(K),M=a(88),N=a(87),O=e(N),P=a(69),Q=e(P),R=a(50),S=e(R),T=a(62),U=e(T),V=a(63),W=e(V),X=a(76),Y=e(X);a(61),a(59),a(55),a(68),a(45),a(1),a(4),a(8),a(41),a(71),a(60);var Z=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","ratechange","volumechange","texttrackchange"],$=function(a){function b(c,d,e){if(f(this,b),c.id=c.id||"vjs_video_"+v.newGUID(),d=(0,M.assign)(b.getTagSettings(c),d),d.initChildren=!1,d.createEl=!1,d.reportTouchActivity=!1,!d.language)if("function"==typeof c.closest){var h=c.closest("[lang]");h&&(d.language=h.getAttribute("lang"))}else for(var i=c;i&&1===i.nodeType;){if(r.getElAttributes(i).hasOwnProperty("lang")){d.language=i.getAttribute("lang");break}i=i.parentNode}var j=g(this,a.call(this,null,d,e));if(!j.options_||!j.options_.techOrder||!j.options_.techOrder.length)throw new Error("No techOrder specified. Did you overwrite videojs.options instead of just changing the properties you want to override?");j.tag=c,j.tagAttributes=c&&r.getElAttributes(c),j.language(j.options_.language),d.languages?!function(){var a={};Object.getOwnPropertyNames(d.languages).forEach(function(b){a[b.toLowerCase()]=d.languages[b]}),j.languages_=a}():j.languages_=b.prototype.options_.languages,j.cache_={},j.poster_=d.poster||"",j.controls_=!!d.controls,c.controls=!1,j.scrubbing_=!1,j.el_=j.createEl();var k=(0,O["default"])(j.options_);return d.plugins&&!function(){var a=d.plugins;Object.getOwnPropertyNames(a).forEach(function(b){"function"==typeof this[b]?this[b](a[b]):z["default"].error("Unable to find plugin:",b)},j)}(),j.options_.playerOptions=k,j.initChildren(),j.isAudio("audio"===c.nodeName.toLowerCase()),j.controls()?j.addClass("vjs-controls-enabled"):j.addClass("vjs-controls-disabled"),j.el_.setAttribute("role","region"),j.isAudio()?j.el_.setAttribute("aria-label","audio player"):j.el_.setAttribute("aria-label","video player"),j.isAudio()&&j.addClass("vjs-audio"),j.flexNotSupported_()&&j.addClass("vjs-no-flex"),x.IS_IOS||j.addClass("vjs-workinghover"),b.players[j.id_]=j,j.userActive(!0),j.reportUserActivity(),j.listenForUserActivity_(),j.on("fullscreenchange",j.handleFullscreenChange_),j.on("stageclick",j.handleStageClick_),j}return h(b,a),b.prototype.dispose=function(){this.trigger("dispose"),this.off("dispose"),this.styleEl_&&this.styleEl_.parentNode&&this.styleEl_.parentNode.removeChild(this.styleEl_),b.players[this.id_]=null,this.tag&&this.tag.player&&(this.tag.player=null),this.el_&&this.el_.player&&(this.el_.player=null),this.tech_&&this.tech_.dispose(),a.prototype.dispose.call(this)},b.prototype.createEl=function(){var b=this.tag,c=void 0,d=this.playerElIngest_=b.parentNode&&b.parentNode.hasAttribute("data-vjs-player");c=d?this.el_=b.parentNode:this.el_=a.prototype.createEl.call(this,"div"),b.removeAttribute("width"),b.removeAttribute("height");var e=r.getElAttributes(b);if(Object.getOwnPropertyNames(e).forEach(function(a){"class"===a?c.className+=" "+e[a]:c.setAttribute(a,e[a])}),b.playerId=b.id,b.id+="_html5_api",b.className="vjs-tech",b.player=c.player=this,this.addClass("vjs-paused"),n["default"].VIDEOJS_NO_DYNAMIC_STYLE!==!0){this.styleEl_=F.createStyleElement("vjs-styles-dimensions");var f=r.$(".vjs-styles-defaults"),g=r.$("head");g.insertBefore(this.styleEl_,f?f.nextSibling:g.firstChild)}this.width(this.options_.width),this.height(this.options_.height),this.fluid(this.options_.fluid),this.aspectRatio(this.options_.aspectRatio);for(var h=b.getElementsByTagName("a"),i=0;i<h.length;i++){var j=h.item(i);r.addElClass(j,"vjs-hidden"),j.setAttribute("hidden","hidden")}return b.initNetworkState_=b.networkState,b.parentNode&&!d&&b.parentNode.insertBefore(c,b),r.insertElFirst(b,c),this.children_.unshift(b),this.el_=c,c},b.prototype.width=function(a){return this.dimension("width",a)},b.prototype.height=function(a){return this.dimension("height",a)},b.prototype.dimension=function(a,b){var c=a+"_";if(void 0===b)return this[c]||0;if(""===b)this[c]=void 0;else{var d=parseFloat(b);if(isNaN(d))return z["default"].error('Improper value "'+b+'" supplied for for '+a),this;this[c]=d}return this.updateStyleEl_(),this},b.prototype.fluid=function(a){return void 0===a?!!this.fluid_:(this.fluid_=!!a,a?this.addClass("vjs-fluid"):this.removeClass("vjs-fluid"),void this.updateStyleEl_())},b.prototype.aspectRatio=function(a){if(void 0===a)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(a))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=a,this.fluid(!0),this.updateStyleEl_()},b.prototype.updateStyleEl_=function(){if(n["default"].VIDEOJS_NO_DYNAMIC_STYLE===!0){var a="number"==typeof this.width_?this.width_:this.options_.width,b="number"==typeof this.height_?this.height_:this.options_.height,c=this.tech_&&this.tech_.el();return void(c&&(a>=0&&(c.width=a),b>=0&&(c.height=b)))}var d=void 0,e=void 0,f=void 0,g=void 0;f=void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:this.videoWidth()>0?this.videoWidth()+":"+this.videoHeight():"16:9";var h=f.split(":"),i=h[1]/h[0];d=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/i:this.videoWidth()||300,e=void 0!==this.height_?this.height_:d*i,g=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(g),F.setTextContent(this.styleEl_,"\n ."+g+" {\n width: "+d+"px;\n height: "+e+"px;\n }\n\n ."+g+".vjs-fluid {\n padding-top: "+100*i+"%;\n }\n ")},b.prototype.loadTech_=function(a,b){var c=this;this.tech_&&this.unloadTech_(),"Html5"!==a&&this.tag&&(U["default"].getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=a,this.isReady_=!1;var d=(0,M.assign)({source:b,nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:this.id()+"_"+a+"_api",videoTracks:this.videoTracks_,textTracks:this.textTracks_,audioTracks:this.audioTracks_,autoplay:this.options_.autoplay,preload:this.options_.preload,loop:this.options_.loop,muted:this.options_.muted,poster:this.poster(),language:this.language(),playerElIngest:this.playerElIngest_||!1,"vtt.js":this.options_["vtt.js"]},this.options_[a.toLowerCase()]);this.tag&&(d.tag=this.tag),b&&(this.currentType_=b.type,b.src===this.cache_.src&&this.cache_.currentTime>0&&(d.startTime=this.cache_.currentTime),this.cache_.sources=null,this.cache_.source=b,this.cache_.src=b.src);var e=U["default"].getTech(a);e||(e=j["default"].getComponent(a)),this.tech_=new e(d),this.tech_.ready(t.bind(this,this.handleTechReady_),!0),Q["default"].jsonToTextTracks(this.textTracksJson_||[],this.tech_),Z.forEach(function(a){c.on(c.tech_,a,c["handleTech"+(0,B["default"])(a)+"_"])}),this.on(this.tech_,"loadstart",this.handleTechLoadStart_),this.on(this.tech_,"waiting",this.handleTechWaiting_),this.on(this.tech_,"canplay",this.handleTechCanPlay_),this.on(this.tech_,"canplaythrough",this.handleTechCanPlayThrough_),this.on(this.tech_,"playing",this.handleTechPlaying_),this.on(this.tech_,"ended",this.handleTechEnded_),this.on(this.tech_,"seeking",this.handleTechSeeking_),this.on(this.tech_,"seeked",this.handleTechSeeked_),this.on(this.tech_,"play",this.handleTechPlay_),this.on(this.tech_,"firstplay",this.handleTechFirstPlay_),this.on(this.tech_,"pause",this.handleTechPause_),this.on(this.tech_,"durationchange",this.handleTechDurationChange_),this.on(this.tech_,"fullscreenchange",this.handleTechFullscreenChange_),this.on(this.tech_,"error",this.handleTechError_),this.on(this.tech_,"loadedmetadata",this.updateStyleEl_),this.on(this.tech_,"posterchange",this.handleTechPosterChange_),this.on(this.tech_,"textdata",this.handleTechTextData_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===a&&this.tag||r.insertElFirst(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)},b.prototype.unloadTech_=function(){this.videoTracks_=this.videoTracks(),this.textTracks_=this.textTracks(),this.audioTracks_=this.audioTracks(),this.textTracksJson_=Q["default"].textTracksToJson(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1},b.prototype.tech=function(a){if(a&&a.IWillNotUseThisInPlugins)return this.tech_;var b="\n Please make sure that you are not using this inside of a plugin.\n To disable this alert and error, please pass in an object with\n `IWillNotUseThisInPlugins` to the `tech` method. See\n https://github.com/videojs/video.js/issues/2617 for more info.\n ";throw n["default"].alert(b),new Error(b)},b.prototype.addTechControlsListeners_=function(){this.removeTechControlsListeners_(),this.on(this.tech_,"mousedown",this.handleTechClick_),this.on(this.tech_,"touchstart",this.handleTechTouchStart_),this.on(this.tech_,"touchmove",this.handleTechTouchMove_),this.on(this.tech_,"touchend",this.handleTechTouchEnd_),this.on(this.tech_,"tap",this.handleTechTap_)},b.prototype.removeTechControlsListeners_=function(){this.off(this.tech_,"tap",this.handleTechTap_),this.off(this.tech_,"touchstart",this.handleTechTouchStart_),this.off(this.tech_,"touchmove",this.handleTechTouchMove_),this.off(this.tech_,"touchend",this.handleTechTouchEnd_),this.off(this.tech_,"mousedown",this.handleTechClick_)},b.prototype.handleTechReady_=function(){if(this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_(),(this.src()||this.currentSrc())&&this.tag&&this.options_.autoplay&&this.paused()){try{delete this.tag.poster}catch(a){(0,z["default"])("deleting tag.poster throws in some browsers",a)}this.play()}},b.prototype.handleTechLoadStart_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-seeking"),this.error(null),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):(this.trigger("loadstart"),this.trigger("firstplay"))},b.prototype.hasStarted=function(a){return void 0!==a?(this.hasStarted_!==a&&(this.hasStarted_=a,a?(this.addClass("vjs-has-started"),this.trigger("firstplay")):this.removeClass("vjs-has-started")),this):!!this.hasStarted_},b.prototype.handleTechPlay_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")},b.prototype.handleTechWaiting_=function(){var a=this;this.addClass("vjs-waiting"),this.trigger("waiting"),this.one("timeupdate",function(){return a.removeClass("vjs-waiting")})},b.prototype.handleTechCanPlay_=function(){this.removeClass("vjs-waiting"),this.trigger("canplay")},b.prototype.handleTechCanPlayThrough_=function(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")},b.prototype.handleTechPlaying_=function(){this.removeClass("vjs-waiting"),this.trigger("playing")},b.prototype.handleTechSeeking_=function(){this.addClass("vjs-seeking"),this.trigger("seeking")},b.prototype.handleTechSeeked_=function(){this.removeClass("vjs-seeking"),this.trigger("seeked")},b.prototype.handleTechFirstPlay_=function(){this.options_.starttime&&(z["default"].warn("Passing the `starttime` option to the player will be deprecated in 6.0"),this.currentTime(this.options_.starttime)),this.addClass("vjs-has-started"),this.trigger("firstplay")},b.prototype.handleTechPause_=function(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")},b.prototype.handleTechEnded_=function(){this.addClass("vjs-ended"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")},b.prototype.handleTechDurationChange_=function(){this.duration(this.techGet_("duration"))},b.prototype.handleTechClick_=function(a){0===a.button&&this.controls()&&(this.paused()?this.play():this.pause())},b.prototype.handleTechTap_=function(){this.userActive(!this.userActive())},b.prototype.handleTechTouchStart_=function(){this.userWasActive=this.userActive()},b.prototype.handleTechTouchMove_=function(){this.userWasActive&&this.reportUserActivity()},b.prototype.handleTechTouchEnd_=function(a){a.preventDefault()},b.prototype.handleFullscreenChange_=function(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")},b.prototype.handleStageClick_=function(){this.reportUserActivity()},b.prototype.handleTechFullscreenChange_=function(a,b){b&&this.isFullscreen(b.isFullscreen),this.trigger("fullscreenchange")},b.prototype.handleTechError_=function(){var a=this.tech_.error();this.error(a)},b.prototype.handleTechTextData_=function(){var a=null;arguments.length>1&&(a=arguments[1]),this.trigger("textdata",a)},b.prototype.getCache=function(){return this.cache_},b.prototype.techCall_=function(a,b){if(this.tech_&&!this.tech_.isReady_)this.tech_.ready(function(){this[a](b)},!0);else try{this.tech_&&this.tech_[a](b)}catch(c){throw(0,z["default"])(c),c}},b.prototype.techGet_=function(a){if(this.tech_&&this.tech_.isReady_)try{return this.tech_[a]()}catch(b){throw void 0===this.tech_[a]?(0,z["default"])("Video.js: "+a+" method not defined for "+this.techName_+" playback technology.",b):"TypeError"===b.name?((0,z["default"])("Video.js: "+a+" unavailable on "+this.techName_+" playback technology element.",b),this.tech_.isReady_=!1):(0,z["default"])(b),b}},b.prototype.play=function(){return this.src()||this.currentSrc()?this.techCall_("play"):this.tech_.one("loadstart",function(){this.play()}),this},b.prototype.pause=function(){return this.techCall_("pause"),this},b.prototype.paused=function(){return this.techGet_("paused")!==!1},b.prototype.scrubbing=function(a){return void 0!==a?(this.scrubbing_=!!a,a?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing"),this):this.scrubbing_},b.prototype.currentTime=function(a){return void 0!==a?(this.techCall_("setCurrentTime",a),this):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)},b.prototype.duration=function(a){return void 0===a?this.cache_.duration||0:(a=parseFloat(a)||0,a<0&&(a=1/0),a!==this.cache_.duration&&(this.cache_.duration=a,a===1/0?this.addClass("vjs-live"):this.removeClass("vjs-live"),this.trigger("durationchange")),this)},b.prototype.remainingTime=function(){return this.duration()-this.currentTime()},b.prototype.buffered=function c(){var c=this.techGet_("buffered");return c&&c.length||(c=(0,C.createTimeRange)(0,0)),c},b.prototype.bufferedPercent=function(){return(0,D.bufferedPercent)(this.buffered(),this.duration())},b.prototype.bufferedEnd=function(){var a=this.buffered(),b=this.duration(),c=a.end(a.length-1);return c>b&&(c=b),c},b.prototype.volume=function(a){var b=void 0;return void 0!==a?(b=Math.max(0,Math.min(1,parseFloat(a))),this.cache_.volume=b,this.techCall_("setVolume",b),this):(b=parseFloat(this.techGet_("volume")),isNaN(b)?1:b)},b.prototype.muted=function(a){return void 0!==a?(this.techCall_("setMuted",a),this):this.techGet_("muted")||!1},b.prototype.supportsFullScreen=function(){return this.techGet_("supportsFullScreen")||!1},b.prototype.isFullscreen=function(a){return void 0!==a?(this.isFullscreen_=!!a,this):!!this.isFullscreen_},b.prototype.requestFullscreen=function(){var a=H["default"];return this.isFullscreen(!0),a.requestFullscreen?(p.on(l["default"],a.fullscreenchange,t.bind(this,function b(c){this.isFullscreen(l["default"][a.fullscreenElement]),this.isFullscreen()===!1&&p.off(l["default"],a.fullscreenchange,b),this.trigger("fullscreenchange")})),this.el_[a.requestFullscreen]()):this.tech_.supportsFullScreen()?this.techCall_("enterFullScreen"):(this.enterFullWindow(),this.trigger("fullscreenchange")),this},b.prototype.exitFullscreen=function(){var a=H["default"];return this.isFullscreen(!1),a.requestFullscreen?l["default"][a.exitFullscreen]():this.tech_.supportsFullScreen()?this.techCall_("exitFullScreen"):(this.exitFullWindow(),this.trigger("fullscreenchange")),this},b.prototype.enterFullWindow=function(){this.isFullWindow=!0,this.docOrigOverflow=l["default"].documentElement.style.overflow,p.on(l["default"],"keydown",t.bind(this,this.fullWindowOnEscKey)),l["default"].documentElement.style.overflow="hidden",r.addElClass(l["default"].body,"vjs-full-window"),this.trigger("enterFullWindow")},b.prototype.fullWindowOnEscKey=function(a){27===a.keyCode&&(this.isFullscreen()===!0?this.exitFullscreen():this.exitFullWindow())},b.prototype.exitFullWindow=function(){this.isFullWindow=!1,p.off(l["default"],"keydown",this.fullWindowOnEscKey),l["default"].documentElement.style.overflow=this.docOrigOverflow,r.removeElClass(l["default"].body,"vjs-full-window"),this.trigger("exitFullWindow")},b.prototype.canPlayType=function(a){for(var b=void 0,c=0,d=this.options_.techOrder;c<d.length;c++){var e=(0,B["default"])(d[c]),f=U["default"].getTech(e);if(f||(f=j["default"].getComponent(e)),f){if(f.isSupported()&&(b=f.canPlayType(a)))return b}else z["default"].error('The "'+e+'" tech is undefined. Skipped browser support check for that tech.')}return""},b.prototype.selectSource=function(a){var b=this,c=this.options_.techOrder.map(B["default"]).map(function(a){return[a,U["default"].getTech(a)||j["default"].getComponent(a)]}).filter(function(a){var b=a[0],c=a[1];return c?c.isSupported():(z["default"].error('The "'+b+'" tech is undefined. Skipped browser support check for that tech.'),!1)}),d=function(a,b,c){var d=void 0;return a.some(function(a){return b.some(function(b){if(d=c(a,b))return!0})}),d},e=void 0,f=function(a){return function(b,c){return a(c,b)}},g=function(a,c){var d=a[0],e=a[1];if(e.canPlaySource(c,b.options_[d.toLowerCase()]))return{source:c,tech:d}};return e=this.options_.sourceOrder?d(a,c,f(g)):d(c,a,g),e||!1},b.prototype.src=function(a){if(void 0===a)return this.techGet_("src");var b=U["default"].getTech(this.techName_);return b||(b=j["default"].getComponent(this.techName_)),Array.isArray(a)?this.sourceList_(a):"string"==typeof a?this.src({src:a}):a instanceof Object&&(a.type&&!b.canPlaySource(a,this.options_[this.techName_.toLowerCase()])?this.sourceList_([a]):(this.cache_.sources=null,this.cache_.source=a,this.cache_.src=a.src,this.currentType_=a.type||"",this.ready(function(){b.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",a):this.techCall_("src",a.src),"auto"===this.options_.preload&&this.load(),this.options_.autoplay&&this.play()},!0))),this},b.prototype.sourceList_=function(a){var b=this.selectSource(a);b?(b.tech===this.techName_?this.src(b.source):this.loadTech_(b.tech,b.source),this.cache_.sources=a):(this.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0),this.triggerReady())},b.prototype.load=function(){return this.techCall_("load"),this},b.prototype.reset=function(){return this.loadTech_((0,B["default"])(this.options_.techOrder[0]),null),this.techCall_("reset"),this},b.prototype.currentSources=function(){var a=this.currentSource(),b=[];return 0!==Object.keys(a).length&&b.push(a),this.cache_.sources||b},b.prototype.currentSource=function(){var a={},b=this.currentSrc();return b&&(a.src=b),this.cache_.source||a},b.prototype.currentSrc=function(){return this.techGet_("currentSrc")||this.cache_.src||""},b.prototype.currentType=function(){return this.currentType_||""},b.prototype.preload=function(a){return void 0!==a?(this.techCall_("setPreload",a),this.options_.preload=a,this):this.techGet_("preload")},b.prototype.autoplay=function(a){return void 0!==a?(this.techCall_("setAutoplay",a),this.options_.autoplay=a,this):this.techGet_("autoplay",a)},b.prototype.loop=function(a){return void 0!==a?(this.techCall_("setLoop",a),this.options_.loop=a,this):this.techGet_("loop")},b.prototype.poster=function(a){return void 0===a?this.poster_:(a||(a=""),this.poster_=a,this.techCall_("setPoster",a),this.trigger("posterchange"),this)},b.prototype.handleTechPosterChange_=function(){!this.poster_&&this.tech_&&this.tech_.poster&&(this.poster_=this.tech_.poster()||"",this.trigger("posterchange"))},b.prototype.controls=function(a){return void 0!==a?(a=!!a,this.controls_!==a&&(this.controls_=a,this.usingNativeControls()&&this.techCall_("setControls",a),a?(this.removeClass("vjs-controls-disabled"),this.addClass("vjs-controls-enabled"),this.trigger("controlsenabled"),this.usingNativeControls()||this.addTechControlsListeners_()):(this.removeClass("vjs-controls-enabled"),this.addClass("vjs-controls-disabled"),this.trigger("controlsdisabled"),this.usingNativeControls()||this.removeTechControlsListeners_())),this):!!this.controls_},b.prototype.usingNativeControls=function(a){return void 0!==a?(a=!!a,this.usingNativeControls_!==a&&(this.usingNativeControls_=a,a?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols"))),this):!!this.usingNativeControls_},b.prototype.error=function(a){return void 0===a?this.error_||null:null===a?(this.error_=a,this.removeClass("vjs-error"),this.errorDisplay&&this.errorDisplay.close(),this):(this.error_=new J["default"](a),this.addClass("vjs-error"),z["default"].error("(CODE:"+this.error_.code+" "+J["default"].errorTypes[this.error_.code]+")",this.error_.message,this.error_),this.trigger("error"),this)},b.prototype.reportUserActivity=function(a){this.userActivity_=!0},b.prototype.userActive=function(a){return void 0!==a?(a=!!a,a!==this.userActive_&&(this.userActive_=a,a?(this.userActivity_=!0,this.removeClass("vjs-user-inactive"),this.addClass("vjs-user-active"),this.trigger("useractive")):(this.userActivity_=!1,this.tech_&&this.tech_.one("mousemove",function(a){a.stopPropagation(),a.preventDefault()}),this.removeClass("vjs-user-active"),this.addClass("vjs-user-inactive"),this.trigger("userinactive"))),this):this.userActive_},b.prototype.listenForUserActivity_=function(){var a=void 0,b=void 0,c=void 0,d=t.bind(this,this.reportUserActivity),e=function(a){a.screenX===b&&a.screenY===c||(b=a.screenX,c=a.screenY,d())},f=function(){d(),this.clearInterval(a),a=this.setInterval(d,250)},g=function(b){d(),this.clearInterval(a)};this.on("mousedown",f),this.on("mousemove",e),this.on("mouseup",g),this.on("keydown",d),this.on("keyup",d);var h=void 0;this.setInterval(function(){if(this.userActivity_){this.userActivity_=!1,this.userActive(!0),this.clearTimeout(h);var a=this.options_.inactivityTimeout;a>0&&(h=this.setTimeout(function(){this.userActivity_||this.userActive(!1)},a))}},250)},b.prototype.playbackRate=function(a){return void 0!==a?(this.techCall_("setPlaybackRate",a),this):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("playbackRate"):1},b.prototype.isAudio=function(a){return void 0!==a?(this.isAudio_=!!a,this):!!this.isAudio_},b.prototype.videoTracks=function(){return this.tech_?this.tech_.videoTracks():(this.videoTracks_=this.videoTracks_||new Y["default"],this.videoTracks_)},b.prototype.audioTracks=function(){return this.tech_?this.tech_.audioTracks():(this.audioTracks_=this.audioTracks_||new W["default"],this.audioTracks_)},b.prototype.textTracks=function(){if(this.tech_)return this.tech_.textTracks()},b.prototype.remoteTextTracks=function(){if(this.tech_)return this.tech_.remoteTextTracks()},b.prototype.remoteTextTrackEls=function(){if(this.tech_)return this.tech_.remoteTextTrackEls()},b.prototype.addTextTrack=function(a,b,c){if(this.tech_)return this.tech_.addTextTrack(a,b,c)},b.prototype.addRemoteTextTrack=function(a,b){if(this.tech_)return this.tech_.addRemoteTextTrack(a,b)},b.prototype.removeRemoteTextTrack=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},b=a.track,c=void 0===b?arguments[0]:b;if(this.tech_)return this.tech_.removeRemoteTextTrack(c)},b.prototype.videoWidth=function(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0},b.prototype.videoHeight=function(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0},b.prototype.language=function(a){return void 0===a?this.language_:(this.language_=String(a).toLowerCase(),this)},b.prototype.languages=function(){return(0,O["default"])(b.prototype.options_.languages,this.languages_)},b.prototype.toJSON=function(){var a=(0,O["default"])(this.options_),b=a.tracks;a.tracks=[];for(var c=0;c<b.length;c++){var d=b[c];d=(0,O["default"])(d),d.player=void 0,a.tracks[c]=d}return a},b.prototype.createModal=function(a,b){var c=this;b=b||{},b.content=a||"";var d=new S["default"](this,b);return this.addChild(d),d.on("dispose",function(){c.removeChild(d)}),d.open()},b.getTagSettings=function(a){var b={sources:[],tracks:[]},c=r.getElAttributes(a),d=c["data-setup"];if(r.hasElClass(a,"vjs-fluid")&&(c.fluid=!0),null!==d){var e=(0,L["default"])(d||"{}"),f=e[0],g=e[1];f&&z["default"].error(f),(0,M.assign)(c,g)}if((0,M.assign)(b,c),a.hasChildNodes())for(var h=a.childNodes,i=0,j=h.length;i<j;i++){var k=h[i],l=k.nodeName.toLowerCase();"source"===l?b.sources.push(r.getElAttributes(k)):"track"===l&&b.tracks.push(r.getElAttributes(k))}return b},b.prototype.flexNotSupported_=function(){var a=l["default"].createElement("i");return!("flexBasis"in a.style||"webkitFlexBasis"in a.style||"mozFlexBasis"in a.style||"msFlexBasis"in a.style||"msFlexOrder"in a.style)},b}(j["default"]);$.players={};var _=n["default"].navigator;$.prototype.options_={techOrder:["html5","flash"],html5:{},flash:{},defaultVolume:0,inactivityTimeout:2e3,playbackRates:[],children:["mediaLoader","posterImage","textTrackDisplay","loadingSpinner","bigPlayButton","controlBar","errorDisplay","textTrackSettings"],language:_&&(_.languages&&_.languages[0]||_.userLanguage||_.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media."},["ended","seeking","seekable","networkState","readyState"].forEach(function(a){$.prototype[a]=function(){return this.techGet_(a)}}),Z.forEach(function(a){$.prototype["handleTech"+(0,B["default"])(a)+"_"]=function(){return this.trigger(a)}}),j["default"].registerComponent("Player",$),c["default"]=$},{1:1,4:4,41:41,44:44,45:45,46:46,5:5,50:50,55:55,59:59,60:60,61:61,62:62,63:63,68:68,69:69,71:71,76:76,78:78,79:79,8:8,81:81,82:82,83:83,85:85,86:86,87:87,88:88,89:89,90:90,91:91,94:94,95:95,97:97}],52:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0;var e=a(51),f=d(e),g=function(a,b){f["default"].prototype[a]=b};c["default"]=g},{51:51}],53:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(3),i=d(h),j=a(5),k=d(j),l=function(a){function b(c){var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,b);var g=f(this,a.call(this,c,d));return g.update(),g}return g(b,a),b.prototype.update=function(){var a=this.createPopup();this.popup&&this.removeChild(this.popup),this.popup=a,this.addChild(a),this.items&&0===this.items.length?this.hide():this.items&&this.items.length>1&&this.show()},b.prototype.createPopup=function(){},b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:this.buildCSSClass()})},b.prototype.buildCSSClass=function(){var b="vjs-menu-button";return b+=this.options_.inline===!0?"-inline":"-popup","vjs-menu-button "+b+" "+a.prototype.buildCSSClass.call(this)},b}(i["default"]);k["default"].registerComponent("PopupButton",l),c["default"]=l},{3:3,5:5}],54:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(83),n=d(m),o=a(82),p=d(o),q=function(a){function b(){return f(this,b),g(this,a.apply(this,arguments))}return h(b,a),b.prototype.addItem=function(a){this.addChild(a),a.on("click",n.bind(this,function(){this.unlockShowing()}))},b.prototype.createEl=function(){var b=this.options_.contentElType||"ul";this.contentEl_=l.createEl(b,{className:"vjs-menu-content"});var c=a.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return c.appendChild(this.contentEl_),p.on(c,"click",function(a){a.preventDefault(),a.stopImmediatePropagation()}),c},b}(j["default"]);j["default"].registerComponent("Popup",q),c["default"]=q},{5:5,81:81,82:82,83:83}],55:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(3),j=e(i),k=a(5),l=e(k),m=a(83),n=d(m),o=a(81),p=d(o),q=a(78),r=d(q),s=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.update(),c.on("posterchange",n.bind(e,e.update)),e}return h(b,a),b.prototype.dispose=function(){this.player().off("posterchange",this.update),a.prototype.dispose.call(this)},b.prototype.createEl=function(){var a=p.createEl("div",{ +className:"vjs-poster",tabIndex:-1});return r.BACKGROUND_SIZE_SUPPORTED||(this.fallbackImg_=p.createEl("img"),a.appendChild(this.fallbackImg_)),a},b.prototype.update=function(a){var b=this.player().poster();this.setSrc(b),b?this.show():this.hide()},b.prototype.setSrc=function(a){if(this.fallbackImg_)this.fallbackImg_.src=a;else{var b="";a&&(b='url("'+a+'")'),this.el_.style.backgroundImage=b}},b.prototype.handleClick=function(a){this.player_.paused()?this.player_.play():this.player_.pause()},b}(j["default"]);l["default"].registerComponent("PosterImage",s),c["default"]=s},{3:3,5:5,78:78,81:81,83:83}],56:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){b&&(p=b),n["default"].setTimeout(q,a)}c.__esModule=!0,c.hasLoaded=c.autoSetupTimeout=c.autoSetup=void 0;var g=a(81),h=e(g),i=a(82),j=e(i),k=a(94),l=d(k),m=a(95),n=d(m),o=!1,p=void 0,q=function(){if(h.isReal()){var a=l["default"].getElementsByTagName("video"),b=l["default"].getElementsByTagName("audio"),c=[];if(a&&a.length>0)for(var d=0,e=a.length;d<e;d++)c.push(a[d]);if(b&&b.length>0)for(var g=0,i=b.length;g<i;g++)c.push(b[g]);if(c&&c.length>0)for(var j=0,k=c.length;j<k;j++){var m=c[j];if(!m||!m.getAttribute){f(1);break}if(void 0===m.player){var n=m.getAttribute("data-setup");null!==n&&p(m)}}else o||f(1)}};h.isReal()&&"complete"===l["default"].readyState?o=!0:j.one(n["default"],"load",function(){o=!0});var r=function(){return o};c.autoSetup=q,c.autoSetupTimeout=f,c.hasLoaded=r},{81:81,82:82,94:94,95:95}],57:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(5),j=e(i),k=a(81),l=d(k),m=a(88),n=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.bar=e.getChild(e.options_.barName),e.vertical(!!e.options_.vertical),e.on("mousedown",e.handleMouseDown),e.on("touchstart",e.handleMouseDown),e.on("focus",e.handleFocus),e.on("blur",e.handleBlur),e.on("click",e.handleClick),e.on(c,"controlsvisible",e.update),e.on(c,e.playerEvent,e.update),e}return h(b,a),b.prototype.createEl=function(b){var c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},d=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return c.className=c.className+" vjs-slider",c=(0,m.assign)({tabIndex:0},c),d=(0,m.assign)({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},d),a.prototype.createEl.call(this,b,c,d)},b.prototype.handleMouseDown=function(a){var b=this.bar.el_.ownerDocument;a.preventDefault(),l.blockTextSelection(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(b,"mousemove",this.handleMouseMove),this.on(b,"mouseup",this.handleMouseUp),this.on(b,"touchmove",this.handleMouseMove),this.on(b,"touchend",this.handleMouseUp),this.handleMouseMove(a)},b.prototype.handleMouseMove=function(a){},b.prototype.handleMouseUp=function(){var a=this.bar.el_.ownerDocument;l.unblockTextSelection(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(a,"mousemove",this.handleMouseMove),this.off(a,"mouseup",this.handleMouseUp),this.off(a,"touchmove",this.handleMouseMove),this.off(a,"touchend",this.handleMouseUp),this.update()},b.prototype.update=function(){if(this.el_){var a=this.getPercent(),b=this.bar;if(b){("number"!=typeof a||a!==a||a<0||a===1/0)&&(a=0);var c=(100*a).toFixed(2)+"%";this.vertical()?b.el().style.height=c:b.el().style.width=c}}},b.prototype.calculateDistance=function(a){var b=l.getPointerPosition(this.el_,a);return this.vertical()?b.y:b.x},b.prototype.handleFocus=function(){this.on(this.bar.el_.ownerDocument,"keydown",this.handleKeyPress)},b.prototype.handleKeyPress=function(a){37===a.which||40===a.which?(a.preventDefault(),this.stepBack()):38!==a.which&&39!==a.which||(a.preventDefault(),this.stepForward())},b.prototype.handleBlur=function(){this.off(this.bar.el_.ownerDocument,"keydown",this.handleKeyPress)},b.prototype.handleClick=function(a){a.stopImmediatePropagation(),a.preventDefault()},b.prototype.vertical=function(a){return void 0===a?this.vertical_||!1:(this.vertical_=!!a,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal"),this)},b}(j["default"]);j["default"].registerComponent("Slider",n),c["default"]=n},{5:5,81:81,88:88}],58:[function(a,b,c){"use strict";function d(a){return a.streamingFormats={"rtmp/mp4":"MP4","rtmp/flv":"FLV"},a.streamFromParts=function(a,b){return a+"&"+b},a.streamToParts=function(a){var b={connection:"",stream:""};if(!a)return b;var c=a.search(/&(?!\w+=)/),d=void 0;return c!==-1?d=c+1:(c=d=a.lastIndexOf("/")+1,0===c&&(c=d=a.length)),b.connection=a.substring(0,c),b.stream=a.substring(d,a.length),b},a.isStreamingType=function(b){return b in a.streamingFormats},a.RTMP_RE=/^rtmp[set]?:\/\//i,a.isStreamingSrc=function(b){return a.RTMP_RE.test(b)},a.rtmpSourceHandler={},a.rtmpSourceHandler.canPlayType=function(b){return a.isStreamingType(b)?"maybe":""},a.rtmpSourceHandler.canHandleSource=function(b,c){var d=a.rtmpSourceHandler.canPlayType(b.type);return d?d:a.isStreamingSrc(b.src)?"maybe":""},a.rtmpSourceHandler.handleSource=function(b,c,d){var e=a.streamToParts(b.src);c.setRtmpConnection(e.connection),c.setRtmpStream(e.stream)},a.registerSourceHandler(a.rtmpSourceHandler),a}c.__esModule=!0,c["default"]=d},{}],59:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}function i(a){var b=a.charAt(0).toUpperCase()+a.slice(1);A["set"+b]=function(b){return this.el_.vjs_setProperty(a,b)}}function j(a){A[a]=function(){return this.el_.vjs_getProperty(a)}}c.__esModule=!0;for(var k=a(62),l=e(k),m=a(81),n=d(m),o=a(92),p=d(o),q=a(90),r=a(58),s=e(r),t=a(5),u=e(t),v=a(95),w=e(v),x=a(88),y=w["default"].navigator,z=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return c.source&&e.ready(function(){this.setSource(c.source)},!0),c.startTime&&e.ready(function(){this.load(),this.play(),this.currentTime(c.startTime)},!0),w["default"].videojs=w["default"].videojs||{},w["default"].videojs.Flash=w["default"].videojs.Flash||{},w["default"].videojs.Flash.onReady=b.onReady,w["default"].videojs.Flash.onEvent=b.onEvent,w["default"].videojs.Flash.onError=b.onError,e.on("seeked",function(){this.lastSeekTarget_=void 0}),e}return h(b,a),b.prototype.createEl=function(){var a=this.options_;if(!a.swf){var c="5.1.0";a.swf="//vjs.zencdn.net/swf/"+c+"/video-js.swf"}var d=a.techId,e=(0,x.assign)({readyFunction:"videojs.Flash.onReady",eventProxyFunction:"videojs.Flash.onEvent",errorEventProxyFunction:"videojs.Flash.onError",autoplay:a.autoplay,preload:a.preload,loop:a.loop,muted:a.muted},a.flashVars),f=(0,x.assign)({wmode:"opaque",bgcolor:"#000000"},a.params),g=(0,x.assign)({id:d,name:d,"class":"vjs-tech"},a.attributes);return this.el_=b.embed(a.swf,e,f,g),this.el_.tech=this,this.el_},b.prototype.play=function(){this.ended()&&this.setCurrentTime(0),this.el_.vjs_play()},b.prototype.pause=function(){this.el_.vjs_pause()},b.prototype.src=function(a){return void 0===a?this.currentSrc():this.setSrc(a)},b.prototype.setSrc=function(a){var b=this;a=p.getAbsoluteURL(a),this.el_.vjs_src(a),this.autoplay()&&this.setTimeout(function(){return b.play()},0)},b.prototype.seeking=function(){return void 0!==this.lastSeekTarget_},b.prototype.setCurrentTime=function(b){var c=this.seekable();c.length&&(b=b>c.start(0)?b:c.start(0),b=b<c.end(c.length-1)?b:c.end(c.length-1),this.lastSeekTarget_=b,this.trigger("seeking"),this.el_.vjs_setProperty("currentTime",b),a.prototype.setCurrentTime.call(this))},b.prototype.currentTime=function(){return this.seeking()?this.lastSeekTarget_||0:this.el_.vjs_getProperty("currentTime")},b.prototype.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.vjs_getProperty("currentSrc")},b.prototype.duration=function c(){if(0===this.readyState())return NaN;var c=this.el_.vjs_getProperty("duration");return c>=0?c:1/0},b.prototype.load=function(){this.el_.vjs_load()},b.prototype.poster=function(){this.el_.vjs_getProperty("poster")},b.prototype.setPoster=function(){},b.prototype.seekable=function(){var a=this.duration();return 0===a?(0,q.createTimeRange)():(0,q.createTimeRange)(0,a)},b.prototype.buffered=function(){var a=this.el_.vjs_getProperty("buffered");return 0===a.length?(0,q.createTimeRange)():(0,q.createTimeRange)(a[0][0],a[0][1])},b.prototype.supportsFullScreen=function(){return!1},b.prototype.enterFullScreen=function(){return!1},b}(l["default"]),A=z.prototype,B="rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),C="networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight".split(","),D=0;D<B.length;D++)j(B[D]),i(B[D]);for(var E=0;E<C.length;E++)j(C[E]);z.isSupported=function(){return z.version()[0]>=10},l["default"].withSourceHandlers(z),z.nativeSourceHandler={},z.nativeSourceHandler.canPlayType=function(a){return a in z.formats?"maybe":""},z.nativeSourceHandler.canHandleSource=function(a,b){function c(a){var b=p.getFileExtension(a);return b?"video/"+b:""}var d=void 0;return d=a.type?a.type.replace(/;.*/,"").toLowerCase():c(a.src),z.nativeSourceHandler.canPlayType(d)},z.nativeSourceHandler.handleSource=function(a,b,c){b.setSrc(a.src)},z.nativeSourceHandler.dispose=function(){},z.registerSourceHandler(z.nativeSourceHandler),z.formats={"video/flv":"FLV","video/x-flv":"FLV","video/mp4":"MP4","video/m4v":"MP4"},z.onReady=function(a){var b=n.getEl(a),c=b&&b.tech;c&&c.el()&&z.checkReady(c)},z.checkReady=function(a){a.el()&&(a.el().vjs_getProperty?a.triggerReady():this.setTimeout(function(){z.checkReady(a)},50))},z.onEvent=function(a,b){var c=n.getEl(a).tech,d=Array.prototype.slice.call(arguments,2);c.setTimeout(function(){c.trigger(b,d)},1)},z.onError=function(a,b){var c=n.getEl(a).tech;return"srcnotfound"===b?c.error(4):void c.error("FLASH: "+b)},z.version=function(){var a="0,0,0";try{a=new w["default"].ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}catch(b){try{y.mimeTypes["application/x-shockwave-flash"].enabledPlugin&&(a=(y.plugins["Shockwave Flash 2.0"]||y.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1])}catch(c){}}return a.split(",")},z.embed=function(a,b,c,d){var e=z.getEmbedCode(a,b,c,d),f=n.createEl("div",{innerHTML:e}).childNodes[0];return f},z.getEmbedCode=function(a,b,c,d){var e='<object type="application/x-shockwave-flash" ',f="",g="",h="";return b&&Object.getOwnPropertyNames(b).forEach(function(a){f+=a+"="+b[a]+"&"}),c=(0,x.assign)({movie:a,flashvars:f,allowScriptAccess:"always",allowNetworking:"all"},c),Object.getOwnPropertyNames(c).forEach(function(a){g+='<param name="'+a+'" value="'+c[a]+'" />'}),d=(0,x.assign)({data:a,width:"100%",height:"100%"},d),Object.getOwnPropertyNames(d).forEach(function(a){h+=a+'="'+d[a]+'" '}),""+e+h+">"+g+"</object>"},(0,s["default"])(z),u["default"].registerComponent("Flash",z),l["default"].registerTech("Flash",z),c["default"]=z},{5:5,58:58,62:62,81:81,88:88,90:90,92:92,95:95}],60:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){return a.raw=b,a}function g(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function h(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function i(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},k=f(["Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\n This may prevent text tracks from loading."],["Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\n This may prevent text tracks from loading."]),l=a(62),m=e(l),n=a(5),o=e(n),p=a(81),q=d(p),r=a(92),s=d(r),t=a(83),u=d(t),v=a(86),w=e(v),x=a(98),y=e(x),z=a(78),A=d(z),B=a(94),C=e(B),D=a(95),E=e(D),F=a(88),G=a(87),H=e(G),I=a(91),J=e(I),K=function(a){function b(c,d){g(this,b);var e=h(this,a.call(this,c,d)),f=c.source,i=!1;if(f&&(e.el_.currentSrc!==f.src||c.tag&&3===c.tag.initNetworkState_)?e.setSource(f):e.handleLateInit_(e.el_),e.el_.hasChildNodes()){for(var j=e.el_.childNodes,l=j.length,m=[];l--;){var n=j[l],o=n.nodeName.toLowerCase();"track"===o&&(e.featuresNativeTextTracks?(e.remoteTextTrackEls().addTrackElement_(n),e.remoteTextTracks().addTrack_(n.track),i||e.el_.hasAttribute("crossorigin")||!s.isCrossOrigin(n.src)||(i=!0)):m.push(n))}for(var p=0;p<m.length;p++)e.el_.removeChild(m[p])}var q=["audio","video"];return q.forEach(function(a){var b=e.el()[a+"Tracks"],c=e[a+"Tracks"](),d=(0,J["default"])(a);e["featuresNative"+d+"Tracks"]&&b&&b.addEventListener&&(e["handle"+d+"TrackChange_"]=function(a){c.trigger({type:"change",target:c,currentTarget:c,srcElement:c})},e["handle"+d+"TrackAdd_"]=function(a){return c.addTrack(a.track)},e["handle"+d+"TrackRemove_"]=function(a){return c.removeTrack(a.track)},b.addEventListener("change",e["handle"+d+"TrackChange_"]),b.addEventListener("addtrack",e["handle"+d+"TrackAdd_"]),b.addEventListener("removetrack",e["handle"+d+"TrackRemove_"]),e["removeOld"+d+"Tracks_"]=function(a){return e.removeOldTracks_(c,b)},e.on("loadstart",e["removeOld"+d+"Tracks_"]))}),e.featuresNativeTextTracks&&(i&&w["default"].warn((0,y["default"])(k)),e.handleTextTrackChange_=u.bind(e,e.handleTextTrackChange),e.handleTextTrackAdd_=u.bind(e,e.handleTextTrackAdd),e.handleTextTrackRemove_=u.bind(e,e.handleTextTrackRemove),e.proxyNativeTextTracks_()),(A.TOUCH_ENABLED||A.IS_IPHONE||A.IS_NATIVE_ANDROID)&&c.nativeControlsForTouch===!0&&e.setControls(!0),e.proxyWebkitFullscreen_(),e.triggerReady(),e}return i(b,a),b.prototype.dispose=function(){var c=this;["audio","video","text"].forEach(function(a){var b=(0,J["default"])(a),d=c.el_[a+"Tracks"];d&&d.removeEventListener&&(d.removeEventListener("change",c["handle"+b+"TrackChange_"]),d.removeEventListener("addtrack",c["handle"+b+"TrackAdd_"]),d.removeEventListener("removetrack",c["handle"+b+"TrackRemove_"])),d&&c.off("loadstart",c["removeOld"+b+"Tracks_"])}),b.disposeMediaElement(this.el_),a.prototype.dispose.call(this)},b.prototype.createEl=function(){var a=this.options_.tag;if(!a||!this.options_.playerElIngest&&!this.movingMediaElementInDOM){if(a){var c=a.cloneNode(!0);a.parentNode&&a.parentNode.insertBefore(c,a),b.disposeMediaElement(a),a=c}else{a=C["default"].createElement("video");var d=this.options_.tag&&q.getElAttributes(this.options_.tag),e=(0,H["default"])({},d);A.TOUCH_ENABLED&&this.options_.nativeControlsForTouch===!0||delete e.controls,q.setElAttributes(a,(0,F.assign)(e,{id:this.options_.techId,"class":"vjs-tech"}))}a.playerId=this.options_.playerId}for(var f=["autoplay","preload","loop","muted"],g=f.length-1;g>=0;g--){var h=f[g],i={};"undefined"!=typeof this.options_[h]&&(i[h]=this.options_[h]),q.setElAttributes(a,i)}return a},b.prototype.handleLateInit_=function(a){var b=this;if(0!==a.networkState&&3!==a.networkState){if(0===a.readyState){var c=function(){var a=!1,c=function(){a=!0};b.on("loadstart",c);var d=function(){a||this.trigger("loadstart")};return b.on("loadedmetadata",d),b.ready(function(){this.off("loadstart",c),this.off("loadedmetadata",d),a||this.trigger("loadstart")}),{v:void 0}}();if("object"===("undefined"==typeof c?"undefined":j(c)))return c.v}var d=["loadstart"];d.push("loadedmetadata"),a.readyState>=2&&d.push("loadeddata"),a.readyState>=3&&d.push("canplay"),a.readyState>=4&&d.push("canplaythrough"),this.ready(function(){d.forEach(function(a){this.trigger(a)},this)})}},b.prototype.proxyNativeTextTracks_=function(){var a=this.el().textTracks;if(a){for(var b=0;b<a.length;b++)this.textTracks().addTrack_(a[b]);a.addEventListener&&(a.addEventListener("change",this.handleTextTrackChange_),a.addEventListener("addtrack",this.handleTextTrackAdd_),a.addEventListener("removetrack",this.handleTextTrackRemove_)),this.on("loadstart",this.removeOldTextTracks_)}},b.prototype.handleTextTrackChange=function(a){var b=this.textTracks();this.textTracks().trigger({type:"change",target:b,currentTarget:b,srcElement:b})},b.prototype.handleTextTrackAdd=function(a){this.textTracks().addTrack_(a.track)},b.prototype.handleTextTrackRemove=function(a){this.textTracks().removeTrack_(a.track)},b.prototype.removeOldTracks_=function(a,b){var c=[];if(b){for(var d=0;d<a.length;d++){for(var e=a[d],f=!1,g=0;g<b.length;g++)if(b[g]===e){f=!0;break}f||c.push(e)}for(var h=0;h<c.length;h++){var i=c[h];a.removeTrack_(i)}}},b.prototype.removeOldTextTracks_=function(a){var b=this.textTracks(),c=this.el().textTracks;this.removeOldTracks_(b,c)},b.prototype.play=function(){var a=this.el_.play();void 0!==a&&"function"==typeof a.then&&a.then(null,function(a){})},b.prototype.setCurrentTime=function(a){try{this.el_.currentTime=a}catch(b){(0,w["default"])(b,"Video is not ready. (Video.js)")}},b.prototype.duration=function(){var a=this;if(this.el_.duration===1/0&&A.IS_ANDROID&&A.IS_CHROME&&0===this.el_.currentTime){var b=function(){var b=function c(){a.el_.currentTime>0&&(a.el_.duration===1/0&&a.trigger("durationchange"),a.off("timeupdate",c))};return a.on("timeupdate",b),{v:NaN}}();if("object"===("undefined"==typeof b?"undefined":j(b)))return b.v}return this.el_.duration||NaN},b.prototype.width=function(){return this.el_.offsetWidth},b.prototype.height=function(){return this.el_.offsetHeight},b.prototype.proxyWebkitFullscreen_=function(){var a=this;if("webkitDisplayingFullscreen"in this.el_){var b=function(){this.trigger("fullscreenchange",{isFullscreen:!1})},c=function(){this.one("webkitendfullscreen",b),this.trigger("fullscreenchange",{isFullscreen:!0})};this.on("webkitbeginfullscreen",c),this.on("dispose",function(){a.off("webkitbeginfullscreen",c),a.off("webkitendfullscreen",b)})}},b.prototype.supportsFullScreen=function(){if("function"==typeof this.el_.webkitEnterFullScreen){var a=E["default"].navigator&&E["default"].navigator.userAgent||"";if(/Android/.test(a)||!/Chrome|Mac OS X 10.5/.test(a))return!0}return!1},b.prototype.enterFullScreen=function(){var a=this.el_;a.paused&&a.networkState<=a.HAVE_METADATA?(this.el_.play(),this.setTimeout(function(){a.pause(),a.webkitEnterFullScreen()},0)):a.webkitEnterFullScreen()},b.prototype.exitFullScreen=function(){this.el_.webkitExitFullScreen()},b.prototype.src=function(a){return void 0===a?this.el_.src:void this.setSrc(a)},b.prototype.reset=function(){b.resetMediaElement(this.el_)},b.prototype.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc},b.prototype.setControls=function(a){this.el_.controls=!!a},b.prototype.addTextTrack=function(b,c,d){return this.featuresNativeTextTracks?this.el_.addTextTrack(b,c,d):a.prototype.addTextTrack.call(this,b,c,d)},b.prototype.createRemoteTextTrack=function(b){if(!this.featuresNativeTextTracks)return a.prototype.createRemoteTextTrack.call(this,b);var c=C["default"].createElement("track");return b.kind&&(c.kind=b.kind),b.label&&(c.label=b.label),(b.language||b.srclang)&&(c.srclang=b.language||b.srclang),b["default"]&&(c["default"]=b["default"]),b.id&&(c.id=b.id),b.src&&(c.src=b.src),c},b.prototype.addRemoteTextTrack=function(b,c){var d=a.prototype.addRemoteTextTrack.call(this,b,c);return this.featuresNativeTextTracks&&this.el().appendChild(d),d},b.prototype.removeRemoteTextTrack=function(b){if(a.prototype.removeRemoteTextTrack.call(this,b),this.featuresNativeTextTracks)for(var c=this.$$("track"),d=c.length;d--;)b!==c[d]&&b!==c[d].track||this.el().removeChild(c[d])},b}(m["default"]);if(q.isReal()){K.TEST_VID=C["default"].createElement("video");var L=C["default"].createElement("track");L.kind="captions",L.srclang="en",L.label="English",K.TEST_VID.appendChild(L)}K.isSupported=function(){try{K.TEST_VID.volume=.5}catch(a){return!1}return!(!K.TEST_VID||!K.TEST_VID.canPlayType)},K.canControlVolume=function(){try{var a=K.TEST_VID.volume;return K.TEST_VID.volume=a/2+.1,a!==K.TEST_VID.volume}catch(b){return!1}},K.canControlPlaybackRate=function(){if(A.IS_ANDROID&&A.IS_CHROME)return!1;try{var a=K.TEST_VID.playbackRate;return K.TEST_VID.playbackRate=a/2+.1,a!==K.TEST_VID.playbackRate}catch(b){return!1}},K.supportsNativeTextTracks=function(){return A.IS_ANY_SAFARI},K.supportsNativeVideoTracks=function(){return!(!K.TEST_VID||!K.TEST_VID.videoTracks)},K.supportsNativeAudioTracks=function(){return!(!K.TEST_VID||!K.TEST_VID.audioTracks)},K.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","volumechange"],K.prototype.featuresVolumeControl=K.canControlVolume(),K.prototype.featuresPlaybackRate=K.canControlPlaybackRate(),K.prototype.movingMediaElementInDOM=!A.IS_IOS,K.prototype.featuresFullscreenResize=!0,K.prototype.featuresProgressEvents=!0,K.prototype.featuresTimeupdateEvents=!0,K.prototype.featuresNativeTextTracks=K.supportsNativeTextTracks(),K.prototype.featuresNativeVideoTracks=K.supportsNativeVideoTracks(),K.prototype.featuresNativeAudioTracks=K.supportsNativeAudioTracks();var M=K.TEST_VID&&K.TEST_VID.constructor.prototype.canPlayType,N=/^application\/(?:x-|vnd\.apple\.)mpegurl/i,O=/^video\/mp4/i;K.patchCanPlayType=function(){A.ANDROID_VERSION>=4&&!A.IS_FIREFOX?K.TEST_VID.constructor.prototype.canPlayType=function(a){return a&&N.test(a)?"maybe":M.call(this,a)}:A.IS_OLD_ANDROID&&(K.TEST_VID.constructor.prototype.canPlayType=function(a){return a&&O.test(a)?"maybe":M.call(this,a)})},K.unpatchCanPlayType=function(){var a=K.TEST_VID.constructor.prototype.canPlayType;return K.TEST_VID.constructor.prototype.canPlayType=M,a},K.patchCanPlayType(),K.disposeMediaElement=function(a){if(a){for(a.parentNode&&a.parentNode.removeChild(a);a.hasChildNodes();)a.removeChild(a.firstChild);a.removeAttribute("src"),"function"==typeof a.load&&!function(){try{a.load()}catch(b){}}()}},K.resetMediaElement=function(a){if(a){for(var b=a.querySelectorAll("source"),c=b.length;c--;)a.removeChild(b[c]);a.removeAttribute("src"),"function"==typeof a.load&&!function(){try{a.load()}catch(b){}}()}},["paused","currentTime","buffered","volume","muted","poster","preload","autoplay","controls","loop","error","seeking","seekable","ended","defaultMuted","playbackRate","played","networkState","readyState","videoWidth","videoHeight"].forEach(function(a){K.prototype[a]=function(){return this.el_[a]}}),["volume","muted","src","poster","preload","autoplay","loop","playbackRate"].forEach(function(a){K.prototype["set"+(0,J["default"])(a)]=function(b){this.el_[a]=b}}),["pause","load"].forEach(function(a){K.prototype[a]=function(){return this.el_[a]()}}),m["default"].withSourceHandlers(K),K.nativeSourceHandler={},K.nativeSourceHandler.canPlayType=function(a){try{return K.TEST_VID.canPlayType(a)}catch(b){return""}},K.nativeSourceHandler.canHandleSource=function(a,b){if(a.type)return K.nativeSourceHandler.canPlayType(a.type);if(a.src){var c=s.getFileExtension(a.src);return K.nativeSourceHandler.canPlayType("video/"+c)}return""},K.nativeSourceHandler.handleSource=function(a,b,c){b.setSrc(a.src)},K.nativeSourceHandler.dispose=function(){},K.registerSourceHandler(K.nativeSourceHandler),o["default"].registerComponent("Html5",K),m["default"].registerTech("Html5",K),c["default"]=K},{5:5,62:62,78:78,81:81,83:83,86:86,87:87,88:88,91:91,92:92,94:94,95:95,98:98}],61:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function f(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function g(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var h=a(5),i=d(h),j=a(62),k=d(j),l=a(91),m=d(l),n=function(a){function b(c,d,g){e(this,b);var h=f(this,a.call(this,c,d,g));if(d.playerOptions.sources&&0!==d.playerOptions.sources.length)c.src(d.playerOptions.sources);else for(var j=0,l=d.playerOptions.techOrder;j<l.length;j++){var n=(0,m["default"])(l[j]),o=k["default"].getTech(n);if(n||(o=i["default"].getComponent(n)),o&&o.isSupported()){c.loadTech_(n);break}}return h}return g(b,a),b}(i["default"]);i["default"].registerComponent("MediaLoader",n),c["default"]=n},{5:5,62:62,91:91}],62:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}function i(a,b,c,d){var e=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{},f=a.textTracks();e.kind=b,c&&(e.label=c),d&&(e.language=d),e.tech=a;var g=new s["default"](e);return f.addTrack_(g),g}c.__esModule=!0;var j=a(5),k=e(j),l=a(66),m=e(l),n=a(65),o=e(n),p=a(87),q=e(p),r=a(72),s=e(r),t=a(70),u=e(t),v=a(76),w=e(v),x=a(63),y=e(x),z=a(83),A=d(z),B=a(86),C=e(B),D=a(90),E=a(79),F=a(46),G=e(F),H=a(95),I=e(H),J=a(94),K=e(J),L=function(a){function b(){var c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};f(this,b),c.reportTouchActivity=!1;var e=g(this,a.call(this,null,c,d));return e.hasStarted_=!1,e.on("playing",function(){this.hasStarted_=!0}),e.on("loadstart",function(){this.hasStarted_=!1}),e.textTracks_=c.textTracks,e.videoTracks_=c.videoTracks,e.audioTracks_=c.audioTracks,e.featuresProgressEvents||e.manualProgressOn(),e.featuresTimeupdateEvents||e.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach(function(a){c["native"+a+"Tracks"]===!1&&(e["featuresNative"+a+"Tracks"]=!1)}),c.nativeCaptions===!1&&(e.featuresNativeTextTracks=!1),e.featuresNativeTextTracks||e.emulateTextTracks(),e.autoRemoteTextTracks_=new u["default"],e.initTextTrackListeners(),e.initTrackListeners(),c.nativeControlsForTouch||e.emitTapEvents(),e}return h(b,a),b.prototype.manualProgressOn=function(){this.on("durationchange",this.onDurationChange),this.manualProgress=!0,this.one("ready",this.trackProgress)},b.prototype.manualProgressOff=function(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange)},b.prototype.trackProgress=function(a){this.stopTrackingProgress(),this.progressInterval=this.setInterval(A.bind(this,function(){var a=this.bufferedPercent();this.bufferedPercent_!==a&&this.trigger("progress"),this.bufferedPercent_=a,1===a&&this.stopTrackingProgress()}),500)},b.prototype.onDurationChange=function(a){this.duration_=this.duration()},b.prototype.buffered=function(){return(0,D.createTimeRange)(0,0)},b.prototype.bufferedPercent=function(){return(0,E.bufferedPercent)(this.buffered(),this.duration_)},b.prototype.stopTrackingProgress=function(){this.clearInterval(this.progressInterval)},b.prototype.manualTimeUpdatesOn=function(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime),this.on("pause",this.stopTrackingCurrentTime)},b.prototype.manualTimeUpdatesOff=function(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime),this.off("pause",this.stopTrackingCurrentTime)},b.prototype.trackCurrentTime=function(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval(function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},250)},b.prototype.stopTrackingCurrentTime=function(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},b.prototype.dispose=function(){this.clearTracks(["audio","video","text"]),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),a.prototype.dispose.call(this)},b.prototype.clearTracks=function(a){var b=this;a=[].concat(a),a.forEach(function(a){for(var c=b[a+"Tracks"]()||[],d=c.length;d--;){var e=c[d];"text"===a&&b.removeRemoteTextTrack(e),c.removeTrack_(e)}})},b.prototype.cleanupAutoTextTracks=function(){for(var a=this.autoRemoteTextTracks_||[],b=a.length;b--;){var c=a[b];this.removeRemoteTextTrack(c)}},b.prototype.reset=function(){},b.prototype.error=function(a){return void 0!==a&&(this.error_=new G["default"](a),this.trigger("error")),this.error_},b.prototype.played=function(){return this.hasStarted_?(0,D.createTimeRange)(0,0):(0,D.createTimeRange)()},b.prototype.setCurrentTime=function(){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},b.prototype.initTextTrackListeners=function(){var a=A.bind(this,function(){this.trigger("texttrackchange")}),b=this.textTracks();b&&(b.addEventListener("removetrack",a),b.addEventListener("addtrack",a),this.on("dispose",A.bind(this,function(){b.removeEventListener("removetrack",a),b.removeEventListener("addtrack",a)})))},b.prototype.initTrackListeners=function(){var a=this,b=["video","audio"];b.forEach(function(b){ +var c=function(){a.trigger(b+"trackchange")},d=a[b+"Tracks"]();d.addEventListener("removetrack",c),d.addEventListener("addtrack",c),a.on("dispose",function(){d.removeEventListener("removetrack",c),d.removeEventListener("addtrack",c)})})},b.prototype.addWebVttScript_=function(){var a=this;I["default"].WebVTT||null===this.el().parentNode||void 0===this.el().parentNode||!function(){var b=K["default"].createElement("script");b.src=a.options_["vtt.js"]||"https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js",b.onload=function(){a.trigger("vttjsloaded")},b.onerror=function(){a.trigger("vttjserror")},a.on("dispose",function(){b.onload=null,b.onerror=null}),I["default"].WebVTT=!0,a.el().parentNode.appendChild(b)}()},b.prototype.emulateTextTracks=function(){var a=this,b=this.textTracks();if(b){this.remoteTextTracks().on("addtrack",function(b){a.textTracks().addTrack_(b.track)}),this.remoteTextTracks().on("removetrack",function(b){a.textTracks().removeTrack_(b.track)}),this.on("ready",this.addWebVttScript_);var c=function(){return a.trigger("texttrackchange")},d=function(){c();for(var a=0;a<b.length;a++){var d=b[a];d.removeEventListener("cuechange",c),"showing"===d.mode&&d.addEventListener("cuechange",c)}};d(),b.addEventListener("change",d),this.on("dispose",function(){b.removeEventListener("change",d)})}},b.prototype.videoTracks=function(){return this.videoTracks_=this.videoTracks_||new w["default"],this.videoTracks_},b.prototype.audioTracks=function(){return this.audioTracks_=this.audioTracks_||new y["default"],this.audioTracks_},b.prototype.textTracks=function(){return this.textTracks_=this.textTracks_||new u["default"],this.textTracks_},b.prototype.remoteTextTracks=function(){return this.remoteTextTracks_=this.remoteTextTracks_||new u["default"],this.remoteTextTracks_},b.prototype.remoteTextTrackEls=function(){return this.remoteTextTrackEls_=this.remoteTextTrackEls_||new o["default"],this.remoteTextTrackEls_},b.prototype.addTextTrack=function(a,b,c){if(!a)throw new Error("TextTrack kind is required but was not provided");return i(this,a,b,c)},b.prototype.createRemoteTextTrack=function(a){var b=(0,q["default"])(a,{tech:this});return new m["default"](b)},b.prototype.addRemoteTextTrack=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},b=arguments[1],c=this.createRemoteTextTrack(a);return b!==!0&&b!==!1&&(C["default"].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'),b=!0),this.remoteTextTrackEls().addTrackElement_(c),this.remoteTextTracks().addTrack_(c.track),b!==!0&&this.autoRemoteTextTracks_.addTrack_(c.track),c},b.prototype.removeRemoteTextTrack=function(a){var b=this.remoteTextTrackEls().getTrackElementByTrack_(a);this.remoteTextTrackEls().removeTrackElement_(b),this.remoteTextTracks().removeTrack_(a),this.autoRemoteTextTracks_.removeTrack_(a)},b.prototype.setPoster=function(){},b.prototype.canPlayType=function(){return""},b.isTech=function(a){return a.prototype instanceof b||a instanceof b||a===b},b.registerTech=function(a,c){if(b.techs_||(b.techs_={}),!b.isTech(c))throw new Error("Tech "+a+" must be a Tech");return b.techs_[a]=c,c},b.getTech=function(a){return b.techs_&&b.techs_[a]?b.techs_[a]:I["default"]&&I["default"].videojs&&I["default"].videojs[a]?(C["default"].warn("The "+a+" tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)"),I["default"].videojs[a]):void 0},b}(k["default"]);L.prototype.textTracks_,L.prototype.audioTracks_,L.prototype.videoTracks_,L.prototype.featuresVolumeControl=!0,L.prototype.featuresFullscreenResize=!1,L.prototype.featuresPlaybackRate=!1,L.prototype.featuresProgressEvents=!1,L.prototype.featuresTimeupdateEvents=!1,L.prototype.featuresNativeTextTracks=!1,L.withSourceHandlers=function(a){a.registerSourceHandler=function(b,c){var d=a.sourceHandlers;d||(d=a.sourceHandlers=[]),void 0===c&&(c=d.length),d.splice(c,0,b)},a.canPlayType=function(b){for(var c=a.sourceHandlers||[],d=void 0,e=0;e<c.length;e++)if(d=c[e].canPlayType(b))return d;return""},a.selectSourceHandler=function(b,c){for(var d=a.sourceHandlers||[],e=void 0,f=0;f<d.length;f++)if(e=d[f].canHandleSource(b,c))return d[f];return null},a.canPlaySource=function(b,c){var d=a.selectSourceHandler(b,c);return d?d.canHandleSource(b,c):""};var b=["seekable","duration"];b.forEach(function(a){var b=this[a];"function"==typeof b&&(this[a]=function(){return this.sourceHandler_&&this.sourceHandler_[a]?this.sourceHandler_[a].apply(this.sourceHandler_,arguments):b.apply(this,arguments)})},a.prototype),a.prototype.setSource=function(b){var c=a.selectSourceHandler(b,this.options_);return c||(a.nativeSourceHandler?c=a.nativeSourceHandler:C["default"].error("No source hander found for the current source.")),this.disposeSourceHandler(),this.off("dispose",this.disposeSourceHandler),c!==a.nativeSourceHandler&&(this.currentSource_=b,this.off(this.el_,"loadstart",a.prototype.firstLoadStartListener_),this.off(this.el_,"loadstart",a.prototype.successiveLoadStartListener_),this.one(this.el_,"loadstart",a.prototype.firstLoadStartListener_)),this.sourceHandler_=c.handleSource(b,this,this.options_),this.on("dispose",this.disposeSourceHandler),this},a.prototype.firstLoadStartListener_=function(){this.one(this.el_,"loadstart",a.prototype.successiveLoadStartListener_)},a.prototype.successiveLoadStartListener_=function(){this.disposeSourceHandler(),this.one(this.el_,"loadstart",a.prototype.successiveLoadStartListener_)},a.prototype.disposeSourceHandler=function(){this.currentSource_&&(this.clearTracks(["audio","video"]),this.currentSource_=null),this.cleanupAutoTextTracks(),this.sourceHandler_&&(this.off(this.el_,"loadstart",a.prototype.firstLoadStartListener_),this.off(this.el_,"loadstart",a.prototype.successiveLoadStartListener_),this.sourceHandler_.dispose&&this.sourceHandler_.dispose(),this.sourceHandler_=null)}},k["default"].registerComponent("Tech",L),k["default"].registerComponent("MediaTechController",L),L.registerTech("Tech",L),c["default"]=L},{46:46,5:5,63:63,65:65,66:66,70:70,72:72,76:76,79:79,83:83,86:86,87:87,90:90,94:94,95:95}],63:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(74),j=e(i),k=a(78),l=d(k),m=a(94),n=e(m),o=function(a,b){for(var c=0;c<a.length;c++)b.id!==a[c].id&&(a[c].enabled=!1)},p=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];f(this,b);for(var h=void 0,i=e.length-1;i>=0;i--)if(e[i].enabled){o(e,e[i]);break}if(l.IS_IE8){h=n["default"].createElement("custom");for(var k in j["default"].prototype)"constructor"!==k&&(h[k]=j["default"].prototype[k]);for(var m in b.prototype)"constructor"!==m&&(h[m]=b.prototype[m])}return h=c=g(this,a.call(this,e,h)),h.changing_=!1,d=h,g(c,d)}return h(b,a),b.prototype.addTrack_=function(b){var c=this;b.enabled&&o(this,b),a.prototype.addTrack_.call(this,b),b.addEventListener&&b.addEventListener("enabledchange",function(){c.changing_||(c.changing_=!0,o(c,b),c.changing_=!1,c.trigger("change"))})},b.prototype.addTrack=function(a){this.addTrack_(a)},b.prototype.removeTrack=function(b){a.prototype.removeTrack_.call(this,b)},b}(j["default"]);c["default"]=p},{74:74,78:78,94:94}],64:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(73),j=a(75),k=e(j),l=a(87),m=e(l),n=a(78),o=d(n),p=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};f(this,b);var h=(0,m["default"])(e,{kind:i.AudioTrackKind[e.kind]||""}),j=c=g(this,a.call(this,h)),k=!1;if(o.IS_IE8)for(var l in b.prototype)"constructor"!==l&&(j[l]=b.prototype[l]);return Object.defineProperty(j,"enabled",{get:function(){return k},set:function(a){"boolean"==typeof a&&a!==k&&(k=a,this.trigger("enabledchange"))}}),h.enabled&&(j.enabled=h.enabled),j.loaded_=!0,d=j,g(c,d)}return h(b,a),b}(k["default"]);c["default"]=p},{73:73,75:75,78:78,87:87}],65:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var g=a(78),h=e(g),i=a(94),j=d(i),k=function(){function a(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];f(this,a);var c=this;if(h.IS_IE8){c=j["default"].createElement("custom");for(var d in a.prototype)"constructor"!==d&&(c[d]=a.prototype[d])}c.trackElements_=[],Object.defineProperty(c,"length",{get:function(){return this.trackElements_.length}});for(var e=0,g=b.length;e<g;e++)c.addTrackElement_(b[e]);if(h.IS_IE8)return c}return a.prototype.addTrackElement_=function(a){var b=this.trackElements_.length;""+b in this||Object.defineProperty(this,b,{get:function(){return this.trackElements_[b]}}),this.trackElements_.indexOf(a)===-1&&this.trackElements_.push(a)},a.prototype.getTrackElementByTrack_=function(a){for(var b=void 0,c=0,d=this.trackElements_.length;c<d;c++)if(a===this.trackElements_[c].track){b=this.trackElements_[c];break}return b},a.prototype.removeTrackElement_=function(a){for(var b=0,c=this.trackElements_.length;b<c;b++)if(a===this.trackElements_[b]){this.trackElements_.splice(b,1);break}},a}();c["default"]=k},{78:78,94:94}],66:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(78),j=e(i),k=a(94),l=d(k),m=a(42),n=d(m),o=a(72),p=d(o),q=0,r=1,s=2,t=3,u=function(a){function b(){var c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};f(this,b);var d=g(this,a.call(this)),e=void 0,h=d;if(j.IS_IE8){h=l["default"].createElement("custom");for(var i in b.prototype)"constructor"!==i&&(h[i]=b.prototype[i])}var k=new p["default"](c);if(h.kind=k.kind,h.src=k.src,h.srclang=k.language,h.label=k.label,h["default"]=k["default"],Object.defineProperty(h,"readyState",{get:function(){return e}}),Object.defineProperty(h,"track",{get:function(){return k}}),e=q,k.addEventListener("loadeddata",function(){e=s,h.trigger({type:"load",target:h})}),j.IS_IE8){var m;return m=h,g(d,m)}return d}return h(b,a),b}(n["default"]);u.prototype.allowedEvents_={load:"load"},u.NONE=q,u.LOADING=r,u.LOADED=s,u.ERROR=t,c["default"]=u},{42:42,72:72,78:78,94:94}],67:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var g=a(78),h=e(g),i=a(94),j=d(i),k=function(){function a(b){f(this,a);var c=this;if(h.IS_IE8){c=j["default"].createElement("custom");for(var d in a.prototype)"constructor"!==d&&(c[d]=a.prototype[d])}if(a.prototype.setCues_.call(c,b),Object.defineProperty(c,"length",{get:function(){return this.length_}}),h.IS_IE8)return c}return a.prototype.setCues_=function(a){var b=this.length||0,c=0,d=a.length;this.cues_=a,this.length_=a.length;var e=function(a){""+a in this||Object.defineProperty(this,""+a,{get:function(){return this.cues_[a]}})};if(b<d)for(c=b;c<d;c++)e.call(this,c)},a.prototype.getCueById=function(a){for(var b=null,c=0,d=this.length;c<d;c++){var e=this[c];if(e.id===a){b=e;break}}return b},a}();c["default"]=k},{78:78,94:94}],68:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}function i(a,b){return"rgba("+parseInt(a[1]+a[1],16)+","+parseInt(a[2]+a[2],16)+","+parseInt(a[3]+a[3],16)+","+b+")"}function j(a,b,c){try{a.style[b]=c}catch(d){return}}c.__esModule=!0;var k=a(5),l=e(k),m=a(83),n=d(m),o=a(95),p=e(o),q="#222",r="#ccc",s={monospace:"monospace",sansSerif:"sans-serif",serif:"serif",monospaceSansSerif:'"Andale Mono", "Lucida Console", monospace',monospaceSerif:'"Courier New", monospace',proportionalSansSerif:"sans-serif",proportionalSerif:"serif",casual:'"Comic Sans MS", Impact, fantasy',script:'"Monotype Corsiva", cursive',smallcaps:'"Andale Mono", "Lucida Console", monospace, sans-serif'},t=function(a){function b(c,d,e){f(this,b);var h=g(this,a.call(this,c,d,e));return c.on("loadstart",n.bind(h,h.toggleDisplay)),c.on("texttrackchange",n.bind(h,h.updateDisplay)),c.ready(n.bind(h,function(){if(c.tech_&&c.tech_.featuresNativeTextTracks)return void this.hide();c.on("fullscreenchange",n.bind(this,this.updateDisplay));for(var a=this.options_.playerOptions.tracks||[],b=0;b<a.length;b++)this.player_.addRemoteTextTrack(a[b],!0);var d={captions:1,subtitles:1},e=this.player_.textTracks(),f=void 0,g=void 0;if(e){for(var h=0;h<e.length;h++){var i=e[h];i["default"]&&("descriptions"!==i.kind||f?i.kind in d&&!g&&(g=i):f=i)}g?g.mode="showing":f&&(f.mode="showing")}})),h}return h(b,a),b.prototype.toggleDisplay=function(){this.player_.tech_&&this.player_.tech_.featuresNativeTextTracks?this.hide():this.show()},b.prototype.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-text-track-display"},{"aria-live":"off","aria-atomic":"true"})},b.prototype.clearDisplay=function(){"function"==typeof p["default"].WebVTT&&p["default"].WebVTT.processCues(p["default"],[],this.el_)},b.prototype.updateDisplay=function(){var a=this.player_.textTracks();if(this.clearDisplay(),a){for(var b=null,c=null,d=a.length;d--;){var e=a[d];"showing"===e.mode&&("descriptions"===e.kind?b=e:c=e)}c?("off"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","off"),this.updateForTrack(c)):b&&("assertive"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","assertive"),this.updateForTrack(b))}},b.prototype.updateForTrack=function(a){if("function"==typeof p["default"].WebVTT&&a.activeCues){for(var b=this.player_.textTrackSettings.getValues(),c=[],d=0;d<a.activeCues.length;d++)c.push(a.activeCues[d]);p["default"].WebVTT.processCues(p["default"],c,this.el_);for(var e=c.length;e--;){var f=c[e];if(f){var g=f.displayState;if(b.color&&(g.firstChild.style.color=b.color),b.textOpacity&&j(g.firstChild,"color",i(b.color||"#fff",b.textOpacity)),b.backgroundColor&&(g.firstChild.style.backgroundColor=b.backgroundColor),b.backgroundOpacity&&j(g.firstChild,"backgroundColor",i(b.backgroundColor||"#000",b.backgroundOpacity)),b.windowColor&&(b.windowOpacity?j(g,"backgroundColor",i(b.windowColor,b.windowOpacity)):g.style.backgroundColor=b.windowColor),b.edgeStyle&&("dropshadow"===b.edgeStyle?g.firstChild.style.textShadow="2px 2px 3px "+q+", 2px 2px 4px "+q+", 2px 2px 5px "+q:"raised"===b.edgeStyle?g.firstChild.style.textShadow="1px 1px "+q+", 2px 2px "+q+", 3px 3px "+q:"depressed"===b.edgeStyle?g.firstChild.style.textShadow="1px 1px "+r+", 0 1px "+r+", -1px -1px "+q+", 0 -1px "+q:"uniform"===b.edgeStyle&&(g.firstChild.style.textShadow="0 0 4px "+q+", 0 0 4px "+q+", 0 0 4px "+q+", 0 0 4px "+q)),b.fontPercent&&1!==b.fontPercent){var h=p["default"].parseFloat(g.style.fontSize);g.style.fontSize=h*b.fontPercent+"px",g.style.height="auto",g.style.top="auto",g.style.bottom="2px"}b.fontFamily&&"default"!==b.fontFamily&&("small-caps"===b.fontFamily?g.firstChild.style.fontVariant="small-caps":g.firstChild.style.fontFamily=s[b.fontFamily])}}}},b}(l["default"]);l["default"].registerComponent("TextTrackDisplay",t),c["default"]=t},{5:5,83:83,95:95}],69:[function(a,b,c){"use strict";c.__esModule=!0;var d=function(a){var b=["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(function(b,c,d){return a[c]&&(b[c]=a[c]),b},{cues:a.cues&&Array.prototype.map.call(a.cues,function(a){return{startTime:a.startTime,endTime:a.endTime,text:a.text,id:a.id}})});return b},e=function(a){var b=a.$$("track"),c=Array.prototype.map.call(b,function(a){return a.track}),e=Array.prototype.map.call(b,function(a){var b=d(a.track);return a.src&&(b.src=a.src),b});return e.concat(Array.prototype.filter.call(a.textTracks(),function(a){return c.indexOf(a)===-1}).map(d))},f=function(a,b){return a.forEach(function(a){var c=b.addRemoteTextTrack(a).track;!a.src&&a.cues&&a.cues.forEach(function(a){return c.addCue(a)})}),b.textTracks()};c["default"]={textTracksToJson:e,jsonToTextTracks:f,trackToJson_:d}},{}],70:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(74),j=e(i),k=a(83),l=d(k),m=a(78),n=d(m),o=a(94),p=e(o),q=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];f(this,b);var h=void 0;if(n.IS_IE8){h=p["default"].createElement("custom");for(var i in j["default"].prototype)"constructor"!==i&&(h[i]=j["default"].prototype[i]);for(var k in b.prototype)"constructor"!==k&&(h[k]=b.prototype[k])}return h=c=g(this,a.call(this,e,h)),d=h,g(c,d)}return h(b,a),b.prototype.addTrack_=function(b){a.prototype.addTrack_.call(this,b),b.addEventListener("modechange",l.bind(this,function(){this.trigger("change")}))},b}(j["default"]);c["default"]=q},{74:74,78:78,83:83,94:94}],71:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}function i(a,b){if(b&&(a=b(a)),a&&"none"!==a)return a}function j(a,b){var c=a.options[a.options.selectedIndex].value;return i(c,b)}function k(a,b,c){if(b)for(var d=0;d<a.options.length;d++)if(i(a.options[d].value,c)===b){a.selectedIndex=d;break}}c.__esModule=!0;var l=a(95),m=e(l),n=a(5),o=e(n),p=a(81),q=a(83),r=d(q),s=a(88),t=d(s),u=a(86),v=e(u),w="vjs-text-track-settings",x=["#000","Black"],y=["#00F","Blue"],z=["#0FF","Cyan"],A=["#0F0","Green"],B=["#F0F","Magenta"],C=["#F00","Red"],D=["#FFF","White"],E=["#FF0","Yellow"],F=["1","Opaque"],G=["0.5","Semi-Transparent"],H=["0","Transparent"],I={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[x,D,C,A,y,E,B,z]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Transparency",options:[F,G,H]},color:{selector:".vjs-fg-color > select",id:"captions-foreground-color-%s",label:"Color",options:[D,x,C,A,y,E,B,z]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Dropshadow"]]},fontFamily:{selector:".vjs-font-family > select",id:"captions-font-family-%s",label:"Font Family",options:[["proportionalSansSerif","Proportional Sans-Serif"],["monospaceSansSerif","Monospace Sans-Serif"],["proportionalSerif","Proportional Serif"],["monospaceSerif","Monospace Serif"],["casual","Casual"],["script","Script"],["small-caps","Small Caps"]]},fontPercent:{selector:".vjs-font-percent > select",id:"captions-font-size-%s",label:"Font Size",options:[["0.50","50%"],["0.75","75%"],["1.00","100%"],["1.25","125%"],["1.50","150%"],["1.75","175%"],["2.00","200%"],["3.00","300%"],["4.00","400%"]],"default":2,parser:function(a){return"1.00"===a?null:Number(a)}},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Transparency",options:[F,G]},windowColor:{selector:".vjs-window-color > select",id:"captions-window-color-%s",label:"Color"},windowOpacity:{selector:".vjs-window-opacity > select",id:"captions-window-opacity-%s",label:"Transparency",options:[H,G,F]}};I.windowColor.options=I.backgroundColor.options;var J=function(a){function b(c,d){f(this,b);var e=g(this,a.call(this,c,d));return e.setDefaults(),e.hide(),e.updateDisplay=r.bind(e,e.updateDisplay),void 0===d.persistTextTrackSettings&&(e.options_.persistTextTrackSettings=e.options_.playerOptions.persistTextTrackSettings),e.on(e.$(".vjs-done-button"),"click",function(){e.saveSettings(),e.hide()}),e.on(e.$(".vjs-default-button"),"click",function(){e.setDefaults(),e.updateDisplay()}),t.each(I,function(a){e.on(e.$(a.selector),"change",e.updateDisplay)}),e.options_.persistTextTrackSettings&&e.restoreSettings(),e}return h(b,a),b.prototype.createElSelect_=function(a){var b=this,c=I[a],d=c.id.replace("%s",this.id_);return[(0,p.createEl)("label",{className:"vjs-label",textContent:c.label},{"for":d}),(0,p.createEl)("select",{id:d},void 0,c.options.map(function(a){return(0,p.createEl)("option",{textContent:b.localize(a[1]),value:a[0]})}))]},b.prototype.createElFgColor_=function(){var a=(0,p.createEl)("legend",{textContent:this.localize("Text")}),b=this.createElSelect_("color"),c=(0,p.createEl)("span",{className:"vjs-text-opacity vjs-opacity"},void 0,this.createElSelect_("textOpacity"));return(0,p.createEl)("fieldset",{className:"vjs-fg-color vjs-tracksetting"},void 0,[a].concat(b,c))},b.prototype.createElBgColor_=function(){var a=(0,p.createEl)("legend",{textContent:this.localize("Background")}),b=this.createElSelect_("backgroundColor"),c=(0,p.createEl)("span",{className:"vjs-bg-opacity vjs-opacity"},void 0,this.createElSelect_("backgroundOpacity"));return(0,p.createEl)("fieldset",{className:"vjs-bg-color vjs-tracksetting"},void 0,[a].concat(b,c))},b.prototype.createElWinColor_=function(){var a=(0,p.createEl)("legend",{textContent:this.localize("Window")}),b=this.createElSelect_("windowColor"),c=(0,p.createEl)("span",{className:"vjs-window-opacity vjs-opacity"},void 0,this.createElSelect_("windowOpacity"));return(0,p.createEl)("fieldset",{className:"vjs-window-color vjs-tracksetting"},void 0,[a].concat(b,c))},b.prototype.createElColors_=function(){return(0,p.createEl)("div",{className:"vjs-tracksettings-colors"},void 0,[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()])},b.prototype.createElFont_=function(){var a=(0,p.createEl)("div",{className:"vjs-font-percent vjs-tracksetting"},void 0,this.createElSelect_("fontPercent")),b=(0,p.createEl)("div",{className:"vjs-edge-style vjs-tracksetting"},void 0,this.createElSelect_("edgeStyle")),c=(0,p.createEl)("div",{className:"vjs-font-family vjs-tracksetting"},void 0,this.createElSelect_("fontFamily"));return(0,p.createEl)("div",{className:"vjs-tracksettings-font"},void 0,[a,b,c])},b.prototype.createElControls_=function(){var a=(0,p.createEl)("button",{className:"vjs-default-button",textContent:this.localize("Defaults")}),b=(0,p.createEl)("button",{className:"vjs-done-button",textContent:"Done"});return(0,p.createEl)("div",{className:"vjs-tracksettings-controls"},void 0,[a,b])},b.prototype.createEl=function(){var a=(0,p.createEl)("div",{className:"vjs-tracksettings"},void 0,[this.createElColors_(),this.createElFont_(),this.createElControls_()]),b=(0,p.createEl)("div",{className:"vjs-control-text",id:"TTsettingsDialogLabel-"+this.id_,textContent:"Caption Settings Dialog"},{"aria-level":"1",role:"heading"}),c=(0,p.createEl)("div",{className:"vjs-control-text",id:"TTsettingsDialogDescription-"+this.id_,textContent:"Beginning of dialog window. Escape will cancel and close the window."}),d=(0,p.createEl)("div",void 0,{role:"document"},[b,c,a]);return(0,p.createEl)("div",{className:"vjs-caption-settings vjs-modal-overlay",tabIndex:-1},{role:"dialog","aria-labelledby":b.id,"aria-describedby":c.id},d)},b.prototype.getValues=function(){var a=this;return t.reduce(I,function(b,c,d){var e=j(a.$(c.selector),c.parser);return void 0!==e&&(b[d]=e),b},{})},b.prototype.setValues=function(a){var b=this;t.each(I,function(c,d){k(b.$(c.selector),a[d],c.parser)})},b.prototype.setDefaults=function(){var a=this;t.each(I,function(b){var c=b.hasOwnProperty("default")?b["default"]:0;a.$(b.selector).selectedIndex=c})},b.prototype.restoreSettings=function(){var a=void 0;try{a=JSON.parse(m["default"].localStorage.getItem(w))}catch(b){v["default"].warn(b)}a&&this.setValues(a)},b.prototype.saveSettings=function(){if(this.options_.persistTextTrackSettings){var a=this.getValues();try{Object.keys(a).length?m["default"].localStorage.setItem(w,JSON.stringify(a)):m["default"].localStorage.removeItem(w)}catch(b){v["default"].warn(b)}}},b.prototype.updateDisplay=function(){var a=this.player_.getChild("textTrackDisplay");a&&a.updateDisplay()},b}(o["default"]);o["default"].registerComponent("TextTrackSettings",J),c["default"]=J},{5:5,81:81,83:83,86:86,88:88,95:95}],72:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(67),j=e(i),k=a(83),l=d(k),m=a(73),n=a(86),o=e(n),p=a(95),q=e(p),r=a(75),s=e(r),t=a(92),u=a(99),v=e(u),w=a(87),x=e(w),y=a(78),z=d(y),A=function(a,b){var c=new q["default"].WebVTT.Parser(q["default"],q["default"].vttjs,q["default"].WebVTT.StringDecoder()),d=[];c.oncue=function(a){b.addCue(a)},c.onparsingerror=function(a){d.push(a)},c.onflush=function(){b.trigger({type:"loadeddata",target:b})},c.parse(a),d.length>0&&(q["default"].console&&q["default"].console.groupCollapsed&&q["default"].console.groupCollapsed("Text Track parsing errors for "+b.src),d.forEach(function(a){return o["default"].error(a)}),q["default"].console&&q["default"].console.groupEnd&&q["default"].console.groupEnd()),c.flush()},B=function(a,b){var c={uri:a},d=(0,t.isCrossOrigin)(a);d&&(c.cors=d),(0,v["default"])(c,l.bind(this,function(a,c,d){return a?o["default"].error(a,c):(b.loaded_=!0,void("function"!=typeof q["default"].WebVTT?b.tech_&&!function(){var a=function(){return A(d,b)};b.tech_.on("vttjsloaded",a),b.tech_.on("vttjserror",function(){o["default"].error("vttjs failed to load, stopping trying to process "+b.src),b.tech_.off("vttjsloaded",a)})}():A(d,b)))}))},C=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(f(this,b),!e.tech)throw new Error("A tech was not provided.");var h=(0,x["default"])(e,{kind:m.TextTrackKind[e.kind]||"subtitles",language:e.language||e.srclang||""}),i=m.TextTrackMode[h.mode]||"disabled",k=h["default"];"metadata"!==h.kind&&"chapters"!==h.kind||(i="hidden");var n=c=g(this,a.call(this,h));if(n.tech_=h.tech,z.IS_IE8)for(var o in b.prototype)"constructor"!==o&&(n[o]=b.prototype[o]);n.cues_=[],n.activeCues_=[];var p=new j["default"](n.cues_),q=new j["default"](n.activeCues_),r=!1,s=l.bind(n,function(){this.activeCues,r&&(this.trigger("cuechange"),r=!1)});return"disabled"!==i&&n.tech_.on("timeupdate",s),Object.defineProperty(n,"default",{get:function(){return k},set:function(){}}),Object.defineProperty(n,"mode",{get:function(){return i},set:function(a){m.TextTrackMode[a]&&(i=a,"showing"===i&&this.tech_.on("timeupdate",s),this.trigger("modechange"))}}),Object.defineProperty(n,"cues",{get:function(){return this.loaded_?p:null},set:function(){}}),Object.defineProperty(n,"activeCues",{get:function(){if(!this.loaded_)return null;if(0===this.cues.length)return q;for(var a=this.tech_.currentTime(),b=[],c=0,d=this.cues.length;c<d;c++){var e=this.cues[c];e.startTime<=a&&e.endTime>=a?b.push(e):e.startTime===e.endTime&&e.startTime<=a&&e.startTime+.5>=a&&b.push(e)}if(r=!1,b.length!==this.activeCues_.length)r=!0;else for(var f=0;f<b.length;f++)this.activeCues_.indexOf(b[f])===-1&&(r=!0);return this.activeCues_=b,q.setCues_(this.activeCues_), +q},set:function(){}}),h.src?(n.src=h.src,B(h.src,n)):n.loaded_=!0,d=n,g(c,d)}return h(b,a),b.prototype.addCue=function(a){var b=this.tech_.textTracks();if(b)for(var c=0;c<b.length;c++)b[c]!==this&&b[c].removeCue(a);this.cues_.push(a),this.cues.setCues_(this.cues_)},b.prototype.removeCue=function(a){for(var b=!1,c=0,d=this.cues_.length;c<d;c++){var e=this.cues_[c];e===a&&(this.cues_.splice(c,1),b=!0)}b&&this.cues.setCues_(this.cues_)},b}(s["default"]);C.prototype.allowedEvents_={cuechange:"cuechange"},c["default"]=C},{67:67,73:73,75:75,78:78,83:83,86:86,87:87,92:92,95:95,99:99}],73:[function(a,b,c){"use strict";c.__esModule=!0;c.VideoTrackKind={alternative:"alternative",captions:"captions",main:"main",sign:"sign",subtitles:"subtitles",commentary:"commentary"},c.AudioTrackKind={alternative:"alternative",descriptions:"descriptions",main:"main","main-desc":"main-desc",translation:"translation",commentary:"commentary"},c.TextTrackKind={subtitles:"subtitles",captions:"captions",descriptions:"descriptions",chapters:"chapters",metadata:"metadata"},c.TextTrackMode={disabled:"disabled",hidden:"hidden",showing:"showing"}},{}],74:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(42),j=e(i),k=a(78),l=d(k),m=a(94),n=e(m),o=function(a){function b(){var c,d=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;f(this,b);var h=g(this,a.call(this));if(!e&&(e=h,l.IS_IE8)){e=n["default"].createElement("custom");for(var i in b.prototype)"constructor"!==i&&(e[i]=b.prototype[i])}e.tracks_=[],Object.defineProperty(e,"length",{get:function(){return this.tracks_.length}});for(var j=0;j<d.length;j++)e.addTrack_(d[j]);return c=e,g(h,c)}return h(b,a),b.prototype.addTrack_=function(a){var b=this.tracks_.length;""+b in this||Object.defineProperty(this,b,{get:function(){return this.tracks_[b]}}),this.tracks_.indexOf(a)===-1&&(this.tracks_.push(a),this.trigger({track:a,type:"addtrack"}))},b.prototype.removeTrack_=function(a){for(var b=void 0,c=0,d=this.length;c<d;c++)if(this[c]===a){b=this[c],b.off&&b.off(),this.tracks_.splice(c,1);break}b&&this.trigger({track:b,type:"removetrack"})},b.prototype.getTrackById=function(a){for(var b=null,c=0,d=this.length;c<d;c++){var e=this[c];if(e.id===a){b=e;break}}return b},b}(j["default"]);o.prototype.allowedEvents_={change:"change",addtrack:"addtrack",removetrack:"removetrack"};for(var p in o.prototype.allowedEvents_)o.prototype["on"+p]=null;c["default"]=o},{42:42,78:78,94:94}],75:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(78),j=e(i),k=a(94),l=d(k),m=a(85),n=e(m),o=a(42),p=d(o),q=function(a){function b(){var c,d=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};f(this,b);var e=g(this,a.call(this)),h=e;if(j.IS_IE8){h=l["default"].createElement("custom");for(var i in b.prototype)"constructor"!==i&&(h[i]=b.prototype[i])}var k={id:d.id||"vjs_track_"+n.newGUID(),kind:d.kind||"",label:d.label||"",language:d.language||""},m=function(a){Object.defineProperty(h,a,{get:function(){return k[a]},set:function(){}})};for(var o in k)m(o);return c=h,g(e,c)}return h(b,a),b}(p["default"]);c["default"]=q},{42:42,78:78,85:85,94:94}],76:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(74),j=e(i),k=a(78),l=d(k),m=a(94),n=e(m),o=function(a,b){for(var c=0;c<a.length;c++)b.id!==a[c].id&&(a[c].selected=!1)},p=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];f(this,b);for(var h=void 0,i=e.length-1;i>=0;i--)if(e[i].selected){o(e,e[i]);break}if(l.IS_IE8){h=n["default"].createElement("custom");for(var k in j["default"].prototype)"constructor"!==k&&(h[k]=j["default"].prototype[k]);for(var m in b.prototype)"constructor"!==m&&(h[m]=b.prototype[m])}return h=c=g(this,a.call(this,e,h)),h.changing_=!1,Object.defineProperty(h,"selectedIndex",{get:function(){for(var a=0;a<this.length;a++)if(this[a].selected)return a;return-1},set:function(){}}),d=h,g(c,d)}return h(b,a),b.prototype.addTrack_=function(b){var c=this;b.selected&&o(this,b),a.prototype.addTrack_.call(this,b),b.addEventListener&&b.addEventListener("selectedchange",function(){c.changing_||(c.changing_=!0,o(c,b),c.changing_=!1,c.trigger("change"))})},b.prototype.addTrack=function(a){this.addTrack_(a)},b.prototype.removeTrack=function(b){a.prototype.removeTrack_.call(this,b)},b}(j["default"]);c["default"]=p},{74:74,78:78,94:94}],77:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function g(a,b){if(!a)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!b||"object"!=typeof b&&"function"!=typeof b?a:b}function h(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}c.__esModule=!0;var i=a(73),j=a(75),k=e(j),l=a(87),m=e(l),n=a(78),o=d(n),p=function(a){function b(){var c,d,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};f(this,b);var h=(0,m["default"])(e,{kind:i.VideoTrackKind[e.kind]||""}),j=c=g(this,a.call(this,h)),k=!1;if(o.IS_IE8)for(var l in b.prototype)"constructor"!==l&&(j[l]=b.prototype[l]);return Object.defineProperty(j,"selected",{get:function(){return k},set:function(a){"boolean"==typeof a&&a!==k&&(k=a,this.trigger("selectedchange"))}}),h.selected&&(j.selected=h.selected),d=j,g(c,d)}return h(b,a),b}(k["default"]);c["default"]=p},{73:73,75:75,78:78,87:87}],78:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}c.__esModule=!0,c.BACKGROUND_SIZE_SUPPORTED=c.TOUCH_ENABLED=c.IS_ANY_SAFARI=c.IS_SAFARI=c.IE_VERSION=c.IS_IE8=c.IS_CHROME=c.IS_EDGE=c.IS_FIREFOX=c.IS_NATIVE_ANDROID=c.IS_OLD_ANDROID=c.ANDROID_VERSION=c.IS_ANDROID=c.IOS_VERSION=c.IS_IOS=c.IS_IPOD=c.IS_IPHONE=c.IS_IPAD=void 0;var f=a(81),g=e(f),h=a(95),i=d(h),j=i["default"].navigator&&i["default"].navigator.userAgent||"",k=/AppleWebKit\/([\d.]+)/i.exec(j),l=k?parseFloat(k.pop()):null,m=c.IS_IPAD=/iPad/i.test(j),n=c.IS_IPHONE=/iPhone/i.test(j)&&!m,o=c.IS_IPOD=/iPod/i.test(j),p=c.IS_IOS=n||m||o,q=(c.IOS_VERSION=function(){var a=j.match(/OS (\d+)_/i);return a&&a[1]?a[1]:null}(),c.IS_ANDROID=/Android/i.test(j)),r=c.ANDROID_VERSION=function(){var a=j.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!a)return null;var b=a[1]&&parseFloat(a[1]),c=a[2]&&parseFloat(a[2]);return b&&c?parseFloat(a[1]+"."+a[2]):b?b:null}(),s=(c.IS_OLD_ANDROID=q&&/webkit/i.test(j)&&r<2.3,c.IS_NATIVE_ANDROID=q&&r<5&&l<537,c.IS_FIREFOX=/Firefox/i.test(j),c.IS_EDGE=/Edge/i.test(j)),t=c.IS_CHROME=!s&&/Chrome/i.test(j),u=(c.IS_IE8=/MSIE\s8\.0/.test(j),c.IE_VERSION=function(a){return a&&parseFloat(a[1])}(/MSIE\s(\d+)\.\d/.exec(j)),c.IS_SAFARI=/Safari/i.test(j)&&!t&&!q&&!s);c.IS_ANY_SAFARI=u||p,c.TOUCH_ENABLED=g.isReal()&&("ontouchstart"in i["default"]||i["default"].DocumentTouch&&i["default"].document instanceof i["default"].DocumentTouch),c.BACKGROUND_SIZE_SUPPORTED=g.isReal()&&"backgroundSize"in i["default"].document.createElement("video").style},{81:81,95:95}],79:[function(a,b,c){"use strict";function d(a,b){var c=0,d=void 0,f=void 0;if(!b)return 0;a&&a.length||(a=(0,e.createTimeRange)(0,0));for(var g=0;g<a.length;g++)d=a.start(g),f=a.end(g),f>b&&(f=b),c+=f-d;return c/b}c.__esModule=!0,c.bufferedPercent=d;var e=a(90)},{90:90}],80:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b){if(!a||!b)return"";if("function"==typeof g["default"].getComputedStyle){var c=g["default"].getComputedStyle(a);return c?c[b]:""}return a.currentStyle[b]||""}c.__esModule=!0,c["default"]=e;var f=a(95),g=d(f)},{95:95}],81:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function e(a){return a&&a.__esModule?a:{"default":a}}function f(a,b){return a.raw=b,a}function g(a){return"string"==typeof a&&/\S/.test(a)}function h(a){if(/\s/.test(a))throw new Error("class has illegal whitespace characters")}function i(a){return new RegExp("(^|\\s)"+a+"($|\\s)")}function j(){return N["default"]===P["default"].document&&"undefined"!=typeof N["default"].createElement}function k(a){return(0,W.isObject)(a)&&1===a.nodeType}function l(a){return function(b,c){if(!g(b))return N["default"][a](null);g(c)&&(c=N["default"].querySelector(c));var d=k(c)?c:N["default"];return d[a]&&d[a](b)}}function m(a){return 0===a.indexOf("#")&&(a=a.slice(1)),N["default"].getElementById(a)}function n(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},d=arguments[3],e=N["default"].createElement(a);return Object.getOwnPropertyNames(b).forEach(function(a){var c=b[a];a.indexOf("aria-")!==-1||"role"===a||"type"===a?(T["default"].warn((0,V["default"])(L,a,c)),e.setAttribute(a,c)):"textContent"===a?o(e,c):e[a]=c}),Object.getOwnPropertyNames(c).forEach(function(a){e.setAttribute(a,c[a])}),d&&J(e,d),e}function o(a,b){return"undefined"==typeof a.textContent?a.innerText=b:a.textContent=b,a}function p(a,b){b.firstChild?b.insertBefore(a,b.firstChild):b.appendChild(a)}function q(a){var b=a[Y];return b||(b=a[Y]=R.newGUID()),X[b]||(X[b]={}),X[b]}function r(a){var b=a[Y];return!!b&&!!Object.getOwnPropertyNames(X[b]).length}function s(a){var b=a[Y];if(b){delete X[b];try{delete a[Y]}catch(c){a.removeAttribute?a.removeAttribute(Y):a[Y]=null}}}function t(a,b){return h(b),a.classList?a.classList.contains(b):i(b).test(a.className)}function u(a,b){return a.classList?a.classList.add(b):t(a,b)||(a.className=(a.className+" "+b).trim()),a}function v(a,b){return a.classList?a.classList.remove(b):(h(b),a.className=a.className.split(/\s+/).filter(function(a){return a!==b}).join(" ")),a}function w(a,b,c){var d=t(a,b);if("function"==typeof c&&(c=c(a,b)),"boolean"!=typeof c&&(c=!d),c!==d)return c?u(a,b):v(a,b),a}function x(a,b){Object.getOwnPropertyNames(b).forEach(function(c){var d=b[c];null===d||"undefined"==typeof d||d===!1?a.removeAttribute(c):a.setAttribute(c,d===!0?"":d)})}function y(a){var b={},c=",autoplay,controls,loop,muted,default,";if(a&&a.attributes&&a.attributes.length>0)for(var d=a.attributes,e=d.length-1;e>=0;e--){var f=d[e].name,g=d[e].value;"boolean"!=typeof a[f]&&c.indexOf(","+f+",")===-1||(g=null!==g),b[f]=g}return b}function z(a,b){return a.getAttribute(b)}function A(a,b,c){a.setAttribute(b,c)}function B(a,b){a.removeAttribute(b)}function C(){N["default"].body.focus(),N["default"].onselectstart=function(){return!1}}function D(){N["default"].onselectstart=function(){return!0}}function E(a){var b=void 0;if(a.getBoundingClientRect&&a.parentNode&&(b=a.getBoundingClientRect()),!b)return{left:0,top:0};var c=N["default"].documentElement,d=N["default"].body,e=c.clientLeft||d.clientLeft||0,f=P["default"].pageXOffset||d.scrollLeft,g=b.left+f-e,h=c.clientTop||d.clientTop||0,i=P["default"].pageYOffset||d.scrollTop,j=b.top+i-h;return{left:Math.round(g),top:Math.round(j)}}function F(a,b){var c={},d=E(a),e=a.offsetWidth,f=a.offsetHeight,g=d.top,h=d.left,i=b.pageY,j=b.pageX;return b.changedTouches&&(j=b.changedTouches[0].pageX,i=b.changedTouches[0].pageY),c.y=Math.max(0,Math.min(1,(g-i+f)/f)),c.x=Math.max(0,Math.min(1,(j-h)/e)),c}function G(a){return(0,W.isObject)(a)&&3===a.nodeType}function H(a){for(;a.firstChild;)a.removeChild(a.firstChild);return a}function I(a){return"function"==typeof a&&(a=a()),(Array.isArray(a)?a:[a]).map(function(a){return"function"==typeof a&&(a=a()),k(a)||G(a)?a:"string"==typeof a&&/\S/.test(a)?N["default"].createTextNode(a):void 0}).filter(function(a){return a})}function J(a,b){return I(b).forEach(function(b){return a.appendChild(b)}),a}function K(a,b){return J(H(a),b)}c.__esModule=!0,c.$$=c.$=void 0;var L=f(["Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set "," to ","."],["Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set "," to ","."]);c.isReal=j,c.isEl=k,c.getEl=m,c.createEl=n,c.textContent=o,c.insertElFirst=p,c.getElData=q,c.hasElData=r,c.removeElData=s,c.hasElClass=t,c.addElClass=u,c.removeElClass=v,c.toggleElClass=w,c.setElAttributes=x,c.getElAttributes=y,c.getAttribute=z,c.setAttribute=A,c.removeAttribute=B,c.blockTextSelection=C,c.unblockTextSelection=D,c.findElPosition=E,c.getPointerPosition=F,c.isTextNode=G,c.emptyEl=H,c.normalizeContent=I,c.appendContent=J,c.insertContent=K;var M=a(94),N=e(M),O=a(95),P=e(O),Q=a(85),R=d(Q),S=a(86),T=e(S),U=a(98),V=e(U),W=a(88),X={},Y="vdata"+(new Date).getTime();c.$=l("querySelector"),c.$$=l("querySelectorAll")},{85:85,86:86,88:88,94:94,95:95,98:98}],82:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a,b){var c=n.getElData(a);0===c.handlers[b].length&&(delete c.handlers[b],a.removeEventListener?a.removeEventListener(b,c.dispatcher,!1):a.detachEvent&&a.detachEvent("on"+b,c.dispatcher)),Object.getOwnPropertyNames(c.handlers).length<=0&&(delete c.handlers,delete c.dispatcher,delete c.disabled),0===Object.getOwnPropertyNames(c).length&&n.removeElData(a)}function g(a,b,c,d){c.forEach(function(c){a(b,c,d)})}function h(a){function b(){return!0}function c(){return!1}return a&&a.isPropagationStopped||!function(){var d=a||t["default"].event;a={};for(var e in d)"layerX"!==e&&"layerY"!==e&&"keyLocation"!==e&&"webkitMovementX"!==e&&"webkitMovementY"!==e&&("returnValue"===e&&d.preventDefault||(a[e]=d[e]));if(a.target||(a.target=a.srcElement||v["default"]),a.relatedTarget||(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement),a.preventDefault=function(){d.preventDefault&&d.preventDefault(),a.returnValue=!1,d.returnValue=!1,a.defaultPrevented=!0},a.defaultPrevented=!1,a.stopPropagation=function(){d.stopPropagation&&d.stopPropagation(),a.cancelBubble=!0,d.cancelBubble=!0,a.isPropagationStopped=b},a.isPropagationStopped=c,a.stopImmediatePropagation=function(){d.stopImmediatePropagation&&d.stopImmediatePropagation(),a.isImmediatePropagationStopped=b,a.stopPropagation()},a.isImmediatePropagationStopped=c,null!==a.clientX&&void 0!==a.clientX){var f=v["default"].documentElement,g=v["default"].body;a.pageX=a.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=a.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)}a.which=a.charCode||a.keyCode,null!==a.button&&void 0!==a.button&&(a.button=1&a.button?0:4&a.button?1:2&a.button?2:0)}(),a}function i(a,b,c){if(Array.isArray(b))return g(i,a,b,c);var d=n.getElData(a);d.handlers||(d.handlers={}),d.handlers[b]||(d.handlers[b]=[]),c.guid||(c.guid=p.newGUID()),d.handlers[b].push(c),d.dispatcher||(d.disabled=!1,d.dispatcher=function(b,c){if(!d.disabled){b=h(b);var e=d.handlers[b.type];if(e)for(var f=e.slice(0),g=0,i=f.length;g<i&&!b.isImmediatePropagationStopped();g++)try{f[g].call(a,b,c)}catch(j){r["default"].error(j)}}}),1===d.handlers[b].length&&(a.addEventListener?a.addEventListener(b,d.dispatcher,!1):a.attachEvent&&a.attachEvent("on"+b,d.dispatcher))}function j(a,b,c){if(n.hasElData(a)){var d=n.getElData(a);if(d.handlers){if(Array.isArray(b))return g(j,a,b,c);var e=function(b){d.handlers[b]=[],f(a,b)};if(b){var h=d.handlers[b];if(h){if(!c)return void e(b);if(c.guid)for(var i=0;i<h.length;i++)h[i].guid===c.guid&&h.splice(i--,1);f(a,b)}}else for(var k in d.handlers)e(k)}}}function k(a,b,c){var d=n.hasElData(a)?n.getElData(a):{},e=a.parentNode||a.ownerDocument;if("string"==typeof b&&(b={type:b,target:a}),b=h(b),d.dispatcher&&d.dispatcher.call(a,b,c),e&&!b.isPropagationStopped()&&b.bubbles===!0)k.call(null,e,b,c);else if(!e&&!b.defaultPrevented){var f=n.getElData(b.target);b.target[b.type]&&(f.disabled=!0,"function"==typeof b.target[b.type]&&b.target[b.type](),f.disabled=!1)}return!b.defaultPrevented}function l(a,b,c){if(Array.isArray(b))return g(l,a,b,c);var d=function e(){j(a,b,e),c.apply(this,arguments)};d.guid=c.guid=c.guid||p.newGUID(),i(a,b,d)}c.__esModule=!0,c.fixEvent=h,c.on=i,c.off=j,c.trigger=k,c.one=l;var m=a(81),n=e(m),o=a(85),p=e(o),q=a(86),r=d(q),s=a(95),t=d(s),u=a(94),v=d(u)},{81:81,85:85,86:86,94:94,95:95}],83:[function(a,b,c){"use strict";c.__esModule=!0,c.throttle=c.bind=void 0;var d=a(85);c.bind=function(a,b,c){b.guid||(b.guid=(0,d.newGUID)());var e=function(){return b.apply(a,arguments)};return e.guid=c?c+"_"+b.guid:b.guid,e},c.throttle=function(a,b){var c=Date.now(),d=function(){var d=Date.now();d-c>=b&&(a.apply(void 0,arguments),c=d)};return d}},{85:85}],84:[function(a,b,c){"use strict";function d(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a;a=a<0?0:a;var c=Math.floor(a%60),d=Math.floor(a/60%60),e=Math.floor(a/3600),f=Math.floor(b/60%60),g=Math.floor(b/3600);return(isNaN(a)||a===1/0)&&(e=d=c="-"),e=e>0||g>0?e+":":"",d=((e||f>=10)&&d<10?"0"+d:d)+":",c=c<10?"0"+c:c,e+d+c}c.__esModule=!0,c["default"]=d},{}],85:[function(a,b,c){"use strict";function d(){return e++}c.__esModule=!0,c.newGUID=d;var e=1},{}],86:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0,c.logByType=void 0;var e=a(95),f=d(e),g=a(78),h=a(88),i=void 0,j=c.logByType=function(a,b){var c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:!!g.IE_VERSION&&g.IE_VERSION<11;"log"!==a&&b.unshift(a.toUpperCase()+":"),i.history.push(b),b.unshift("VIDEOJS:");var d=f["default"].console&&f["default"].console[a];d&&(c&&(b=b.map(function(a){if((0,h.isObject)(a)||Array.isArray(a))try{return JSON.stringify(a)}catch(b){return String(a)}return String(a)}).join(" ")),d.apply?d[Array.isArray(b)?"apply":"call"](f["default"].console,b):d(b))};i=function(){for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];j("log",b)},i.history=[],i.error=function(){for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];return j("error",b)},i.warn=function(){for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];return j("warn",b)},c["default"]=i},{78:78,88:88,95:95}],87:[function(a,b,c){"use strict";function d(){for(var a={},b=arguments.length,c=Array(b),f=0;f<b;f++)c[f]=arguments[f];return c.forEach(function(b){b&&(0,e.each)(b,function(b,c){return(0,e.isPlain)(b)?((0,e.isPlain)(a[c])||(a[c]={}),void(a[c]=d(a[c],b))):void(a[c]=b)})}),a}c.__esModule=!0,c["default"]=d;var e=a(88)},{88:88}],88:[function(a,b,c){"use strict";function d(a,b){Object.keys(a).forEach(function(c){return b(a[c],c)})}function e(a,b){var c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Object.keys(a).reduce(function(c,d){return b(c,a[d],d)},c)}function f(a){for(var b=arguments.length,c=Array(b>1?b-1:0),e=1;e<b;e++)c[e-1]=arguments[e];return Object.assign?Object.assign.apply(Object,[a].concat(c)):(c.forEach(function(b){b&&d(b,function(b,c){a[c]=b})}),a)}function g(a){return!!a&&"object"===("undefined"==typeof a?"undefined":i(a))}function h(a){return g(a)&&"[object Object]"===j.call(a)&&a.constructor===Object}c.__esModule=!0;var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};c.each=d,c.reduce=e,c.assign=f,c.isObject=g,c.isPlain=h;var j=Object.prototype.toString},{}],89:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0,c.setTextContent=c.createStyleElement=void 0;var e=a(94),f=d(e);c.createStyleElement=function(a){var b=f["default"].createElement("style");return b.className=a,b},c.setTextContent=function(a,b){a.styleSheet?a.styleSheet.cssText=b:a.textContent=b}},{94:94}],90:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}function e(a,b,c){if(b<0||b>c)throw new Error("Failed to execute '"+a+"' on 'TimeRanges': The index provided ("+b+") is greater than or equal to the maximum bound ("+c+").")}function f(a,b,c,d){return void 0===d&&(j["default"].warn("DEPRECATED: Function '"+a+"' on 'TimeRanges' called without an index argument."),d=0),e(a,d,c.length-1),c[d][b]}function g(a){return void 0===a||0===a.length?{length:0,start:function(){throw new Error("This TimeRanges object is empty")},end:function(){throw new Error("This TimeRanges object is empty")}}:{length:a.length,start:f.bind(null,"start",0,a),end:f.bind(null,"end",1,a)}}function h(a,b){return Array.isArray(a)?g(a):void 0===a||void 0===b?g():g([[a,b]])}c.__esModule=!0,c.createTimeRange=void 0,c.createTimeRanges=h;var i=a(86),j=d(i);c.createTimeRange=h},{86:86}],91:[function(a,b,c){"use strict";function d(a){return"string"!=typeof a?a:a.charAt(0).toUpperCase()+a.slice(1)}c.__esModule=!0,c["default"]=d},{}],92:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{"default":a}}c.__esModule=!0,c.isCrossOrigin=c.getFileExtension=c.getAbsoluteURL=c.parseUrl=void 0;var e=a(94),f=d(e),g=a(95),h=d(g),i=c.parseUrl=function(a){var b=["protocol","hostname","port","pathname","search","hash","host"],c=f["default"].createElement("a");c.href=a;var d=""===c.host&&"file:"!==c.protocol,e=void 0;d&&(e=f["default"].createElement("div"),e.innerHTML='<a href="'+a+'"></a>',c=e.firstChild,e.setAttribute("style","display:none; position:absolute;"),f["default"].body.appendChild(e));for(var g={},h=0;h<b.length;h++)g[b[h]]=c[b[h]];return"http:"===g.protocol&&(g.host=g.host.replace(/:80$/,"")),"https:"===g.protocol&&(g.host=g.host.replace(/:443$/,"")),d&&f["default"].body.removeChild(e),g};c.getAbsoluteURL=function(a){if(!a.match(/^https?:\/\//)){var b=f["default"].createElement("div");b.innerHTML='<a href="'+a+'">x</a>',a=b.firstChild.href}return a},c.getFileExtension=function(a){if("string"==typeof a){var b=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i,c=b.exec(a);if(c)return c.pop().toLowerCase()}return""},c.isCrossOrigin=function(a){var b=h["default"].location,c=i(a),d=":"===c.protocol?b.protocol:c.protocol,e=d+c.host!==b.protocol+b.host;return e}},{94:94,95:95}],93:[function(b,c,d){"use strict";function e(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b}function f(a){return a&&a.__esModule?a:{"default":a}}function g(a,b,c){var d=void 0;if("string"==typeof a){if(0===a.indexOf("#")&&(a=a.slice(1)),g.getPlayers()[a])return b&&O["default"].warn('Player "'+a+'" is already initialised. Options will not be applied.'),c&&g.getPlayers()[a].ready(c),g.getPlayers()[a];d=Q.getEl(a)}else d=a;if(!d||!d.nodeName)throw new TypeError("The element or ID supplied is not valid. (videojs)");if(d.player||x["default"].players[d.playerId])return d.player||x["default"].players[d.playerId];b=b||{},g.hooks("beforesetup").forEach(function(a){var c=a(d,(0,B["default"])(b));return!(0,V.isObject)(c)||Array.isArray(c)?void O["default"].error("please return an object in beforesetup hooks"):void(b=(0,B["default"])(b,c))});var e=r["default"].getComponent("Player"),f=new e(d,b,c);return g.hooks("setup").forEach(function(a){return a(f)}),f}d.__esModule=!0;var h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},i=b(95),j=f(i),k=b(94),l=f(k),m=b(56),n=e(m),o=b(89),p=e(o),q=b(5),r=f(q),s=b(42),t=f(s),u=b(82),v=e(u),w=b(51),x=f(w),y=b(52),z=f(y),A=b(87),B=f(A),C=b(83),D=e(C),E=b(72),F=f(E),G=b(64),H=f(G),I=b(77),J=f(I),K=b(90),L=b(84),M=f(L),N=b(86),O=f(N),P=b(81),Q=e(P),R=b(78),S=e(R),T=b(92),U=e(T),V=b(88),W=b(80),X=f(W),Y=b(43),Z=f(Y),$=b(99),_=f($),aa=b(62),ba=f(aa);if("undefined"==typeof HTMLVideoElement&&Q.isReal()&&(l["default"].createElement("video"),l["default"].createElement("audio"),l["default"].createElement("track")),g.hooks_={},g.hooks=function(a,b){return g.hooks_[a]=g.hooks_[a]||[],b&&(g.hooks_[a]=g.hooks_[a].concat(b)),g.hooks_[a]},g.hook=function(a,b){g.hooks(a,b)},g.removeHook=function(a,b){var c=g.hooks(a).indexOf(b);return!(c<=-1)&&(g.hooks_[a]=g.hooks_[a].slice(),g.hooks_[a].splice(c,1),!0)},j["default"].VIDEOJS_NO_DYNAMIC_STYLE!==!0&&Q.isReal()){var ca=Q.$(".vjs-styles-defaults");if(!ca){ca=p.createStyleElement("vjs-styles-defaults");var da=Q.$("head");da&&da.insertBefore(ca,da.firstChild),p.setTextContent(ca,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ")}}n.autoSetupTimeout(1,g),g.VERSION="5.15.1",g.options=x["default"].prototype.options_,g.getPlayers=function(){return x["default"].players},g.players=x["default"].players,g.getComponent=r["default"].getComponent,g.registerComponent=function(a,b){ba["default"].isTech(b)&&O["default"].warn("The "+a+" tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)"),r["default"].registerComponent.call(r["default"],a,b)},g.getTech=ba["default"].getTech,g.registerTech=ba["default"].registerTech,g.browser=S,g.TOUCH_ENABLED=S.TOUCH_ENABLED,g.extend=Z["default"],g.mergeOptions=B["default"],g.bind=D.bind,g.plugin=z["default"],g.addLanguage=function(a,b){var c;return a=(""+a).toLowerCase(),g.options.languages=(0,B["default"])(g.options.languages,(c={},c[a]=b,c)),g.options.languages[a]},g.log=O["default"],g.createTimeRange=g.createTimeRanges=K.createTimeRanges,g.formatTime=M["default"],g.parseUrl=U.parseUrl,g.isCrossOrigin=U.isCrossOrigin,g.EventTarget=t["default"],g.on=v.on,g.one=v.one,g.off=v.off,g.trigger=v.trigger,g.xhr=_["default"],g.TextTrack=F["default"],g.AudioTrack=H["default"],g.VideoTrack=J["default"],g.isEl=Q.isEl,g.isTextNode=Q.isTextNode,g.createEl=Q.createEl,g.hasClass=Q.hasElClass,g.addClass=Q.addElClass,g.removeClass=Q.removeElClass,g.toggleClass=Q.toggleElClass,g.setAttributes=Q.setElAttributes,g.getAttributes=Q.getElAttributes,g.emptyEl=Q.emptyEl,g.appendContent=Q.appendContent,g.insertContent=Q.insertContent,g.computedStyle=X["default"],"function"==typeof a&&a.amd?a("videojs",[],function(){return g}):"object"===("undefined"==typeof d?"undefined":h(d))&&"object"===("undefined"==typeof c?"undefined":h(c))&&(c.exports=g),d["default"]=g},{42:42,43:43,5:5,51:51,52:52,56:56,62:62,64:64,72:72,77:77,78:78,80:80,81:81,82:82,83:83,84:84,86:86,87:87,88:88,89:89,90:90,92:92,94:94,95:95,99:99}],94:[function(a,b,c){(function(c){var d="undefined"!=typeof c?c:"undefined"!=typeof window?window:{},e=a(96);if("undefined"!=typeof document)b.exports=document;else{var f=d["__GLOBAL_DOCUMENT_CACHE@4"];f||(f=d["__GLOBAL_DOCUMENT_CACHE@4"]=e),b.exports=f}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{96:96}],95:[function(a,b,c){(function(a){"undefined"!=typeof window?b.exports=window:"undefined"!=typeof a?b.exports=a:"undefined"!=typeof self?b.exports=self:b.exports={}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],96:[function(a,b,c){},{}],97:[function(a,b,c){function d(a,b){var c,d=null;try{c=JSON.parse(a,b)}catch(e){d=e}return[d,c]}b.exports=d},{}],98:[function(a,b,c){function d(a){return a.replace(/\n\r?\s*/g,"")}b.exports=function(a){for(var b="",c=0;c<arguments.length;c++)b+=d(a[c])+(arguments[c+1]||"");return b}},{}],99:[function(a,b,c){"use strict";function d(a,b){for(var c=0;c<a.length;c++)b(a[c])}function e(a){for(var b in a)if(a.hasOwnProperty(b))return!1;return!0}function f(a,b,c){var d=a;return l(b)?(c=b,"string"==typeof a&&(d={uri:a})):d=n(b,{uri:a}),d.callback=c,d}function g(a,b,c){return b=f(a,b,c),h(b)}function h(a){function b(){4===l.readyState&&f()}function c(){var a=void 0;if(a=l.response?l.response:l.responseText||i(l),v)try{a=JSON.parse(a)}catch(b){}return a}function d(a){return clearTimeout(p),a instanceof Error||(a=new Error(""+(a||"Unknown XMLHttpRequest Error"))),a.statusCode=0,j(a,k)}function f(){if(!o){var b;clearTimeout(p),b=a.useXDR&&void 0===l.status?200:1223===l.status?204:l.status;var d=k,e=null;return 0!==b?(d={body:c(),statusCode:b,method:r,headers:{},url:q,rawRequest:l},l.getAllResponseHeaders&&(d.headers=m(l.getAllResponseHeaders()))):e=new Error("Internal XMLHttpRequest Error"),j(e,d,d.body)}}if("undefined"==typeof a.callback)throw new Error("callback argument missing");var h=!1,j=function(b,c,d){h||(h=!0,a.callback(b,c,d))},k={body:void 0,headers:{},statusCode:0,method:r,url:q,rawRequest:l},l=a.xhr||null;l||(l=a.cors||a.useXDR?new g.XDomainRequest:new g.XMLHttpRequest);var n,o,p,q=l.url=a.uri||a.url,r=l.method=a.method||"GET",s=a.body||a.data||null,t=l.headers=a.headers||{},u=!!a.sync,v=!1;if("json"in a&&(v=!0,t.accept||t.Accept||(t.Accept="application/json"),"GET"!==r&&"HEAD"!==r&&(t["content-type"]||t["Content-Type"]||(t["Content-Type"]="application/json"), +s=JSON.stringify(a.json))),l.onreadystatechange=b,l.onload=f,l.onerror=d,l.onprogress=function(){},l.ontimeout=d,l.open(r,q,!u,a.username,a.password),u||(l.withCredentials=!!a.withCredentials),!u&&a.timeout>0&&(p=setTimeout(function(){o=!0,l.abort("timeout");var a=new Error("XMLHttpRequest timeout");a.code="ETIMEDOUT",d(a)},a.timeout)),l.setRequestHeader)for(n in t)t.hasOwnProperty(n)&&l.setRequestHeader(n,t[n]);else if(a.headers&&!e(a.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in a&&(l.responseType=a.responseType),"beforeSend"in a&&"function"==typeof a.beforeSend&&a.beforeSend(l),l.send(s),l}function i(a){if("document"===a.responseType)return a.responseXML;var b=204===a.status&&a.responseXML&&"parsererror"===a.responseXML.documentElement.nodeName;return""!==a.responseType||b?null:a.responseXML}function j(){}var k=a(95),l=a(100),m=a(103),n=a(104);b.exports=g,g.XMLHttpRequest=k.XMLHttpRequest||j,g.XDomainRequest="withCredentials"in new g.XMLHttpRequest?g.XMLHttpRequest:k.XDomainRequest,d(["get","put","post","patch","head","delete"],function(a){g["delete"===a?"del":a]=function(b,c,d){return c=f(b,c,d),c.method=a.toUpperCase(),h(c)}})},{100:100,103:103,104:104,95:95}],100:[function(a,b,c){function d(a){var b=e.call(a);return"[object Function]"===b||"function"==typeof a&&"[object RegExp]"!==b||"undefined"!=typeof window&&(a===window.setTimeout||a===window.alert||a===window.confirm||a===window.prompt)}b.exports=d;var e=Object.prototype.toString},{}],101:[function(a,b,c){function d(a,b,c){if(!h(b))throw new TypeError("iterator must be a function");arguments.length<3&&(c=this),"[object Array]"===i.call(a)?e(a,b,c):"string"==typeof a?f(a,b,c):g(a,b,c)}function e(a,b,c){for(var d=0,e=a.length;d<e;d++)j.call(a,d)&&b.call(c,a[d],d,a)}function f(a,b,c){for(var d=0,e=a.length;d<e;d++)b.call(c,a.charAt(d),d,a)}function g(a,b,c){for(var d in a)j.call(a,d)&&b.call(c,a[d],d,a)}var h=a(100);b.exports=d;var i=Object.prototype.toString,j=Object.prototype.hasOwnProperty},{100:100}],102:[function(a,b,c){function d(a){return a.replace(/^\s*|\s*$/g,"")}c=b.exports=d,c.left=function(a){return a.replace(/^\s*/,"")},c.right=function(a){return a.replace(/\s*$/,"")}},{}],103:[function(a,b,c){var d=a(102),e=a(101),f=function(a){return"[object Array]"===Object.prototype.toString.call(a)};b.exports=function(a){if(!a)return{};var b={};return e(d(a).split("\n"),function(a){var c=a.indexOf(":"),e=d(a.slice(0,c)).toLowerCase(),g=d(a.slice(c+1));"undefined"==typeof b[e]?b[e]=g:f(b[e])?b[e].push(g):b[e]=[b[e],g]}),b}},{101:101,102:102}],104:[function(a,b,c){function d(){for(var a={},b=0;b<arguments.length;b++){var c=arguments[b];for(var d in c)e.call(c,d)&&(a[d]=c[d])}return a}b.exports=d;var e=Object.prototype.hasOwnProperty},{}]},{},[93])(93)}),function(a){var b=a.vttjs={},c=b.VTTCue,d=b.VTTRegion,e=a.VTTCue,f=a.VTTRegion;b.shim=function(){b.VTTCue=c,b.VTTRegion=d},b.restore=function(){b.VTTCue=e,b.VTTRegion=f}}(this),function(a,b){function c(a){if("string"!=typeof a)return!1;var b=h[a.toLowerCase()];return!!b&&a.toLowerCase()}function d(a){if("string"!=typeof a)return!1;var b=i[a.toLowerCase()];return!!b&&a.toLowerCase()}function e(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)a[d]=c[d]}return a}function f(a,b,f){var h=this,i=/MSIE\s8\.0/.test(navigator.userAgent),j={};i?h=document.createElement("custom"):j.enumerable=!0,h.hasBeenReset=!1;var k="",l=!1,m=a,n=b,o=f,p=null,q="",r=!0,s="auto",t="start",u=50,v="middle",w=50,x="middle";if(Object.defineProperty(h,"id",e({},j,{get:function(){return k},set:function(a){k=""+a}})),Object.defineProperty(h,"pauseOnExit",e({},j,{get:function(){return l},set:function(a){l=!!a}})),Object.defineProperty(h,"startTime",e({},j,{get:function(){return m},set:function(a){if("number"!=typeof a)throw new TypeError("Start time must be set to a number.");m=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"endTime",e({},j,{get:function(){return n},set:function(a){if("number"!=typeof a)throw new TypeError("End time must be set to a number.");n=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"text",e({},j,{get:function(){return o},set:function(a){o=""+a,this.hasBeenReset=!0}})),Object.defineProperty(h,"region",e({},j,{get:function(){return p},set:function(a){p=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"vertical",e({},j,{get:function(){return q},set:function(a){var b=c(a);if(b===!1)throw new SyntaxError("An invalid or illegal string was specified.");q=b,this.hasBeenReset=!0}})),Object.defineProperty(h,"snapToLines",e({},j,{get:function(){return r},set:function(a){r=!!a,this.hasBeenReset=!0}})),Object.defineProperty(h,"line",e({},j,{get:function(){return s},set:function(a){if("number"!=typeof a&&a!==g)throw new SyntaxError("An invalid number or illegal string was specified.");s=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"lineAlign",e({},j,{get:function(){return t},set:function(a){var b=d(a);if(!b)throw new SyntaxError("An invalid or illegal string was specified.");t=b,this.hasBeenReset=!0}})),Object.defineProperty(h,"position",e({},j,{get:function(){return u},set:function(a){if(a<0||a>100)throw new Error("Position must be between 0 and 100.");u=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"positionAlign",e({},j,{get:function(){return v},set:function(a){var b=d(a);if(!b)throw new SyntaxError("An invalid or illegal string was specified.");v=b,this.hasBeenReset=!0}})),Object.defineProperty(h,"size",e({},j,{get:function(){return w},set:function(a){if(a<0||a>100)throw new Error("Size must be between 0 and 100.");w=a,this.hasBeenReset=!0}})),Object.defineProperty(h,"align",e({},j,{get:function(){return x},set:function(a){var b=d(a);if(!b)throw new SyntaxError("An invalid or illegal string was specified.");x=b,this.hasBeenReset=!0}})),h.displayState=void 0,i)return h}var g="auto",h={"":!0,lr:!0,rl:!0},i={start:!0,middle:!0,end:!0,left:!0,right:!0};f.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)},a.VTTCue=a.VTTCue||f,b.VTTCue=f}(this,this.vttjs||{}),function(a,b){function c(a){if("string"!=typeof a)return!1;var b=f[a.toLowerCase()];return!!b&&a.toLowerCase()}function d(a){return"number"==typeof a&&a>=0&&a<=100}function e(){var a=100,b=3,e=0,f=100,g=0,h=100,i="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return a},set:function(b){if(!d(b))throw new Error("Width must be between 0 and 100.");a=b}},lines:{enumerable:!0,get:function(){return b},set:function(a){if("number"!=typeof a)throw new TypeError("Lines must be set to a number.");b=a}},regionAnchorY:{enumerable:!0,get:function(){return f},set:function(a){if(!d(a))throw new Error("RegionAnchorX must be between 0 and 100.");f=a}},regionAnchorX:{enumerable:!0,get:function(){return e},set:function(a){if(!d(a))throw new Error("RegionAnchorY must be between 0 and 100.");e=a}},viewportAnchorY:{enumerable:!0,get:function(){return h},set:function(a){if(!d(a))throw new Error("ViewportAnchorY must be between 0 and 100.");h=a}},viewportAnchorX:{enumerable:!0,get:function(){return g},set:function(a){if(!d(a))throw new Error("ViewportAnchorX must be between 0 and 100.");g=a}},scroll:{enumerable:!0,get:function(){return i},set:function(a){var b=c(a);if(b===!1)throw new SyntaxError("An invalid or illegal string was specified.");i=b}}})}var f={"":!0,up:!0};a.VTTRegion=a.VTTRegion||e,b.VTTRegion=e}(this,this.vttjs||{}),function(a){function b(a,b){this.name="ParsingError",this.code=a.code,this.message=b||a.message}function c(a){function b(a,b,c,d){return 3600*(0|a)+60*(0|b)+(0|c)+(0|d)/1e3}var c=a.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);return c?c[3]?b(c[1],c[2],c[3].replace(":",""),c[4]):c[1]>59?b(c[1],c[2],0,c[4]):b(0,c[1],c[2],c[4]):null}function d(){this.values=o(null)}function e(a,b,c,d){var e=d?a.split(d):[a];for(var f in e)if("string"==typeof e[f]){var g=e[f].split(c);if(2===g.length){var h=g[0],i=g[1];b(h,i)}}}function f(a,f,g){function h(){var d=c(a);if(null===d)throw new b(b.Errors.BadTimeStamp,"Malformed timestamp: "+k);return a=a.replace(/^[^\sa-zA-Z-]+/,""),d}function i(a,b){var c=new d;e(a,function(a,b){switch(a){case"region":for(var d=g.length-1;d>=0;d--)if(g[d].id===b){c.set(a,g[d].region);break}break;case"vertical":c.alt(a,b,["rl","lr"]);break;case"line":var e=b.split(","),f=e[0];c.integer(a,f),c.percent(a,f)?c.set("snapToLines",!1):null,c.alt(a,f,["auto"]),2===e.length&&c.alt("lineAlign",e[1],["start","middle","end"]);break;case"position":e=b.split(","),c.percent(a,e[0]),2===e.length&&c.alt("positionAlign",e[1],["start","middle","end"]);break;case"size":c.percent(a,b);break;case"align":c.alt(a,b,["start","middle","end","left","right"])}},/:/,/\s/),b.region=c.get("region",null),b.vertical=c.get("vertical",""),b.line=c.get("line","auto"),b.lineAlign=c.get("lineAlign","start"),b.snapToLines=c.get("snapToLines",!0),b.size=c.get("size",100),b.align=c.get("align","middle"),b.position=c.get("position",{start:0,left:0,middle:50,end:100,right:100},b.align),b.positionAlign=c.get("positionAlign",{start:"start",left:"start",middle:"middle",end:"end",right:"end"},b.align)}function j(){a=a.replace(/^\s+/,"")}var k=a;if(j(),f.startTime=h(),j(),"-->"!==a.substr(0,3))throw new b(b.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '-->'): "+k);a=a.substr(3),j(),f.endTime=h(),j(),i(a,f)}function g(a,b){function d(){function a(a){return b=b.substr(a.length),a}if(!b)return null;var c=b.match(/^([^<]*)(<[^>]+>?)?/);return a(c[1]?c[1]:c[2])}function e(a){return p[a]}function f(a){for(;o=a.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)a=a.replace(o[0],e);return a}function g(a,b){return!s[b.localName]||s[b.localName]===a.localName}function h(b,c){var d=q[b];if(!d)return null;var e=a.document.createElement(d);e.localName=d;var f=r[b];return f&&c&&(e[f]=c.trim()),e}for(var i,j=a.document.createElement("div"),k=j,l=[];null!==(i=d());)if("<"!==i[0])k.appendChild(a.document.createTextNode(f(i)));else{if("/"===i[1]){l.length&&l[l.length-1]===i.substr(2).replace(">","")&&(l.pop(),k=k.parentNode);continue}var m,n=c(i.substr(1,i.length-2));if(n){m=a.document.createProcessingInstruction("timestamp",n),k.appendChild(m);continue}var o=i.match(/^<([^.\s\/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);if(!o)continue;if(m=h(o[1],o[3]),!m)continue;if(!g(k,m))continue;o[2]&&(m.className=o[2].substr(1).replace("."," ")),l.push(o[1]),k.appendChild(m),k=m}return j}function h(a){function b(a,b){for(var c=b.childNodes.length-1;c>=0;c--)a.push(b.childNodes[c])}function c(a){if(!a||!a.length)return null;var d=a.pop(),e=d.textContent||d.innerText;if(e){var f=e.match(/^.*(\n|\r)/);return f?(a.length=0,f[0]):e}return"ruby"===d.tagName?c(a):d.childNodes?(b(a,d),c(a)):void 0}var d,e=[],f="";if(!a||!a.childNodes)return"ltr";for(b(e,a);f=c(e);)for(var g=0;g<f.length;g++){d=f.charCodeAt(g);for(var h=0;h<t.length;h++)if(t[h]===d)return"rtl"}return"ltr"}function i(a){if("number"==typeof a.line&&(a.snapToLines||a.line>=0&&a.line<=100))return a.line;if(!a.track||!a.track.textTrackList||!a.track.textTrackList.mediaElement)return-1;for(var b=a.track,c=b.textTrackList,d=0,e=0;e<c.length&&c[e]!==b;e++)"showing"===c[e].mode&&d++;return++d*-1}function j(){}function k(a,b,c){var d=/MSIE\s8\.0/.test(navigator.userAgent),e="rgba(255, 255, 255, 1)",f="rgba(0, 0, 0, 0.8)";d&&(e="rgb(255, 255, 255)",f="rgb(0, 0, 0)"),j.call(this),this.cue=b,this.cueDiv=g(a,b.text);var i={color:e,backgroundColor:f,position:"relative",left:0,right:0,top:0,bottom:0,display:"inline"};d||(i.writingMode=""===b.vertical?"horizontal-tb":"lr"===b.vertical?"vertical-lr":"vertical-rl",i.unicodeBidi="plaintext"),this.applyStyles(i,this.cueDiv),this.div=a.document.createElement("div"),i={textAlign:"middle"===b.align?"center":b.align,font:c.font,whiteSpace:"pre-line",position:"absolute"},d||(i.direction=h(this.cueDiv),i.writingMode=""===b.vertical?"horizontal-tb":"lr"===b.vertical?"vertical-lr":"vertical-rl".stylesunicodeBidi="plaintext"),this.applyStyles(i),this.div.appendChild(this.cueDiv);var k=0;switch(b.positionAlign){case"start":k=b.position;break;case"middle":k=b.position-b.size/2;break;case"end":k=b.position-b.size}""===b.vertical?this.applyStyles({left:this.formatStyle(k,"%"),width:this.formatStyle(b.size,"%")}):this.applyStyles({top:this.formatStyle(k,"%"),height:this.formatStyle(b.size,"%")}),this.move=function(a){this.applyStyles({top:this.formatStyle(a.top,"px"),bottom:this.formatStyle(a.bottom,"px"),left:this.formatStyle(a.left,"px"),right:this.formatStyle(a.right,"px"),height:this.formatStyle(a.height,"px"),width:this.formatStyle(a.width,"px")})}}function l(a){var b,c,d,e,f=/MSIE\s8\.0/.test(navigator.userAgent);if(a.div){c=a.div.offsetHeight,d=a.div.offsetWidth,e=a.div.offsetTop;var g=(g=a.div.childNodes)&&(g=g[0])&&g.getClientRects&&g.getClientRects();a=a.div.getBoundingClientRect(),b=g?Math.max(g[0]&&g[0].height||0,a.height/g.length):0}this.left=a.left,this.right=a.right,this.top=a.top||e,this.height=a.height||c,this.bottom=a.bottom||e+(a.height||c),this.width=a.width||d,this.lineHeight=void 0!==b?b:a.lineHeight,f&&!this.lineHeight&&(this.lineHeight=13)}function m(a,b,c,d){function e(a,b){for(var e,f=new l(a),g=1,h=0;h<b.length;h++){for(;a.overlapsOppositeAxis(c,b[h])||a.within(c)&&a.overlapsAny(d);)a.move(b[h]);if(a.within(c))return a;var i=a.intersectPercentage(c);g>i&&(e=new l(a),g=i),a=new l(f)}return e||f}var f=new l(b),g=b.cue,h=i(g),j=[];if(g.snapToLines){var k;switch(g.vertical){case"":j=["+y","-y"],k="height";break;case"rl":j=["+x","-x"],k="width";break;case"lr":j=["-x","+x"],k="width"}var m=f.lineHeight,n=m*Math.round(h),o=c[k]+m,p=j[0];Math.abs(n)>o&&(n=n<0?-1:1,n*=Math.ceil(o/m)*m),h<0&&(n+=""===g.vertical?c.height:c.width,j=j.reverse()),f.move(p,n)}else{var q=f.lineHeight/c.height*100;switch(g.lineAlign){case"middle":h-=q/2;break;case"end":h-=q}switch(g.vertical){case"":b.applyStyles({top:b.formatStyle(h,"%")});break;case"rl":b.applyStyles({left:b.formatStyle(h,"%")});break;case"lr":b.applyStyles({right:b.formatStyle(h,"%")})}j=["+y","-x","+x","-y"],f=new l(b)}var r=e(f,j);b.move(r.toCSSCompatValues(c))}function n(){}var o=Object.create||function(){function a(){}return function(b){if(1!==arguments.length)throw new Error("Object.create shim only accepts one parameter.");return a.prototype=b,new a}}();b.prototype=o(Error.prototype),b.prototype.constructor=b,b.Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},d.prototype={set:function(a,b){this.get(a)||""===b||(this.values[a]=b)},get:function(a,b,c){return c?this.has(a)?this.values[a]:b[c]:this.has(a)?this.values[a]:b},has:function(a){return a in this.values},alt:function(a,b,c){for(var d=0;d<c.length;++d)if(b===c[d]){this.set(a,b);break}},integer:function(a,b){/^-?\d+$/.test(b)&&this.set(a,parseInt(b,10))},percent:function(a,b){var c;return!!((c=b.match(/^([\d]{1,3})(\.[\d]*)?%$/))&&(b=parseFloat(b),b>=0&&b<=100))&&(this.set(a,b),!0)}};var p={"&":"&","<":"<",">":">","‎":"","‏":""," ":" "},q={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},r={v:"title",lang:"lang"},s={rt:"ruby"},t=[1470,1472,1475,1478,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1520,1521,1522,1523,1524,1544,1547,1549,1563,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1645,1646,1647,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1765,1766,1774,1775,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1807,1808,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1969,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2e3,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2036,2037,2042,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2074,2084,2088,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2142,2208,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,8207,64285,64287,64288,64289,64290,64291,64292,64293,64294,64295,64296,64298,64299,64300,64301,64302,64303,64304,64305,64306,64307,64308,64309,64310,64312,64313,64314,64315,64316,64318,64320,64321,64323,64324,64326,64327,64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340,64341,64342,64343,64344,64345,64346,64347,64348,64349,64350,64351,64352,64353,64354,64355,64356,64357,64358,64359,64360,64361,64362,64363,64364,64365,64366,64367,64368,64369,64370,64371,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,64382,64383,64384,64385,64386,64387,64388,64389,64390,64391,64392,64393,64394,64395,64396,64397,64398,64399,64400,64401,64402,64403,64404,64405,64406,64407,64408,64409,64410,64411,64412,64413,64414,64415,64416,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428,64429,64430,64431,64432,64433,64434,64435,64436,64437,64438,64439,64440,64441,64442,64443,64444,64445,64446,64447,64448,64449,64467,64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480,64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493,64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506,64507,64508,64509,64510,64511,64512,64513,64514,64515,64516,64517,64518,64519,64520,64521,64522,64523,64524,64525,64526,64527,64528,64529,64530,64531,64532,64533,64534,64535,64536,64537,64538,64539,64540,64541,64542,64543,64544,64545,64546,64547,64548,64549,64550,64551,64552,64553,64554,64555,64556,64557,64558,64559,64560,64561,64562,64563,64564,64565,64566,64567,64568,64569,64570,64571,64572,64573,64574,64575,64576,64577,64578,64579,64580,64581,64582,64583,64584,64585,64586,64587,64588,64589,64590,64591,64592,64593,64594,64595,64596,64597,64598,64599,64600,64601,64602,64603,64604,64605,64606,64607,64608,64609,64610,64611,64612,64613,64614,64615,64616,64617,64618,64619,64620,64621,64622,64623,64624,64625,64626,64627,64628,64629,64630,64631,64632,64633,64634,64635,64636,64637,64638,64639,64640,64641,64642,64643,64644,64645,64646,64647,64648,64649,64650,64651,64652,64653,64654,64655,64656,64657,64658,64659,64660,64661,64662,64663,64664,64665,64666,64667,64668,64669,64670,64671,64672,64673,64674,64675,64676,64677,64678,64679,64680,64681,64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694,64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707,64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720,64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733,64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746,64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759,64760,64761,64762,64763,64764,64765,64766,64767,64768,64769,64770,64771,64772,64773,64774,64775,64776,64777,64778,64779,64780,64781,64782,64783,64784,64785,64786,64787,64788,64789,64790,64791,64792,64793,64794,64795,64796,64797,64798,64799,64800,64801,64802,64803,64804,64805,64806,64807,64808,64809,64810,64811,64812,64813,64814,64815,64816,64817,64818,64819,64820,64821,64822,64823,64824,64825,64826,64827,64828,64829,64848,64849,64850,64851,64852,64853,64854,64855,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866,64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879,64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892,64893,64894,64895,64896,64897,64898,64899,64900,64901,64902,64903,64904,64905,64906,64907,64908,64909,64910,64911,64914,64915,64916,64917,64918,64919,64920,64921,64922,64923,64924,64925,64926,64927,64928,64929,64930,64931,64932,64933,64934,64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947,64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960,64961,64962,64963,64964,64965,64966,64967,65008,65009,65010,65011,65012,65013,65014,65015,65016,65017,65018,65019,65020,65136,65137,65138,65139,65140,65142,65143,65144,65145,65146,65147,65148,65149,65150,65151,65152,65153,65154,65155,65156,65157,65158,65159,65160,65161,65162,65163,65164,65165,65166,65167,65168,65169,65170,65171,65172,65173,65174,65175,65176,65177,65178,65179,65180,65181,65182,65183,65184,65185,65186,65187,65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200,65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213,65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226,65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239,65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252,65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265,65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,67584,67585,67586,67587,67588,67589,67592,67594,67595,67596,67597,67598,67599,67600,67601,67602,67603,67604,67605,67606,67607,67608,67609,67610,67611,67612,67613,67614,67615,67616,67617,67618,67619,67620,67621,67622,67623,67624,67625,67626,67627,67628,67629,67630,67631,67632,67633,67634,67635,67636,67637,67639,67640,67644,67647,67648,67649,67650,67651,67652,67653,67654,67655,67656,67657,67658,67659,67660,67661,67662,67663,67664,67665,67666,67667,67668,67669,67671,67672,67673,67674,67675,67676,67677,67678,67679,67840,67841,67842,67843,67844,67845,67846,67847,67848,67849,67850,67851,67852,67853,67854,67855,67856,67857,67858,67859,67860,67861,67862,67863,67864,67865,67866,67867,67872,67873,67874,67875,67876,67877,67878,67879,67880,67881,67882,67883,67884,67885,67886,67887,67888,67889,67890,67891,67892,67893,67894,67895,67896,67897,67903,67968,67969,67970,67971,67972,67973,67974,67975,67976,67977,67978,67979,67980,67981,67982,67983,67984,67985,67986,67987,67988,67989,67990,67991,67992,67993,67994,67995,67996,67997,67998,67999,68e3,68001,68002,68003,68004,68005,68006,68007,68008,68009,68010,68011,68012,68013,68014,68015,68016,68017,68018,68019,68020,68021,68022,68023,68030,68031,68096,68112,68113,68114,68115,68117,68118,68119,68121,68122,68123,68124,68125,68126,68127,68128,68129,68130,68131,68132,68133,68134,68135,68136,68137,68138,68139,68140,68141,68142,68143,68144,68145,68146,68147,68160,68161,68162,68163,68164,68165,68166,68167,68176,68177,68178,68179,68180,68181,68182,68183,68184,68192,68193,68194,68195,68196,68197,68198,68199,68200,68201,68202,68203,68204,68205,68206,68207,68208,68209,68210,68211,68212,68213,68214,68215,68216,68217,68218,68219,68220,68221,68222,68223,68352,68353,68354,68355,68356,68357,68358,68359,68360,68361,68362,68363,68364,68365,68366,68367,68368,68369,68370,68371,68372,68373,68374,68375,68376,68377,68378,68379,68380,68381,68382,68383,68384,68385,68386,68387,68388,68389,68390,68391,68392,68393,68394,68395,68396,68397,68398,68399,68400,68401,68402,68403,68404,68405,68416,68417,68418,68419,68420,68421,68422,68423,68424,68425,68426,68427,68428,68429,68430,68431,68432,68433,68434,68435,68436,68437,68440,68441,68442,68443,68444,68445,68446,68447,68448,68449,68450,68451,68452,68453,68454,68455,68456,68457,68458,68459,68460,68461,68462,68463,68464,68465,68466,68472,68473,68474,68475,68476,68477,68478,68479,68608,68609,68610,68611,68612,68613,68614,68615,68616,68617,68618,68619,68620,68621,68622,68623,68624,68625,68626,68627,68628,68629,68630,68631,68632,68633,68634,68635,68636,68637,68638,68639,68640,68641,68642,68643,68644,68645,68646,68647,68648,68649,68650,68651,68652,68653,68654,68655,68656,68657,68658,68659,68660,68661,68662,68663,68664,68665,68666,68667,68668,68669,68670,68671,68672,68673,68674,68675,68676,68677,68678,68679,68680,126464,126465,126466,126467,126469,126470,126471,126472,126473,126474,126475,126476,126477,126478,126479,126480,126481,126482,126483,126484,126485,126486,126487,126488,126489,126490,126491,126492,126493,126494,126495,126497,126498,126500,126503,126505,126506,126507,126508,126509,126510,126511,126512,126513,126514,126516,126517,126518,126519,126521,126523,126530,126535,126537,126539,126541,126542,126543,126545,126546,126548,126551,126553,126555,126557,126559,126561,126562,126564,126567,126568,126569,126570,126572,126573,126574,126575,126576,126577,126578,126580,126581,126582,126583,126585,126586,126587,126588,126590,126592,126593,126594,126595,126596,126597,126598,126599,126600,126601,126603,126604,126605,126606,126607,126608,126609,126610,126611,126612,126613,126614,126615,126616,126617,126618,126619,126625,126626,126627,126629,126630,126631,126632,126633,126635,126636,126637,126638,126639,126640,126641,126642,126643,126644,126645,126646,126647,126648,126649,126650,126651,1114109];j.prototype.applyStyles=function(a,b){b=b||this.div;for(var c in a)a.hasOwnProperty(c)&&(b.style[c]=a[c])},j.prototype.formatStyle=function(a,b){return 0===a?0:a+b},k.prototype=o(j.prototype),k.prototype.constructor=k,l.prototype.move=function(a,b){switch(b=void 0!==b?b:this.lineHeight,a){case"+x":this.left+=b,this.right+=b;break;case"-x":this.left-=b,this.right-=b;break;case"+y":this.top+=b,this.bottom+=b;break;case"-y":this.top-=b,this.bottom-=b}},l.prototype.overlaps=function(a){return this.left<a.right&&this.right>a.left&&this.top<a.bottom&&this.bottom>a.top},l.prototype.overlapsAny=function(a){for(var b=0;b<a.length;b++)if(this.overlaps(a[b]))return!0;return!1},l.prototype.within=function(a){return this.top>=a.top&&this.bottom<=a.bottom&&this.left>=a.left&&this.right<=a.right},l.prototype.overlapsOppositeAxis=function(a,b){switch(b){case"+x":return this.left<a.left;case"-x":return this.right>a.right;case"+y":return this.top<a.top;case"-y":return this.bottom>a.bottom}},l.prototype.intersectPercentage=function(a){var b=Math.max(0,Math.min(this.right,a.right)-Math.max(this.left,a.left)),c=Math.max(0,Math.min(this.bottom,a.bottom)-Math.max(this.top,a.top)),d=b*c;return d/(this.height*this.width)},l.prototype.toCSSCompatValues=function(a){return{top:this.top-a.top,bottom:a.bottom-this.bottom,left:this.left-a.left,right:a.right-this.right,height:this.height,width:this.width}},l.getSimpleBoxPosition=function(a){var b=a.div?a.div.offsetHeight:a.tagName?a.offsetHeight:0,c=a.div?a.div.offsetWidth:a.tagName?a.offsetWidth:0,d=a.div?a.div.offsetTop:a.tagName?a.offsetTop:0;a=a.div?a.div.getBoundingClientRect():a.tagName?a.getBoundingClientRect():a;var e={left:a.left,right:a.right,top:a.top||d,height:a.height||b,bottom:a.bottom||d+(a.height||b),width:a.width||c};return e},n.StringDecoder=function(){return{decode:function(a){if(!a)return"";if("string"!=typeof a)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(a))}}},n.convertCueToDOMTree=function(a,b){return a&&b?g(a,b):null};var u=.05,v="sans-serif",w="1.5%";n.processCues=function(a,b,c){function d(a){for(var b=0;b<a.length;b++)if(a[b].hasBeenReset||!a[b].displayState)return!0;return!1}if(!a||!b||!c)return null;for(;c.firstChild;)c.removeChild(c.firstChild);var e=a.document.createElement("div");if(e.style.position="absolute",e.style.left="0",e.style.right="0",e.style.top="0",e.style.bottom="0",e.style.margin=w,c.appendChild(e),d(b)){var f=[],g=l.getSimpleBoxPosition(e),h=Math.round(g.height*u*100)/100,i={font:h+"px "+v};!function(){for(var c,d,h=0;h<b.length;h++)d=b[h],c=new k(a,d,i),e.appendChild(c.div),m(a,c,g,f),d.displayState=c.div,f.push(l.getSimpleBoxPosition(c))}()}else for(var j=0;j<b.length;j++)e.appendChild(b[j].displayState)},n.Parser=function(a,b,c){c||(c=b,b={}),b||(b={}),this.window=a,this.vttjs=b,this.state="INITIAL",this.buffer="",this.decoder=c||new TextDecoder("utf8"),this.regionList=[]},n.Parser.prototype={reportOrThrowError:function(a){if(!(a instanceof b))throw a;this.onparsingerror&&this.onparsingerror(a)},parse:function(a){function c(){for(var a=i.buffer,b=0;b<a.length&&"\r"!==a[b]&&"\n"!==a[b];)++b;var c=a.substr(0,b);return"\r"===a[b]&&++b,"\n"===a[b]&&++b,i.buffer=a.substr(b),c}function g(a){var b=new d;if(e(a,function(a,c){switch(a){case"id":b.set(a,c);break;case"width":b.percent(a,c);break;case"lines":b.integer(a,c);break;case"regionanchor":case"viewportanchor":var e=c.split(",");if(2!==e.length)break;var f=new d;if(f.percent("x",e[0]),f.percent("y",e[1]),!f.has("x")||!f.has("y"))break;b.set(a+"X",f.get("x")),b.set(a+"Y",f.get("y"));break;case"scroll":b.alt(a,c,["up"])}},/=/,/\s/),b.has("id")){var c=new(i.vttjs.VTTRegion||i.window.VTTRegion);c.width=b.get("width",100),c.lines=b.get("lines",3),c.regionAnchorX=b.get("regionanchorX",0),c.regionAnchorY=b.get("regionanchorY",100),c.viewportAnchorX=b.get("viewportanchorX",0),c.viewportAnchorY=b.get("viewportanchorY",100),c.scroll=b.get("scroll",""),i.onregion&&i.onregion(c),i.regionList.push({id:b.get("id"),region:c})}}function h(a){e(a,function(a,b){switch(a){case"Region":g(b)}},/:/)}var i=this;a&&(i.buffer+=i.decoder.decode(a,{stream:!0}));try{var j;if("INITIAL"===i.state){if(!/\r\n|\n/.test(i.buffer))return this;j=c();var k=j.match(/^WEBVTT([ \t].*)?$/);if(!k||!k[0])throw new b(b.Errors.BadSignature);i.state="HEADER"}for(var l=!1;i.buffer;){if(!/\r\n|\n/.test(i.buffer))return this;switch(l?l=!1:j=c(),i.state){case"HEADER":/:/.test(j)?h(j):j||(i.state="ID");continue;case"NOTE":j||(i.state="ID");continue;case"ID":if(/^NOTE($|[ \t])/.test(j)){i.state="NOTE";break}if(!j)continue;if(i.cue=new(i.vttjs.VTTCue||i.window.VTTCue)(0,0,""),i.state="CUE",j.indexOf("-->")===-1){i.cue.id=j;continue}case"CUE":try{f(j,i.cue,i.regionList)}catch(m){i.reportOrThrowError(m),i.cue=null,i.state="BADCUE";continue}i.state="CUETEXT";continue;case"CUETEXT":var n=j.indexOf("-->")!==-1;if(!j||n&&(l=!0)){i.oncue&&i.oncue(i.cue),i.cue=null,i.state="ID";continue}i.cue.text&&(i.cue.text+="\n"),i.cue.text+=j;continue;case"BADCUE":j||(i.state="ID");continue}}}catch(m){i.reportOrThrowError(m),"CUETEXT"===i.state&&i.cue&&i.oncue&&i.oncue(i.cue),i.cue=null,i.state="INITIAL"===i.state?"BADWEBVTT":"BADCUE"}return this},flush:function(){var a=this;try{if(a.buffer+=a.decoder.decode(),(a.cue||"HEADER"===a.state)&&(a.buffer+="\n\n",a.parse()),"INITIAL"===a.state)throw new b(b.Errors.BadSignature)}catch(c){a.reportOrThrowError(c)}return a.onflush&&a.onflush(),this}},a.WebVTT=n}(this,this.vttjs||{});
\ No newline at end of file diff --git a/addons/webinterface.default/themes/base/css/base.css b/addons/webinterface.default/themes/base/css/base.css index 55b3b0a8b5..45bb1eb6cf 100644 --- a/addons/webinterface.default/themes/base/css/base.css +++ b/addons/webinterface.default/themes/base/css/base.css @@ -34,29 +34,28 @@ fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100% @media (max-width: 767px){.hidden-xs{display:none !important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none !important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none !important}}@media (min-width: 1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}} .visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}} .visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}} -@media print{.hidden-print{display:none !important}}.shadow-z-1,.card,.snackbar,.landing-page .region-content h3,.landing-page h3.set-header{box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24)}.shadow-z-2,.well,.jumbotron,.btn-raised,.btn-group,.btn-group-vertical,.btn-group.btn-group-raised,.btn-group-vertical.btn-group-raised,.modal-content{box-shadow:0 0px 14px -5px rgba(0,0,0,0.06),0 6px 12px -6px rgba(0,0,0,0.13)}.shadow-z-2-hover,.btn:hover:not(.btn-link){box-shadow:0 3px 6px rgba(0,0,0,0.2),0 3px 6px rgba(0,0,0,0.28)}.shadow-z-3,.btn:active:not(.btn-link),.btn-raised:active:not(.btn-link),.btn-group:active:not(.btn-link),.btn-group-vertical:active:not(.btn-link),.btn-group.btn-group-raised:active:not(.btn-link),.btn-group-vertical.btn-group-raised:active:not(.btn-link){box-shadow:0 10px 20px rgba(0,0,0,0.19),0 6px 6px rgba(0,0,0,0.23)}.shadow-z-4,.btn-raised:hover,.btn-group:hover,.btn-group-vertical:hover,.btn-group.btn-group-raised:hover,.btn-group-vertical.btn-group-raised:hover{box-shadow:0 14px 28px rgba(0,0,0,0.25),0 10px 10px rgba(0,0,0,0.22)}.shadow-z-5{box-shadow:0 19px 38px rgba(0,0,0,0.3),0 15px 12px rgba(0,0,0,0.22)}body{background-color:#EEEEEE}body.inverse{background:#333333}body.inverse,body.inverse .form-control{color:rgba(255,255,255,0.84)}.well,.well .form-control,.well:not([class^="well well-material-"]),.well:not([class^="well well-material-"]) .form-control{color:rgba(0,0,0,0.84)}.well .floating-label,.well:not([class^="well well-material-"]) .floating-label{color:#7e7e7e}.well .form-control,.well:not([class^="well well-material-"]) .form-control{border-bottom-color:#7e7e7e}.well .form-control::-webkit-input-placeholder,.well:not([class^="well well-material-"]) .form-control::-webkit-input-placeholder{color:#7e7e7e}.well .form-control::-moz-placeholder,.well:not([class^="well well-material-"]) .form-control::-moz-placeholder{color:#7e7e7e;opacity:1}.well .form-control:-ms-input-placeholder,.well:not([class^="well well-material-"]) .form-control:-ms-input-placeholder{color:#7e7e7e}.well .option,.well .create,.well:not([class^="well well-material-"]) .option,.well:not([class^="well well-material-"]) .create{color:rgba(0,0,0,0.84)}[class^="well well-material-"],[class^="well well-material-"] .form-control,[class^="well well-material-"] .floating-label{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control{border-bottom-color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control::-webkit-input-placeholder{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control::-moz-placeholder{color:rgba(255,255,255,0.84);opacity:1}[class^="well well-material-"] .form-control:-ms-input-placeholder{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .option,[class^="well well-material-"] .create{color:rgba(0,0,0,0.84)}.well,.jumbotron{background-color:#fff;padding:19px;margin-bottom:20px;border-radius:2px;border:0}.well p,.jumbotron p{font-weight:300}.btn{position:relative;padding:8px 30px;border:0;margin:10px 1px;cursor:pointer;border-radius:2px;text-transform:uppercase;text-decoration:none;color:rgba(255,255,255,0.84);transition:box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);outline:none !important}.btn:hover{color:rgba(255,255,255,0.84)}.btn-link,.btn:not([class^="btn btn-"]),.btn-default{color:rgba(0,0,0,0.84)}.btn-link:hover,.btn:not([class^="btn btn-"]):hover,.btn-default:hover{color:rgba(0,0,0,0.84)}.btn:not([class^="btn btn-"]):hover,.btn-default:hover{background-color:rgba(255,255,255,0.5)}.btn-raised{transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-flat{box-shadow:none !important}.btn-flat.btn-default:hover{background:none}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus{background:#10a0cf;border-color:#10a0cf}.btn-group,.btn-group-vertical{position:relative;border-radius:4px;margin:10px 1px;transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-group.open .dropdown-toggle,.btn-group-vertical.open .dropdown-toggle{box-shadow:none}.btn-group.btn-group-raised,.btn-group-vertical.btn-group-raised{transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-group .btn,.btn-group .btn:active,.btn-group .btn-group,.btn-group-vertical .btn,.btn-group-vertical .btn:active,.btn-group-vertical .btn-group{box-shadow:none !important;margin:0}.btn-group .btn:active .caret,.btn-group-vertical .btn:active .caret{margin-left:-1px}.btn-group-flat{box-shadow:none !important}.btn-fab{margin:0;padding:15px;font-size:26px;width:56px;height:56px}.btn-fab,.btn-fab .ripple-wrapper{border-radius:100%}.btn-fab.btn-mini{width:40px;height:40px;padding:13px;font-size:15px}.btn-default{background-color:#fff}.btn-primary{background-color:#12b2e7}.btn-success{background-color:#0f9d58}.btn-info{background-color:#03a9f4}.btn-warning{background-color:#ff5722}.btn-danger{background-color:#f44336}.btn-material-red{background-color:#f44336}.btn-material-pink{background-color:#e91e63}.btn-material-purple{background-color:#9c27b0}.btn-material-deeppurple{background-color:#673ab7}.btn-material-indigo{background-color:#3f51b5}.btn-material-lightblue{background-color:#03a9f4}.btn-material-cyan{background-color:#00bcd4}.btn-material-teal{background-color:#009688}.btn-material-lightgreen{background-color:#8bc34a}.btn-material-lime{background-color:#cddc39}.btn-material-lightyellow{background-color:#ffeb3b}.btn-material-orange{background-color:#ff9800}.btn-material-deeporange{background-color:#ff5722}.btn-material-grey{background-color:#9e9e9e}.btn-material-bluegrey{background-color:#607d8b}.btn-material-brown{background-color:#795548}.btn-material-lightgrey{background-color:#ececec}.form-horizontal .checkbox{padding-top:15px}.checkbox{transform:rotate(0deg)}.checkbox label{cursor:pointer;padding-left:45px;position:relative}.checkbox label span{display:block;position:absolute;left:0px;transition-duration:0.2s}.checkbox label .check:after{display:block;position:absolute;content:"";background-color:rgba(0,0,0,0.84);left:-5px;top:-15px;height:50px;width:50px;border-radius:100%;z-index:1;opacity:0;margin:0}.checkbox label .check:before{display:block;content:"";border:2px solid rgba(0,0,0,0.84);height:20px;width:20px;transition-delay:0.2s}.checkbox input[type=checkbox]{opacity:0}.checkbox input[type=checkbox] ~ .check:before{position:absolute;top:2px;left:11px;width:18px;height:18px;border:solid 2px;border-color:#5a5a5a;animation:uncheck 300ms ease-out forwards}.checkbox input[type=checkbox]:focus ~ .check:after{opacity:0.2}.checkbox input[type=checkbox]:checked ~ .check:before{animation:check 300ms ease-out forwards}.checkbox input[type=checkbox]:not(:checked) ~ .check:after{animation:rippleOff 500ms linear forwards}.checkbox input[type=checkbox]:checked ~ .check:after{animation:rippleOn 500ms linear forwards}.checkbox:not(:hover) input[type=checkbox] ~ .check:before,.checkbox:not(:hover) input[type=checkbox] ~ .check:after{animation-duration:1ms}.checkbox input[type=checkbox][disabled]:not(:checked) ~ .check:before{opacity:0.5}.checkbox input[type=checkbox][disabled] ~ .check:after{background-color:rgba(0,0,0,0.84);transform:rotate(-45deg)}@keyframes uncheck{0%{top:-3px;left:17px;width:10px;height:21px;border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent;transform:rotate(45deg)}50%{top:14px;left:17px;width:4px;height:4px;transform:rotate(45deg);border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent}51%{border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}100%{top:1px;left:12px;width:18px;height:18px;transform:rotate(0deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}}@keyframes check{100%{top:-3px;left:17px;width:10px;height:21px;transform:rotate(45deg);border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent}51%{border-left:transparent;border-top-color:transparent}50%{top:14px;left:17px;width:4px;height:4px;transform:rotate(45deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}0%{top:1px;left:12px;width:18px;height:18px;transform:rotate(0deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}}@keyframes rippleOn{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}@keyframes rippleOff{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}.togglebutton{vertical-align:middle}.togglebutton,.togglebutton *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.togglebutton label{font-weight:400;cursor:pointer}.togglebutton label input[type=checkbox]:first-child{opacity:0;width:0;height:0}.togglebutton label input[type=checkbox]:first-child:checked+.toggle{background-color:rgba(18,178,231,0.5)}.togglebutton label input[type=checkbox]:first-child:checked+.toggle:after{background-color:#12b2e7}.togglebutton label .toggle,.togglebutton label input[type=checkbox][disabled]:first-child+.toggle{content:"";display:inline-block;width:30px;height:15px;background-color:rgba(80,80,80,0.7);border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle}.togglebutton label .toggle:after{content:"";display:inline-block;width:20px;height:20px;background-color:#F1F1F1;border-radius:20px;position:relative;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-2px;transition:left 0.3s ease, background 0.3s ease, box-shadow 0.1s ease}.togglebutton label input[type=checkbox][disabled]:first-child+.toggle:after,.togglebutton label input[type=checkbox][disabled]:checked:first-child+.toggle:after{background-color:#BDBDBD}.togglebutton label input[type=checkbox]:first-child:checked ~ .toggle:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,149,135,0.1)}.togglebutton label input[type=checkbox]:first-child ~ .toggle:active:after,.togglebutton label input[type=checkbox][disabled]:first-child ~ .toggle:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.1)}.togglebutton label input[type=checkbox]:first-child:checked+.toggle:after{left:15px}.form-horizontal .radio{margin-bottom:10px}.radio label{cursor:pointer;padding-left:45px;position:relative}.radio label span{display:block;position:absolute;left:10px;top:2px;transition-duration:0.2s}.radio label .circle{border:2px solid rgba(0,0,0,0.84);height:15px;width:15px;border-radius:100%}.radio label .check{height:15px;width:15px;border-radius:100%;background-color:rgba(0,0,0,0.84);transform:scale(0)}.radio label .check:after{display:block;position:absolute;content:"";background-color:rgba(0,0,0,0.84);left:-18px;top:-18px;height:50px;width:50px;border-radius:100%;z-index:1;opacity:0;margin:0;transform:scale(1.5)}.radio label input[type=radio]:not(:checked) ~ .check:after{animation:rippleOff 500ms}.radio label input[type=radio]:checked ~ .check:after{animation:rippleOn 500ms}.radio input[type=radio][disabled] ~ .check,.radio input[type=radio][disabled] ~ .circle{opacity:0.5}.radio input[type=radio]{display:none}.radio input[type=radio]:checked ~ .check{transform:scale(0.55)}.radio input[type=radio][disabled] ~ .circle{border-color:rgba(0,0,0,0.84)}.radio input[type=radio][disabled] ~ .check{background-color:rgba(0,0,0,0.84)}@keyframes rippleOn{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}@keyframes rippleOff{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}fieldset[disabled] .form-control,fieldset[disabled] .form-control:focus,fieldset[disabled] .form-control.focus,.form-control-wrapper .form-control,.form-control-wrapper .form-control:focus,.form-control-wrapper .form-control.focus,.form-control,.form-control:focus,.form-control.focus{padding:0;float:none;border:0;box-shadow:none;border-radius:0;background:transparent;border-bottom:1px solid #757575}fieldset[disabled] .form-control:not(textarea):not(select),fieldset[disabled] .form-control:focus:not(textarea):not(select),fieldset[disabled] .form-control.focus:not(textarea):not(select),.form-control-wrapper .form-control:not(textarea):not(select),.form-control-wrapper .form-control:focus:not(textarea):not(select),.form-control-wrapper .form-control.focus:not(textarea):not(select),.form-control:not(textarea):not(select),.form-control:focus:not(textarea):not(select),.form-control.focus:not(textarea):not(select){height:28px}fieldset[disabled] .form-control:disabled,fieldset[disabled] .form-control:focus:disabled,fieldset[disabled] .form-control.focus:disabled,.form-control-wrapper .form-control:disabled,.form-control-wrapper .form-control:focus:disabled,.form-control-wrapper .form-control.focus:disabled,.form-control:disabled,.form-control:focus:disabled,.form-control.focus:disabled{border-style:dashed}select.form-control{height:23px}select[multiple].form-control,select[multiple].form-control:focus,select[multiple].form-control.focus{height:85px}.form-control-wrapper{position:relative}.form-control-wrapper .form-control:focus,.form-control-wrapper .form-control.focus{outline:none}.form-control-wrapper .floating-label{color:#7E7E7E;font-size:14px;position:absolute;pointer-events:none;left:0px;top:5px;transition:0.2s ease all;opacity:0}.form-control-wrapper .form-control:not(.empty) ~ .floating-label{top:-10px;font-size:10px;opacity:1}.form-control-wrapper .form-control:focus:invalid ~ .floating-label,.form-control-wrapper .form-control.focus:invalid ~ .floating-label{color:#f44336}.form-control-wrapper .form-control:focus ~ .material-input:after,.form-control-wrapper .form-control.focus ~ .material-input:after{background-color:#12b2e7}.form-control-wrapper .form-control:focus:invalid ~ .material-input:before,.form-control-wrapper .form-control:focus:invalid ~ .material-input:after,.form-control-wrapper .form-control.focus:invalid ~ .material-input:before,.form-control-wrapper .form-control.focus:invalid ~ .material-input:after{background-color:#f44336}.form-control-wrapper .form-control.empty ~ .floating-label{opacity:1}.form-control-wrapper .material-input:before{position:absolute;content:"";width:100%;left:0;height:2px;background-color:#12b2e7;bottom:-1px;transform:scaleX(0);transition:transform 0s}.form-control-wrapper .form-control:focus ~ .material-input:before,.form-control-wrapper .form-control.focus ~ .material-input:before{transform:scaleX(1);transition:transform 0.2s ease-out}.form-control-wrapper .material-input:after{content:"";position:absolute;height:18px;width:100px;margin-top:-1px;top:7px;left:0;pointer-events:none;opacity:0.9;transform-origin:left}.form-control-wrapper .input-lg ~ .material-input:after,.form-control-wrapper .input-group-lg>.form-control ~ .material-input:after,.form-control-wrapper .input-group-lg>.input-group-addon ~ .material-input:after,.form-control-wrapper .input-group-lg>.input-group-btn>.btn ~ .material-input:after{height:26px}.form-control-wrapper textarea{resize:inherit}.form-control-wrapper textarea ~ .form-control-highlight{margin-top:-11px}.form-control-wrapper .form-control:focus ~ .material-input:after,.form-control-wrapper .form-control.focus ~ .material-input:after{animation:input-highlight 0.3s ease;animation-fill-mode:forwards;opacity:0}.form-control-wrapper select ~ .material-input:after{display:none}.form-group.has-warning .material-input:before,.form-group.has-warning input.form-control:focus ~ .material-input:after,.form-group.has-warning input.form-control.focus ~ .material-input:after{background:#ff5722}.form-group.has-warning .control-label,.form-group.has-warning input.form-control:not(.empty) ~ .floating-label{color:#ff5722}.form-group.has-error .material-input:before,.form-group.has-error input.form-control:focus ~ .material-input:after,.form-group.has-error input.form-control.focus ~ .material-input:after{background:#f44336}.form-group.has-error .control-label,.form-group.has-error input.form-control:not(.empty) ~ .floating-label{color:#f44336}.form-group.has-success .material-input:before,.form-group.has-success input.form-control:focus ~ .material-input:after,.form-group.has-success input.form-control.focus ~ .material-input:after{background:#0f9d58}.form-group.has-success .control-label,.form-group.has-success input.form-control:not(.empty) ~ .floating-label{color:#0f9d58}.form-group.has-info .material-input:before,.form-group.has-info input.form-control:focus ~ .material-input:after,.form-group.has-info input.form-control.focus ~ .material-input:after{background:#03a9f4}.form-group.has-info .control-label,.form-group.has-info input.form-control:not(.empty) ~ .floating-label{color:#03a9f4}.input-group .form-control-wrapper{margin-right:5px;margin-left:5px;bottom:-10px}.input-group .form-control-wrapper .form-control{float:none}.input-group .input-group-addon{border:0}.input-group .input-group-btn .btn{border-radius:4px}select.form-control{border:0;box-shadow:none;border-bottom:1px solid #757575;border-radius:0}select.form-control:focus,select.form-control.focus{box-shadow:none;border-color:#757575}@keyframes input-highlight{0%{left:20%;transform:scaleX(20%)}99%{transform:scaleX(0);left:0;opacity:1}100%{opacity:0}}.form-control-wrapper input[type=file]{opacity:0;position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}legend{border-bottom:0}.modal-content{border-radius:0;border:0}.modal-content .modal-header{border-bottom:0}.modal-content .modal-footer{border-top:0}.modal-content .modal-footer .btn+.btn{margin-bottom:10px}.list-group{border-radius:0}.list-group .list-group-item{background-color:transparent;overflow:hidden;border:0;border-radius:0;padding:0 16px}.list-group .list-group-item .row-picture,.list-group .list-group-item .row-action-primary{float:left;display:inline-block;padding-right:16px}.list-group .list-group-item .row-picture img,.list-group .list-group-item .row-picture i,.list-group .list-group-item .row-picture label,.list-group .list-group-item .row-action-primary img,.list-group .list-group-item .row-action-primary i,.list-group .list-group-item .row-action-primary label{display:block;width:56px;height:56px}.list-group .list-group-item .row-picture img,.list-group .list-group-item .row-action-primary img{background:rgba(0,0,0,0.1);padding:1px}.list-group .list-group-item .row-picture img.circle,.list-group .list-group-item .row-action-primary img.circle{border-radius:100%}.list-group .list-group-item .row-picture i,.list-group .list-group-item .row-action-primary i{background:rgba(0,0,0,0.25);border-radius:100%;text-align:center;line-height:56px;font-size:20px;color:white}.list-group .list-group-item .row-picture label,.list-group .list-group-item .row-action-primary label{margin-left:7px;margin-right:-7px;margin-top:5px;margin-bottom:-5px}.list-group .list-group-item .row-content{display:inline-block;width:calc(100% - 92px);min-height:66px}.list-group .list-group-item .row-content .action-secondary{position:absolute;right:16px;top:16px}.list-group .list-group-item .row-content .action-secondary i{font-size:20px;color:rgba(0,0,0,0.25);cursor:pointer}.list-group .list-group-item .row-content .action-secondary ~ *{max-width:calc(100% - 30px)}.list-group .list-group-item .row-content .least-content{position:absolute;right:16px;top:0px;color:rgba(0,0,0,0.54);font-size:14px}.list-group .list-group-item .list-group-item-heading{color:rgba(0,0,0,0.77);font-size:20px;line-height:29px}.list-group .list-group-separator{clear:both;overflow:hidden;margin-top:10px;margin-bottom:10px}.list-group .list-group-separator:before{content:"";width:calc(100% - 90px);border-bottom:1px solid rgba(0,0,0,0.1);float:right}.navbar{background-color:#12b2e7;border:0;border-radius:0}.navbar .navbar-brand{position:relative;height:60px;line-height:30px;color:rgba(255,255,255,0.84)}.navbar .navbar-brand:hover,.navbar .navbar-brand:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-text{color:rgba(255,255,255,0.84);margin-top:20px;margin-bottom:20px}.navbar .navbar-nav>li>a{color:rgba(255,255,255,0.84);padding-top:20px;padding-bottom:20px}.navbar .navbar-nav>li>a:hover,.navbar .navbar-nav>li>a:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-nav>.active>a,.navbar .navbar-nav>.active>a:hover,.navbar .navbar-nav>.active>a:focus{color:rgba(255,255,255,0.84);background-color:rgba(0,0,0,0.05)}.navbar .navbar-nav>.disabled>a,.navbar .navbar-nav>.disabled>a:hover,.navbar .navbar-nav>.disabled>a:focus{color:#e5e5e5;background-color:transparent}.navbar .navbar-toggle{border-color:rgba(255,255,255,0.84)}.navbar .navbar-toggle:hover,.navbar .navbar-toggle:focus{background-color:transparent}.navbar .navbar-toggle .icon-bar{background-color:rgba(255,255,255,0.84)}.navbar .navbar-collapse,.navbar .navbar-form{border-color:rgba(0,0,0,0.1)}.navbar .navbar-nav>.open>a,.navbar .navbar-nav>.open>a:hover,.navbar .navbar-nav>.open>a:focus{background-color:rgba(0,0,0,0.05);color:rgba(255,255,255,0.84)}@media (max-width: 767px){.navbar .navbar-nav .open .dropdown-menu>.dropdown-header{border:0;color:rgba(212,212,212,0.84)}.navbar .navbar-nav .open .dropdown-menu .divider{background-color:rgba(255,255,255,0.84)}.navbar .navbar-nav .open .dropdown-menu>li>a{color:rgba(255,255,255,0.84)}.navbar .navbar-nav .open .dropdown-menu>li>a:hover,.navbar .navbar-nav .open .dropdown-menu>li>a:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:rgba(255,255,255,0.84);background-color:rgba(0,0,0,0.05)}.navbar .navbar-nav .open .dropdown-menu>.disabled>a,.navbar .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#e5e5e5;background-color:transparent}}.navbar .navbar-link{color:rgba(255,255,255,0.84)}.navbar .navbar-link:hover{color:rgba(255,255,255,0.84)}.navbar .navbar-link{color:rgba(255,255,255,0.84)}.navbar .navbar-link:hover,.navbar .navbar-link:focus{color:rgba(255,255,255,0.84)}.navbar .navbar-link[disabled]:hover,.navbar .navbar-link[disabled]:focus,fieldset[disabled] .navbar .navbar-link:hover,fieldset[disabled] .navbar .navbar-link:focus{color:#e5e5e5}.navbar .navbar-form{margin-top:16px}.navbar .navbar-form .form-control-wrapper .form-control,.navbar .navbar-form .form-control{border-color:rgba(255,255,255,0.84);color:rgba(255,255,255,0.84)}.navbar .navbar-form .form-control-wrapper .material-input:before,.navbar .navbar-form .form-control-wrapper input:focus ~ .material-input:after{background-color:rgba(255,255,255,0.84)}.navbar .navbar-form ::-webkit-input-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form :-moz-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form ::-moz-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form :-ms-input-placeholder{color:rgba(255,255,255,0.84)}.navbar-inverse{background-color:#5264ae}.navbar-white{background-color:#FFF}.navbar-white .navbar-brand,.navbar-white .navbar-brand:hover,.navbar-white .navbar-brand:focus{color:rgba(0,0,0,0.84)}.navbar-white .navbar-nav>li>a{color:rgba(0,0,0,0.84)}.navbar-white .navbar-nav>li>a:hover,.navbar-white .navbar-nav>li>a:focus{color:rgba(0,0,0,0.84);background-color:transparent}.navbar-white .navbar-nav>.active>a,.navbar-white .navbar-nav>.active>a:hover,.navbar-white .navbar-nav>.active>a:focus{color:rgba(0,0,0,0.84);background-color:rgba(0,0,0,0.05)}.navbar-white .navbar-nav>.disabled>a,.navbar-white .navbar-nav>.disabled>a:hover,.navbar-white .navbar-nav>.disabled>a:focus{color:rgba(0,0,0,0.84);background-color:transparent}.navbar-white .navbar-nav>.open>a,.navbar-white .navbar-nav>.open>a:hover,.navbar-white .navbar-nav>.open>a:focus{background-color:rgba(0,0,0,0.05);color:rgba(0,0,0,0.84)}.navbar-default{background-color:#12b2e7}.navbar-primary{background-color:#12b2e7}.navbar-success{background-color:#0f9d58}.navbar-info{background-color:#03a9f4}.navbar-warning{background-color:#ff5722}.navbar-danger{background-color:#f44336}.navbar-material-red{background-color:#f44336}.navbar-material-pink{background-color:#e91e63}.navbar-material-purple{background-color:#9c27b0}.navbar-material-deeppurple{background-color:#673ab7}.navbar-material-indigo{background-color:#3f51b5}.navbar-material-lightblue{background-color:#03a9f4}.navbar-material-cyan{background-color:#00bcd4}.navbar-material-teal{background-color:#009688}.navbar-material-lightgreen{background-color:#8bc34a}.navbar-material-lime{background-color:#cddc39}.navbar-material-lightyellow{background-color:#ffeb3b}.navbar-material-orange{background-color:#ff9800}.navbar-material-deeporange{background-color:#ff5722}.navbar-material-grey{background-color:#9e9e9e}.navbar-material-bluegrey{background-color:#607d8b}.navbar-material-brown{background-color:#795548}.navbar-material-lightgrey{background-color:#ececec}.dropdown-menu{border:0;box-shadow:0 2px 5px 0 rgba(0,0,0,0.26)}.dropdown-menu .divider{background-color:rgba(229,229,229,0.12)}.dropdown-menu li{overflow:hidden;position:relative}.dropdown-menu li a:hover{background:rgba(0,0,0,0.08)}.alert{border:0px;border-radius:0}.alert a,.alert .alert-link{color:#FFFFFF}.alert-default{background-color:rgba(255,255,255,0.35);color:rgba(0,0,0,0.84)}.alert-default a,.alert-default .alert-link{color:#000000}.alert-primary{color:#FFFFFF;background-color:rgba(18,178,231,0.35);color:rgba(0,0,0,0.84)}.alert-success{color:#FFFFFF;background-color:rgba(15,157,88,0.35);color:rgba(0,0,0,0.84)}.alert-info{color:#FFFFFF;background-color:rgba(3,169,244,0.35);color:rgba(0,0,0,0.84)}.alert-warning{color:#FFFFFF;background-color:rgba(255,87,34,0.35);color:rgba(0,0,0,0.84)}.alert-danger{background-color:rgba(244,67,54,0.35);color:rgba(0,0,0,0.84)}.alert-material-red{background-color:rgba(244,67,54,0.35);color:rgba(0,0,0,0.84)}.alert-material-pink{background-color:rgba(233,30,99,0.35);color:rgba(0,0,0,0.84)}.alert-material-purple{background-color:rgba(156,39,176,0.35);color:rgba(0,0,0,0.84)}.alert-material-deeppurple{background-color:rgba(103,58,183,0.35);color:rgba(0,0,0,0.84)}.alert-material-indigo{background-color:rgba(63,81,181,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightblue{background-color:rgba(3,169,244,0.35);color:rgba(0,0,0,0.84)}.alert-material-cyan{background-color:rgba(0,188,212,0.35);color:rgba(0,0,0,0.84)}.alert-material-teal{background-color:rgba(0,150,136,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightgreen{background-color:rgba(139,195,74,0.35);color:rgba(0,0,0,0.84)}.alert-material-lime{background-color:rgba(205,220,57,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightyellow{background-color:rgba(255,235,59,0.35);color:rgba(0,0,0,0.84)}.alert-material-orange{background-color:rgba(255,152,0,0.35);color:rgba(0,0,0,0.84)}.alert-material-deeporange{background-color:rgba(255,87,34,0.35);color:rgba(0,0,0,0.84)}.alert-material-grey{background-color:rgba(158,158,158,0.35);color:rgba(0,0,0,0.84)}.alert-material-bluegrey{background-color:rgba(96,125,139,0.35);color:rgba(0,0,0,0.84)}.alert-material-brown{background-color:rgba(121,85,72,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightgrey{background-color:rgba(236,236,236,0.35);color:rgba(0,0,0,0.84)}.progress{height:4px;border-radius:0;box-shadow:none;background:#c8c8c8}.progress .progress-bar{box-shadow:none}.progress .progress-bar-default{background-color:#12b2e7}.progress .progress-bar-primary{background-color:#12b2e7}.progress .progress-bar-success{background-color:#0f9d58}.progress .progress-bar-info{background-color:#03a9f4}.progress .progress-bar-warning{background-color:#ff5722}.progress .progress-bar-danger{background-color:#f44336}.progress .progress-bar-material-red{background-color:#f44336}.progress .progress-bar-material-pink{background-color:#e91e63}.progress .progress-bar-material-purple{background-color:#9c27b0}.progress .progress-bar-material-deeppurple{background-color:#673ab7}.progress .progress-bar-material-indigo{background-color:#3f51b5}.progress .progress-bar-material-lightblue{background-color:#03a9f4}.progress .progress-bar-material-cyan{background-color:#00bcd4}.progress .progress-bar-material-teal{background-color:#009688}.progress .progress-bar-material-lightgreen{background-color:#8bc34a}.progress .progress-bar-material-lime{background-color:#cddc39}.progress .progress-bar-material-lightyellow{background-color:#ffeb3b}.progress .progress-bar-material-orange{background-color:#ff9800}.progress .progress-bar-material-deeporange{background-color:#ff5722}.progress .progress-bar-material-grey{background-color:#9e9e9e}.progress .progress-bar-material-bluegrey{background-color:#607d8b}.progress .progress-bar-material-brown{background-color:#795548}.progress .progress-bar-material-lightgrey{background-color:#ececec}.card{border-radius:2px;margin-bottom:20px}.card h1,.card h2,.card h3,.card h4,.card h5,.card h6{font-weight:100;margin:10px 0}.card .card-body{padding:15px}.card .card-actions{padding:15px;text-transform:uppercase}.card .card-actions .main{font-weight:bold}.card .card-actions a{font-size:15px;margin:0 15px 0 0}.card .card-actions a:hover{text-decoration:none}.card img{max-width:100%;max-height:100%}.card .card-footer{padding:15px;border-top:1px solid;border-color:#ececec}.card .card-footer .icon{font-size:25px;transition:ease transform 0.5s}.card .card-footer .icon:hover{text-decoration:none;transform:transform3d(0, 0, 0, -1px)}.card-default{background-color:#fff;color:#000}.card-default .card-footer,.card-default .card-header{border-color:#e6e6e6}.card-default a{color:#000}.card-primary{background-color:#12b2e7;color:#fff}.card-primary .card-footer,.card-primary .card-header{border-color:#ececec}.card-primary a{color:#fff}.card-success{background-color:#0f9d58;color:#fff}.card-success .card-footer,.card-success .card-header{border-color:#0b6e3e}.card-success a{color:#fff}.card-info{background-color:#03a9f4;color:#fff}.card-info .card-footer,.card-info .card-header{border-color:#0286c2}.card-info a{color:#fff}.card-warning{background-color:#ff5722;color:#fff}.card-warning .card-footer,.card-warning .card-header{border-color:#ff7e55}.card-warning a{color:#fff}.card-danger{background-color:#f44336;color:#fff}.card-danger .card-footer,.card-danger .card-header{border-color:#ea1c0d}.card-danger a{color:#fff}.card-material-red{background-color:#f44336;color:#fff}.card-material-red .card-footer,.card-material-red .card-header{border-color:#f77066}.card-material-red a{color:#fff}.card-material-pink{background-color:#e91e63;color:#fff}.card-material-pink .card-footer,.card-material-pink .card-header{border-color:#c1134e}.card-material-pink a{color:#fff}.card-material-purple{background-color:#9c27b0;color:#fff}.card-material-purple .card-footer,.card-material-purple .card-header{border-color:#771e86}.card-material-purple a{color:#fff}.card-material-deeppurple{background-color:#673ab7;color:#fff}.card-material-deeppurple .card-footer,.card-material-deeppurple .card-header{border-color:#8259cb}.card-material-deeppurple a{color:#fff}.card-material-indigo{background-color:#3f51b5;color:#fff}.card-material-indigo .card-footer,.card-material-indigo .card-header{border-color:#606fc7}.card-material-indigo a{color:#fff}.card-material-lightblue{background-color:#03a9f4;color:#fff}.card-material-lightblue .card-footer,.card-material-lightblue .card-header{border-color:#0286c2}.card-material-lightblue a{color:#fff}.card-material-cyan{background-color:#00bcd4;color:#fff}.card-material-cyan .card-footer,.card-material-cyan .card-header{border-color:#008fa1}.card-material-cyan a{color:#fff}.card-material-teal{background-color:#009688;color:#fff}.card-material-teal .card-footer,.card-material-teal .card-header{border-color:#00635a}.card-material-teal a{color:#fff}.card-material-lightgreen{background-color:#8bc34a;color:#fff}.card-material-lightgreen .card-footer,.card-material-lightgreen .card-header{border-color:#71a436}.card-material-lightgreen a{color:#fff}.card-material-lime{background-color:#cddc39;color:#fff}.card-material-lime .card-footer,.card-material-lime .card-header{border-color:#b2c022}.card-material-lime a{color:#fff}.card-material-lightyellow{background-color:#ffeb3b;color:#080700}.card-material-lightyellow .card-footer,.card-material-lightyellow .card-header{border-color:#ffe608}.card-material-lightyellow a{color:#080700}.card-material-orange{background-color:#ff9800;color:#fff}.card-material-orange .card-footer,.card-material-orange .card-header{border-color:#cc7a00}.card-material-orange a{color:#fff}.card-material-deeporange{background-color:#ff5722;color:#fff}.card-material-deeporange .card-footer,.card-material-deeporange .card-header{border-color:#ee3900}.card-material-deeporange a{color:#fff}.card-material-grey{background-color:#9e9e9e;color:#fff}.card-material-grey .card-footer,.card-material-grey .card-header{border-color:#858585}.card-material-grey a{color:#fff}.card-material-bluegrey{background-color:#607d8b;color:#fff}.card-material-bluegrey .card-footer,.card-material-bluegrey .card-header{border-color:#4b626d}.card-material-bluegrey a{color:#fff}.card-material-brown{background-color:#795548;color:#fff}.card-material-brown .card-footer,.card-material-brown .card-header{border-color:#996b5b}.card-material-brown a{color:#fff}.card-material-lightgrey{background-color:#ececec;color:#e6e6e6}.card-material-lightgrey .card-footer,.card-material-lightgrey .card-header{border-color:#d3d3d3}.card-material-lightgrey a{color:#e6e6e6}.text-warning{color:#ff5722}.text-primary{color:#12b2e7}.text-danger{color:#f44336}.text-success{color:#0f9d58}.text-info{color:#03a9f4}.nav-tabs{background:#12b2e7}.nav-tabs>li>a{color:#FFFFFF;border:0;margin:0}.nav-tabs>li>a:hover{background:transparent;border:0}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.open>a,.nav-tabs>li.open>a:hover{background:transparent !important;border:0 !important;color:#FFFFFF !important;font-weight:500}.nav-tabs>li.disabled>a,.nav-tabs>li.disabled>a:hover{color:rgba(255,255,255,0.5)}.popover,.tooltip-inner{background:#323232;color:#FFF;border-radius:2px}.tooltip,.tooltip.in{opacity:1}.popover.left .arrow:after,.popover.left .tooltip-arrow,.tooltip.left .arrow:after,.tooltip.left .tooltip-arrow{border-left-color:#323232}.popover.right .arrow:after,.popover.right .tooltip-arrow,.tooltip.right .arrow:after,.tooltip.right .tooltip-arrow{border-right-color:#323232}.popover.top .arrow:after,.popover.top .tooltip-arrow,.tooltip.top .arrow:after,.tooltip.top .tooltip-arrow{border-top-color:#323232}.popover.bottom .arrow:after,.popover.bottom .tooltip-arrow,.tooltip.bottom .arrow:after,.tooltip.bottom .tooltip-arrow{border-bottom-color:#323232}.icon-default{color:rgba(0,0,0,0.84)}.icon-primary{color:#12b2e7}.icon-success{color:#0f9d58}.icon-info{color:#03a9f4}.icon-warning{color:#ff5722}.icon-danger{color:#f44336}.icon-material-red{color:#f44336}.icon-material-pink{color:#e91e63}.icon-material-purple{color:#9c27b0}.icon-material-deeppurple{color:#673ab7}.icon-material-indigo{color:#3f51b5}.icon-material-lightblue{color:#03a9f4}.icon-material-cyan{color:#00bcd4}.icon-material-teal{color:#009688}.icon-material-lightgreen{color:#8bc34a}.icon-material-lime{color:#cddc39}.icon-material-lightyellow{color:#ffeb3b}.icon-material-orange{color:#ff9800}.icon-material-deeporange{color:#ff5722}.icon-material-grey{color:#9e9e9e}.icon-material-bluegrey{color:#607d8b}.icon-material-brown{color:#795548}.icon-material-lightgrey{color:#ececec}.snackbar{background-color:#323232;color:rgba(255,255,255,0.84);font-size:14px;border-radius:2px;height:0;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, padding 0 linear 0.2s, height 0 linear 0.2s;transform:translateY(200%)}.snackbar.snackbar-opened{padding:14px 15px;margin-bottom:20px;height:auto;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, height 0 linear 0.2s;transform:none}.snackbar.toast{border-radius:200px}.noUi-target,.noUi-target *{-webkit-touch-callout:none;-ms-touch-action:none;user-select:none;box-sizing:border-box}.noUi-base{width:100%;height:100%;position:relative}.noUi-origin{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-handle{position:relative;z-index:1;box-sizing:border-box}.noUi-stacking .noUi-handle{z-index:10}.noUi-stacking+.noUi-origin{*z-index:-1}.noUi-state-tap .noUi-origin{transition:left 0.3s, top 0.3s}.noUi-state-drag *{cursor:inherit !important}.noUi-horizontal{height:10px}.noUi-horizontal .noUi-handle{box-sizing:border-box;width:12px;height:12px;left:-10px;top:-5px}.noUi-horizontal.noUi-extended{padding:0 15px}.noUi-horizontal.noUi-extended .noUi-origin{right:-15px}.noUi-background{height:2px;margin:20px 0}.noUi-origin{margin:0;border-radius:0;height:2px;background:#c8c8c8}.noUi-origin[style^="left: 0"] .noUi-handle{background-color:#fff;border:2px solid #c8c8c8}.noUi-target{border-radius:2px}.noUi-handle{border-radius:100%;cursor:default;transition:all 0.2s ease-out;border:1px solid}.noUi-horizontal{height:2px;margin:15px 0}[disabled].noUi-slider{opacity:0.5}[disabled] .noUi-handle{cursor:not-allowed}.slider{background:#c8c8c8}.withripple{position:relative}.ripple-wrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:2px}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:rgba(0,0,0,0.05);transform:scale(1);transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{transition:opacity 0.15s ease-in 0s,transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;opacity:1}.ripple.ripple-out{transition:opacity 0.1s linear 0s !important;opacity:0}.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-user-select:none;-ms-touch-action:none;-ms-user-select:none;-moz-user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base{width:100%;height:100%;position:relative}.noUi-origin{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-handle{position:relative;z-index:1}.noUi-stacking .noUi-handle{z-index:10}.noUi-stacking+.noUi-origin{*z-index:-1}.noUi-state-tap .noUi-origin{-webkit-transition:left 0.3s, top 0.3s;transition:left 0.3s, top 0.3s}.noUi-state-drag *{cursor:inherit !important}.noUi-base{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}.noUi-connect{-webkit-transition:background 450ms;transition:background 450ms}.noUi-dragable{cursor:w-resize}.noUi-vertical .noUi-dragable{cursor:n-resize}[disabled] .noUi-handle{cursor:not-allowed}.xbbcode-b{font-weight:bold}.xbbcode-center{margin-left:auto;margin-right:auto;display:block;text-align:center}.xbbcode-code{white-space:pre-wrap;font-family:monospace}.xbbcode-i{font-style:italic}.xbbcode-justify{display:block;text-align:justify}.xbbcode-left{display:block;text-align:left}.xbbcode-right{display:block;text-align:right}.xbbcode-s{text-decoration:line-through}.xbbcode-size-4{font-size:4px}.xbbcode-size-5{font-size:5px}.xbbcode-size-6{font-size:6px}.xbbcode-size-7{font-size:7px}.xbbcode-size-8{font-size:8px}.xbbcode-size-9{font-size:9px}.xbbcode-size-10{font-size:10px}.xbbcode-size-11{font-size:11px}.xbbcode-size-12{font-size:12px}.xbbcode-size-13{font-size:13px}.xbbcode-size-14{font-size:14px}.xbbcode-size-15{font-size:15px}.xbbcode-size-16{font-size:16px}.xbbcode-size-17{font-size:17px}.xbbcode-size-18{font-size:18px}.xbbcode-size-19{font-size:19px}.xbbcode-size-20{font-size:20px}.xbbcode-size-21{font-size:21px}.xbbcode-size-22{font-size:22px}.xbbcode-size-23{font-size:23px}.xbbcode-size-24{font-size:24px}.xbbcode-size-25{font-size:25px}.xbbcode-size-26{font-size:26px}.xbbcode-size-27{font-size:27px}.xbbcode-size-28{font-size:28px}.xbbcode-size-29{font-size:29px}.xbbcode-size-30{font-size:30px}.xbbcode-size-31{font-size:31px}.xbbcode-size-32{font-size:32px}.xbbcode-size-33{font-size:33px}.xbbcode-size-34{font-size:34px}.xbbcode-size-35{font-size:35px}.xbbcode-size-36{font-size:36px}.xbbcode-size-37{font-size:37px}.xbbcode-size-38{font-size:38px}.xbbcode-size-39{font-size:39px}.xbbcode-size-40{font-size:40px}.xbbcode-u{text-decoration:underline}.xbbcode-table{border-collapse:collapse}.xbbcode-table,.xbbcode-th,.xbbcode-td{border:1px solid #666}*,*:before,*:after{-webkit-box-sizing:"border-box";-moz-box-sizing:"border-box";box-sizing:"border-box"}img,video{max-width:100%;height:auto}.youtube-list .flat-btn,.filters-container .filter-btn,.filters-container .filter-btn:before,.local-playlist-list .region-first .new-list,.local-playlist-list .region-first .new-list:before,.player .controls-primary .control,.player .controls-secondary .control,.player .slider-bar,.set-page .entity-set .more a,.set-page .entity-set .more a:before,.imdblink,.imdblink:before,.btn-flat-play,.btn-flat-play:before,.btn-flat-add,.btn-flat-add:before,.btn-flat-stream,.btn-flat-stream:before,.btn-flat-download,.btn-flat-download:before,.btn-flat-more,.btn-flat-more:before,.btn-flat-watched,.btn-flat-watched:before{-webkit-transition:0.3s all linear;-o-transition:0.3s all linear;transition:0.3s all linear}@-moz-keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}@-webkit-keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}@keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}#files-container .loading-box{-webkit-animation:none;-o-animation:none;animation:none}@-moz-keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}@-webkit-keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}@keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}.filters-container .options-search-wrapper,.search-box{position:relative;padding-right:1em}.filters-container .options-search-wrapper:before,.search-box:before{content:"\e65f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .options-search-wrapper:before,.search-box:before{top:8px;left:6px;position:absolute;z-index:20;font-size:130%;opacity:0.8}.filters-container .options-search-wrapper input,.search-box input{color:#666;border:none;width:100%;padding:0.5em;padding-left:2em;background:rgba(255,255,255,0.5);margin-bottom:1em}.filters-container .options-search-wrapper input:focus,.search-box input:focus{background:rgba(255,255,255,0.9);outline:none}.card-detail .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.landing-page .landing-section,.region-content{position:relative;padding:12px 12px 30px 12px}.with-header .landing-page .landing-section,.landing-page .with-header .landing-section,.with-header .region-content{padding:10px 20px 50px 20px}.edit-form .form-tabs,.form-imageselect__tabs,.folder-layout .folder-container,#modal-window.style-edit-form .form-content-region,.form-imageselect__thumbs,.form-imageselect__loader,.youtube-list li,form .inline-list,.help--page .help--overview--report ul li,.details-header .region-details-top,.content-container.with-sidebar,.section-content,.kodi-remote .secondary-controls,.icon-browser ul{*zoom:1}.edit-form .form-tabs:after,.form-imageselect__tabs:after,.folder-layout .folder-container:after,#modal-window.style-edit-form .form-content-region:after,.form-imageselect__thumbs:after,.form-imageselect__loader:after,.youtube-list li:after,form .inline-list:after,.help--page .help--overview--report ul li:after,.details-header .region-details-top:after,.content-container.with-sidebar:after,.section-content:after,.kodi-remote .secondary-controls:after,.icon-browser ul:after{content:"";display:table;clear:both}.help--page .region-content-wrapper h2,.help--page .region-content-wrapper h3,.help--page .region-content-wrapper h4{margin-top:1.5em}.help--page .region-content-wrapper h2{font-size:1.6em;font-weight:bold;border-bottom:1px dotted #ddd;padding-bottom:0.5em;margin-top:2em}.help--page .region-content-wrapper h3{font-size:1.3em;color:#666;margin-bottom:1em}.help--page .region-content-wrapper h4{font-size:1.2em}.help--page .region-content-wrapper p,.help--page .region-content-wrapper li{line-height:1.8}.help--page .region-content-wrapper ul,.help--page .region-content-wrapper ol{padding-left:1.5em}.help--page .region-content-wrapper ul li,.help--page .region-content-wrapper ol li{list-style:disc;margin:0.5em 0}.help--page .region-content-wrapper ol li{list-style-type:decimal}.help--page .region-content-wrapper code{border:1px solid rgba(186,193,200,0.33);background:rgba(221,221,221,0.5);color:#2b2f30}.help--page .region-content-wrapper code:hover{color:#12b2e7;border-color:#12b2e7}.help--page .region-content-wrapper pre{border:1px dashed #bac1c8;margin:1em;margin-left:0}.help--page .region-content-wrapper pre code{background:none;border:none}.help--page .region-content-wrapper pre code:hover{color:inherit;border-color:inherit}.help--page .region-content-wrapper img{width:100%;max-width:1000px}.options-list,.mobile-menu{margin:0;padding:0}.options-list li,.mobile-menu li{margin:0;padding:0;list-style:none}.sidebar-section h3,.browser-page .region-first h3,.filters-container h3,.local-playlist-list .region-first h3,.modal .playlist-selection-list h3,.region-first .nav-sub h3{font-size:15px;text-transform:uppercase;margin:1em 0;color:#888;font-weight:bold}.text-dim,.folder-layout .empty--page-content{opacity:0.4;font-size:0.85em}.landing-page .region-content h3,.landing-page h3.set-header{background:#fff;padding:1em 1em;margin:0;font-size:18px;position:relative}.empty-result h2,.search-no-result{text-align:center;margin-top:10%;font-size:1.8em;color:#a8a7a6}.edit-form .form-tabs,.form-imageselect__tabs{background:#ddd;margin-bottom:1em;padding:0.5em 0.5em 0}.edit-form .form-tabs li,.form-imageselect__tabs li{cursor:pointer;float:left;padding:0.5em 1em}.edit-form .form-tabs li.active,.form-imageselect__tabs li.active{background:#fff;color:#12b2e7}.edit-form .form-tabs li:hover,.form-imageselect__tabs li:hover{color:#12b2e7}.card-grid--square .card{color:#888;width:159px;height:216px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--square .card a{color:#888}.card-grid--square .card .title a{color:#2b2f30}.card-grid--square .card .subtitle{font-size:85%;margin-top:5px}.card-grid--square .card .dropdown i,.card-grid--square .card .actions li,.card-grid--square .card .play{color:rgba(255,255,255,0.8)}.card-grid--square .card .dropdown i:hover,.card-grid--square .card .actions li:hover,.card-grid--square .card .play:hover{color:#fff}.card-grid--square .card .record{color:rgba(255,255,255,0.8)}.card-grid--square .card .record:hover{color:#bf0a07}.card-grid--square .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--square .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:159px;height:159px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--square .card .artwork img{display:block;vertical-align:middle;width:159px;margin-top:0}.card-grid--square .card .artwork .thumb{width:159px;height:159px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--square .card .artwork a{display:block}.card-grid--square .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:216px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--square .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--square .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--square .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--square .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--square .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--square .card .watched,.card-grid--square .thumbs-page .card .watched{display:none}.card-grid--square .is-watched.card .watched{color:#12b2e7}.card-grid--square .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--square .card .meta{position:relative;padding:8px 10px;width:159px}.card-grid--square .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--square .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--square .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--square .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--square .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--square .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--square .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .dropdown{top:5px;right:0;position:absolute}.card-grid--square .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--square .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--square .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--square .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--square .card .actions .thumbs,.card-grid--square .disable-thumbs .card .actions .thumbs{display:none}.card-grid--square .card .actions li{float:left;margin-left:3px}.card-grid--square .card .actions li:before{display:table-cell !important}.card-grid--square .card:hover .artwork .thumb:after{opacity:1}.card-grid--square .card:hover .actions,.card-grid--square .card:hover .dropdown i,.card-grid--square .card:hover .play{display:table}.card-grid--square .card:hover .record{display:table}.card-grid--square .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--square .selected.card,.card-grid--square .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--square .selected.card:before,.card-grid--square .active-player-local .selected.card:before{border-color:#db2464}.card-grid--square .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--square .selected.card .current-progress{display:none}.card-grid--square .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--square .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--wide .card{color:#888;width:276px;height:170px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--wide .card a{color:#888}.card-grid--wide .card .title a{color:#2b2f30}.card-grid--wide .card .subtitle{font-size:85%;margin-top:5px}.card-grid--wide .card .dropdown i,.card-grid--wide .card .actions li,.card-grid--wide .card .play{color:rgba(255,255,255,0.8)}.card-grid--wide .card .dropdown i:hover,.card-grid--wide .card .actions li:hover,.card-grid--wide .card .play:hover{color:#fff}.card-grid--wide .card .record{color:rgba(255,255,255,0.8)}.card-grid--wide .card .record:hover{color:#bf0a07}.card-grid--wide .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--wide .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:276px;height:138px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--wide .card .artwork img{display:block;vertical-align:middle;width:276px;margin-top:20%}.card-grid--wide .card .artwork .thumb{width:276px;height:138px;background-position:50% 20%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--wide .card .artwork a{display:block}.card-grid--wide .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:170px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--wide .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--wide .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--wide .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--wide .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--wide .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--wide .card .watched,.card-grid--wide .thumbs-page .card .watched{display:none}.card-grid--wide .is-watched.card .watched{color:#12b2e7}.card-grid--wide .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--wide .card .meta{position:relative;padding:8px 10px;width:276px}.card-grid--wide .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--wide .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--wide .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--wide .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--wide .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--wide .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--wide .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .dropdown{top:5px;right:0;position:absolute}.card-grid--wide .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--wide .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--wide .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--wide .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--wide .card .actions .thumbs,.card-grid--wide .disable-thumbs .card .actions .thumbs{display:none}.card-grid--wide .card .actions li{float:left;margin-left:3px}.card-grid--wide .card .actions li:before{display:table-cell !important}.card-grid--wide .card:hover .artwork .thumb:after{opacity:1}.card-grid--wide .card:hover .actions,.card-grid--wide .card:hover .dropdown i,.card-grid--wide .card:hover .play{display:table}.card-grid--wide .card:hover .record{display:table}.card-grid--wide .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--wide .selected.card,.card-grid--wide .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--wide .selected.card:before,.card-grid--wide .active-player-local .selected.card:before{border-color:#db2464}.card-grid--wide .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--wide .selected.card .current-progress{display:none}.card-grid--wide .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--wide .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--episode .card{color:#888;width:275px;height:196px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--episode .card a{color:#888}.card-grid--episode .card .title a{color:#2b2f30}.card-grid--episode .card .subtitle{font-size:85%;margin-top:5px}.card-grid--episode .card .dropdown i,.card-grid--episode .card .actions li,.card-grid--episode .card .play{color:rgba(255,255,255,0.8)}.card-grid--episode .card .dropdown i:hover,.card-grid--episode .card .actions li:hover,.card-grid--episode .card .play:hover{color:#fff}.card-grid--episode .card .record{color:rgba(255,255,255,0.8)}.card-grid--episode .card .record:hover{color:#bf0a07}.card-grid--episode .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--episode .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:275px;height:138px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--episode .card .artwork img{display:block;vertical-align:middle;width:275px;margin-top:0}.card-grid--episode .card .artwork .thumb{width:275px;height:138px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--episode .card .artwork a{display:block}.card-grid--episode .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:196px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--episode .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--episode .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--episode .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--episode .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--episode .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--episode .card .watched,.card-grid--episode .thumbs-page .card .watched{display:none}.card-grid--episode .is-watched.card .watched{color:#12b2e7}.card-grid--episode .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--episode .card .meta{position:relative;padding:8px 10px;width:275px}.card-grid--episode .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--episode .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--episode .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--episode .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--episode .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--episode .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--episode .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--episode .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--episode .card .dropdown{top:5px;right:0;position:absolute}.card-grid--episode .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--episode .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--episode .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--episode .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--episode .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--episode .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--episode .card .actions .thumbs,.card-grid--episode .disable-thumbs .card .actions .thumbs{display:none}.card-grid--episode .card .actions li{float:left;margin-left:3px}.card-grid--episode .card .actions li:before{display:table-cell !important}.card-grid--episode .card:hover .artwork .thumb:after{opacity:1}.card-grid--episode .card:hover .actions,.card-grid--episode .card:hover .dropdown i,.card-grid--episode .card:hover .play{display:table}.card-grid--episode .card:hover .record{display:table}.card-grid--episode .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--episode .selected.card,.card-grid--episode .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--episode .selected.card:before,.card-grid--episode .active-player-local .selected.card:before{border-color:#db2464}.card-grid--episode .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--episode .selected.card .current-progress{display:none}.card-grid--episode .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--episode .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--tall .card{color:#888;width:159px;height:300px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--tall .card a{color:#888}.card-grid--tall .card .title a{color:#2b2f30}.card-grid--tall .card .subtitle{font-size:85%;margin-top:5px}.card-grid--tall .card .dropdown i,.card-grid--tall .card .actions li,.card-grid--tall .card .play{color:rgba(255,255,255,0.8)}.card-grid--tall .card .dropdown i:hover,.card-grid--tall .card .actions li:hover,.card-grid--tall .card .play:hover{color:#fff}.card-grid--tall .card .record{color:rgba(255,255,255,0.8)}.card-grid--tall .card .record:hover{color:#bf0a07}.card-grid--tall .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--tall .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:159px;height:235px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--tall .card .artwork img{display:block;vertical-align:middle;width:159px;margin-top:0}.card-grid--tall .card .artwork .thumb{width:159px;height:235px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--tall .card .artwork a{display:block}.card-grid--tall .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:300px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--tall .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--tall .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--tall .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--tall .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--tall .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--tall .card .watched,.card-grid--tall .thumbs-page .card .watched{display:none}.card-grid--tall .is-watched.card .watched{color:#12b2e7}.card-grid--tall .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--tall .card .meta{position:relative;padding:8px 10px;width:159px}.card-grid--tall .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--tall .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--tall .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--tall .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--tall .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--tall .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--tall .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .dropdown{top:5px;right:0;position:absolute}.card-grid--tall .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--tall .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--tall .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--tall .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--tall .card .actions .thumbs,.card-grid--tall .disable-thumbs .card .actions .thumbs{display:none}.card-grid--tall .card .actions li{float:left;margin-left:3px}.card-grid--tall .card .actions li:before{display:table-cell !important}.card-grid--tall .card:hover .artwork .thumb:after{opacity:1}.card-grid--tall .card:hover .actions,.card-grid--tall .card:hover .dropdown i,.card-grid--tall .card:hover .play{display:table}.card-grid--tall .card:hover .record{display:table}.card-grid--tall .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--tall .selected.card,.card-grid--tall .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--tall .selected.card:before,.card-grid--tall .active-player-local .selected.card:before{border-color:#db2464}.card-grid--tall .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--tall .selected.card .current-progress{display:none}.card-grid--tall .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--tall .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--square .card,.card-grid--wide .card,.card-grid--episode .card,.card-grid--tall .card{display:inline-block}body{background:#fff}*{box-sizing:border-box}img{width:100%;max-width:auto;height:auto}ul,ol{margin:0;padding:0}ul li,ol li{margin:0;padding:0;list-style:none}a{color:#12b2e7;cursor:pointer}.hidden{display:none}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:inherit}.form-control-wrapper textarea,.form-control-wrapper textarea.form-control,textarea,textarea.form-control{resize:vertical;height:auto !important}@font-face{font-family:"Material-Design-Icons";src:url("../fonts/material/Material-Design-Icons.eot");src:url("../fonts/material/Material-Design-Icons.eot?#iefix") format("embedded-opentype"),url("../fonts/material/Material-Design-Icons.woff") format("woff"),url("../fonts/material/Material-Design-Icons.ttf") format("truetype");font-weight:normal;font-style:normal}.mdi-action-3d-rotation:before{content:"\e600"}.mdi-action-accessibility:before{content:"\e601"}.mdi-action-account-balance:before{content:"\e602"}.mdi-action-account-balance-wallet:before{content:"\e603"}.mdi-action-account-box:before{content:"\e604"}.mdi-action-account-child:before{content:"\e605"}.mdi-action-account-circle:before{content:"\e606"}.mdi-action-add-shopping-cart:before{content:"\e607"}.mdi-action-alarm:before{content:"\e608"}.mdi-action-alarm-add:before{content:"\e609"}.mdi-action-alarm-off:before{content:"\e60a"}.mdi-action-alarm-on:before{content:"\e60b"}.mdi-action-android:before{content:"\e60c"}.mdi-action-announcement:before{content:"\e60d"}.mdi-action-aspect-ratio:before{content:"\e60e"}.mdi-action-assessment:before{content:"\e60f"}.mdi-action-assignment:before{content:"\e610"}.mdi-action-assignment-ind:before{content:"\e611"}.mdi-action-assignment-late:before{content:"\e612"}.mdi-action-assignment-return:before{content:"\e613"}.mdi-action-assignment-returned:before{content:"\e614"}.mdi-action-assignment-turned-in:before{content:"\e615"}.mdi-action-autorenew:before{content:"\e616"}.mdi-action-backup:before{content:"\e617"}.mdi-action-book:before{content:"\e618"}.mdi-action-bookmark:before{content:"\e619"}.mdi-action-bookmark-outline:before{content:"\e61a"}.mdi-action-bug-report:before{content:"\e61b"}.mdi-action-cached:before{content:"\e61c"}.mdi-action-class:before{content:"\e61d"}.mdi-action-credit-card:before{content:"\e61e"}.mdi-action-dashboard:before{content:"\e61f"}.mdi-action-delete:before{content:"\e620"}.mdi-action-description:before{content:"\e621"}.mdi-action-dns:before{content:"\e622"}.mdi-action-done:before{content:"\e623"}.mdi-action-done-all:before{content:"\e624"}.mdi-action-event:before{content:"\e625"}.mdi-action-exit-to-app:before{content:"\e626"}.mdi-action-explore:before{content:"\e627"}.mdi-action-extension:before{content:"\e628"}.mdi-action-face-unlock:before{content:"\e629"}.mdi-action-favorite:before{content:"\e62a"}.mdi-action-favorite-outline:before{content:"\e62b"}.mdi-action-find-in-page:before{content:"\e62c"}.mdi-action-find-replace:before{content:"\e62d"}.mdi-action-flip-to-back:before{content:"\e62e"}.mdi-action-flip-to-front:before{content:"\e62f"}.mdi-action-get-app:before{content:"\e630"}.mdi-action-grade:before{content:"\e631"}.mdi-action-group-work:before{content:"\e632"}.mdi-action-help:before{content:"\e633"}.mdi-action-highlight-remove:before{content:"\e634"}.mdi-action-history:before{content:"\e635"}.mdi-action-home:before{content:"\e636"}.mdi-action-https:before{content:"\e637"}.mdi-action-info:before{content:"\e638"}.mdi-action-info-outline:before{content:"\e639"}.mdi-action-input:before{content:"\e63a"}.mdi-action-invert-colors:before{content:"\e63b"}.mdi-action-label:before{content:"\e63c"}.mdi-action-label-outline:before{content:"\e63d"}.mdi-action-language:before{content:"\e63e"}.mdi-action-launch:before{content:"\e63f"}.mdi-action-list:before{content:"\e640"}.mdi-action-lock:before{content:"\e641"}.mdi-action-lock-open:before{content:"\e642"}.mdi-action-lock-outline:before{content:"\e643"}.mdi-action-loyalty:before{content:"\e644"}.mdi-action-markunread-mailbox:before{content:"\e645"}.mdi-action-note-add:before{content:"\e646"}.mdi-action-open-in-browser:before{content:"\e647"}.mdi-action-open-in-new:before{content:"\e648"}.mdi-action-open-with:before{content:"\e649"}.mdi-action-pageview:before{content:"\e64a"}.mdi-action-payment:before{content:"\e64b"}.mdi-action-perm-camera-mic:before{content:"\e64c"}.mdi-action-perm-contact-cal:before{content:"\e64d"}.mdi-action-perm-data-setting:before{content:"\e64e"}.mdi-action-perm-device-info:before{content:"\e64f"}.mdi-action-perm-identity:before{content:"\e650"}.mdi-action-perm-media:before{content:"\e651"}.mdi-action-perm-phone-msg:before{content:"\e652"}.mdi-action-perm-scan-wifi:before{content:"\e653"}.mdi-action-picture-in-picture:before{content:"\e654"}.mdi-action-polymer:before{content:"\e655"}.mdi-action-print:before{content:"\e656"}.mdi-action-query-builder:before{content:"\e657"}.mdi-action-question-answer:before{content:"\e658"}.mdi-action-receipt:before{content:"\e659"}.mdi-action-redeem:before{content:"\e65a"}.mdi-action-report-problem:before{content:"\e65b"}.mdi-action-restore:before{content:"\e65c"}.mdi-action-room:before{content:"\e65d"}.mdi-action-schedule:before{content:"\e65e"}.mdi-action-search:before{content:"\e65f"}.mdi-action-settings:before{content:"\e660"}.mdi-action-settings-applications:before{content:"\e661"}.mdi-action-settings-backup-restore:before{content:"\e662"}.mdi-action-settings-bluetooth:before{content:"\e663"}.mdi-action-settings-cell:before{content:"\e664"}.mdi-action-settings-display:before{content:"\e665"}.mdi-action-settings-ethernet:before{content:"\e666"}.mdi-action-settings-input-antenna:before{content:"\e667"}.mdi-action-settings-input-component:before{content:"\e668"}.mdi-action-settings-input-composite:before{content:"\e669"}.mdi-action-settings-input-hdmi:before{content:"\e66a"}.mdi-action-settings-input-svideo:before{content:"\e66b"}.mdi-action-settings-overscan:before{content:"\e66c"}.mdi-action-settings-phone:before{content:"\e66d"}.mdi-action-settings-power:before{content:"\e66e"}.mdi-action-settings-remote:before{content:"\e66f"}.mdi-action-settings-voice:before{content:"\e670"}.mdi-action-shop:before{content:"\e671"}.mdi-action-shopping-basket:before{content:"\e672"}.mdi-action-shopping-cart:before{content:"\e673"}.mdi-action-shop-two:before{content:"\e674"}.mdi-action-speaker-notes:before{content:"\e675"}.mdi-action-spellcheck:before{content:"\e676"}.mdi-action-star-rate:before{content:"\e677"}.mdi-action-stars:before{content:"\e678"}.mdi-action-store:before{content:"\e679"}.mdi-action-subject:before{content:"\e67a"}.mdi-action-swap-horiz:before{content:"\e67b"}.mdi-action-swap-vert:before{content:"\e67c"}.mdi-action-swap-vert-circle:before{content:"\e67d"}.mdi-action-system-update-tv:before{content:"\e67e"}.mdi-action-tab:before{content:"\e67f"}.mdi-action-tab-unselected:before{content:"\e680"}.mdi-action-theaters:before{content:"\e681"}.mdi-action-thumb-down:before{content:"\e682"}.mdi-action-thumbs-up-down:before{content:"\e683"}.mdi-action-thumb-up:before{content:"\e684"}.mdi-action-toc:before{content:"\e685"}.mdi-action-today:before{content:"\e686"}.mdi-action-track-changes:before{content:"\e687"}.mdi-action-translate:before{content:"\e688"}.mdi-action-trending-down:before{content:"\e689"}.mdi-action-trending-neutral:before{content:"\e68a"}.mdi-action-trending-up:before{content:"\e68b"}.mdi-action-turned-in:before{content:"\e68c"}.mdi-action-turned-in-not:before{content:"\e68d"}.mdi-action-verified-user:before{content:"\e68e"}.mdi-action-view-agenda:before{content:"\e68f"}.mdi-action-view-array:before{content:"\e690"}.mdi-action-view-carousel:before{content:"\e691"}.mdi-action-view-column:before{content:"\e692"}.mdi-action-view-day:before{content:"\e693"}.mdi-action-view-headline:before{content:"\e694"}.mdi-action-view-list:before{content:"\e695"}.mdi-action-view-module:before{content:"\e696"}.mdi-action-view-quilt:before{content:"\e697"}.mdi-action-view-stream:before{content:"\e698"}.mdi-action-view-week:before{content:"\e699"}.mdi-action-visibility:before{content:"\e69a"}.mdi-action-visibility-off:before{content:"\e69b"}.mdi-action-wallet-giftcard:before{content:"\e69c"}.mdi-action-wallet-membership:before{content:"\e69d"}.mdi-action-wallet-travel:before{content:"\e69e"}.mdi-action-work:before{content:"\e69f"}.mdi-alert-error:before{content:"\e6a0"}.mdi-alert-warning:before{content:"\e6a1"}.mdi-av-album:before{content:"\e6a2"}.mdi-av-timer:before{content:"\e6a3"}.mdi-av-closed-caption:before{content:"\e6a4"}.mdi-av-equalizer:before{content:"\e6a5"}.mdi-av-explicit:before{content:"\e6a6"}.mdi-av-fast-forward:before{content:"\e6a7"}.mdi-av-fast-rewind:before{content:"\e6a8"}.mdi-av-games:before{content:"\e6a9"}.mdi-av-hearing:before{content:"\e6aa"}.mdi-av-high-quality:before{content:"\e6ab"}.mdi-av-loop:before{content:"\e6ac"}.mdi-av-mic:before{content:"\e6ad"}.mdi-av-mic-none:before{content:"\e6ae"}.mdi-av-mic-off:before{content:"\e6af"}.mdi-av-movie:before{content:"\e6b0"}.mdi-av-my-library-add:before{content:"\e6b1"}.mdi-av-my-library-books:before{content:"\e6b2"}.mdi-av-my-library-music:before{content:"\e6b3"}.mdi-av-new-releases:before{content:"\e6b4"}.mdi-av-not-interested:before{content:"\e6b5"}.mdi-av-pause:before{content:"\e6b6"}.mdi-av-pause-circle-fill:before{content:"\e6b7"}.mdi-av-pause-circle-outline:before{content:"\e6b8"}.mdi-av-play-arrow:before{content:"\e6b9"}.mdi-av-play-circle-fill:before{content:"\e6ba"}.mdi-av-play-circle-outline:before{content:"\e6bb"}.mdi-av-playlist-add:before{content:"\e6bc"}.mdi-av-play-shopping-bag:before{content:"\e6bd"}.mdi-av-queue:before{content:"\e6be"}.mdi-av-queue-music:before{content:"\e6bf"}.mdi-av-radio:before{content:"\e6c0"}.mdi-av-recent-actors:before{content:"\e6c1"}.mdi-av-repeat:before{content:"\e6c2"}.mdi-av-repeat-one:before{content:"\e6c3"}.mdi-av-replay:before{content:"\e6c4"}.mdi-av-shuffle:before{content:"\e6c5"}.mdi-av-skip-next:before{content:"\e6c6"}.mdi-av-skip-previous:before{content:"\e6c7"}.mdi-av-snooze:before{content:"\e6c8"}.mdi-av-stop:before{content:"\e6c9"}.mdi-av-subtitles:before{content:"\e6ca"}.mdi-av-surround-sound:before{content:"\e6cb"}.mdi-av-videocam:before{content:"\e6cc"}.mdi-av-videocam-off:before{content:"\e6cd"}.mdi-av-video-collection:before{content:"\e6ce"}.mdi-av-volume-down:before{content:"\e6cf"}.mdi-av-volume-mute:before{content:"\e6d0"}.mdi-av-volume-off:before{content:"\e6d1"}.mdi-av-volume-up:before{content:"\e6d2"}.mdi-av-web:before{content:"\e6d3"}.mdi-communication-business:before{content:"\e6d4"}.mdi-communication-call:before{content:"\e6d5"}.mdi-communication-call-end:before{content:"\e6d6"}.mdi-communication-call-made:before{content:"\e6d7"}.mdi-communication-call-merge:before{content:"\e6d8"}.mdi-communication-call-missed:before{content:"\e6d9"}.mdi-communication-call-received:before{content:"\e6da"}.mdi-communication-call-split:before{content:"\e6db"}.mdi-communication-chat:before{content:"\e6dc"}.mdi-communication-clear-all:before{content:"\e6dd"}.mdi-communication-comment:before{content:"\e6de"}.mdi-communication-contacts:before{content:"\e6df"}.mdi-communication-dialer-sip:before{content:"\e6e0"}.mdi-communication-dialpad:before{content:"\e6e1"}.mdi-communication-dnd-on:before{content:"\e6e2"}.mdi-communication-email:before{content:"\e6e3"}.mdi-communication-forum:before{content:"\e6e4"}.mdi-communication-import-export:before{content:"\e6e5"}.mdi-communication-invert-colors-off:before{content:"\e6e6"}.mdi-communication-invert-colors-on:before{content:"\e6e7"}.mdi-communication-live-help:before{content:"\e6e8"}.mdi-communication-location-off:before{content:"\e6e9"}.mdi-communication-location-on:before{content:"\e6ea"}.mdi-communication-message:before{content:"\e6eb"}.mdi-communication-messenger:before{content:"\e6ec"}.mdi-communication-no-sim:before{content:"\e6ed"}.mdi-communication-phone:before{content:"\e6ee"}.mdi-communication-portable-wifi-off:before{content:"\e6ef"}.mdi-communication-quick-contacts-dialer:before{content:"\e6f0"}.mdi-communication-quick-contacts-mail:before{content:"\e6f1"}.mdi-communication-ring-volume:before{content:"\e6f2"}.mdi-communication-stay-current-landscape:before{content:"\e6f3"}.mdi-communication-stay-current-portrait:before{content:"\e6f4"}.mdi-communication-stay-primary-landscape:before{content:"\e6f5"}.mdi-communication-stay-primary-portrait:before{content:"\e6f6"}.mdi-communication-swap-calls:before{content:"\e6f7"}.mdi-communication-textsms:before{content:"\e6f8"}.mdi-communication-voicemail:before{content:"\e6f9"}.mdi-communication-vpn-key:before{content:"\e6fa"}.mdi-content-add:before{content:"\e6fb"}.mdi-content-add-box:before{content:"\e6fc"}.mdi-content-add-circle:before{content:"\e6fd"}.mdi-content-add-circle-outline:before{content:"\e6fe"}.mdi-content-archive:before{content:"\e6ff"}.mdi-content-backspace:before{content:"\e700"}.mdi-content-block:before{content:"\e701"}.mdi-content-clear:before{content:"\e702"}.mdi-content-content-copy:before{content:"\e703"}.mdi-content-content-cut:before{content:"\e704"}.mdi-content-content-paste:before{content:"\e705"}.mdi-content-create:before{content:"\e706"}.mdi-content-drafts:before{content:"\e707"}.mdi-content-filter-list:before{content:"\e708"}.mdi-content-flag:before{content:"\e709"}.mdi-content-forward:before{content:"\e70a"}.mdi-content-gesture:before{content:"\e70b"}.mdi-content-inbox:before{content:"\e70c"}.mdi-content-link:before{content:"\e70d"}.mdi-content-mail:before{content:"\e70e"}.mdi-content-markunread:before{content:"\e70f"}.mdi-content-redo:before{content:"\e710"}.mdi-content-remove:before{content:"\e711"}.mdi-content-remove-circle:before{content:"\e712"}.mdi-content-remove-circle-outline:before{content:"\e713"}.mdi-content-reply:before{content:"\e714"}.mdi-content-reply-all:before{content:"\e715"}.mdi-content-report:before{content:"\e716"}.mdi-content-save:before{content:"\e717"}.mdi-content-select-all:before{content:"\e718"}.mdi-content-send:before{content:"\e719"}.mdi-content-sort:before{content:"\e71a"}.mdi-content-text-format:before{content:"\e71b"}.mdi-content-undo:before{content:"\e71c"}.mdi-device-access-alarm:before{content:"\e71d"}.mdi-device-access-alarms:before{content:"\e71e"}.mdi-device-access-time:before{content:"\e71f"}.mdi-device-add-alarm:before{content:"\e720"}.mdi-device-airplanemode-off:before{content:"\e721"}.mdi-device-airplanemode-on:before{content:"\e722"}.mdi-device-battery-20:before{content:"\e723"}.mdi-device-battery-30:before{content:"\e724"}.mdi-device-battery-50:before{content:"\e725"}.mdi-device-battery-60:before{content:"\e726"}.mdi-device-battery-80:before{content:"\e727"}.mdi-device-battery-90:before{content:"\e728"}.mdi-device-battery-alert:before{content:"\e729"}.mdi-device-battery-charging-20:before{content:"\e72a"}.mdi-device-battery-charging-30:before{content:"\e72b"}.mdi-device-battery-charging-50:before{content:"\e72c"}.mdi-device-battery-charging-60:before{content:"\e72d"}.mdi-device-battery-charging-80:before{content:"\e72e"}.mdi-device-battery-charging-90:before{content:"\e72f"}.mdi-device-battery-charging-full:before{content:"\e730"}.mdi-device-battery-full:before{content:"\e731"}.mdi-device-battery-std:before{content:"\e732"}.mdi-device-battery-unknown:before{content:"\e733"}.mdi-device-bluetooth:before{content:"\e734"}.mdi-device-bluetooth-connected:before{content:"\e735"}.mdi-device-bluetooth-disabled:before{content:"\e736"}.mdi-device-bluetooth-searching:before{content:"\e737"}.mdi-device-brightness-auto:before{content:"\e738"}.mdi-device-brightness-high:before{content:"\e739"}.mdi-device-brightness-low:before{content:"\e73a"}.mdi-device-brightness-medium:before{content:"\e73b"}.mdi-device-data-usage:before{content:"\e73c"}.mdi-device-developer-mode:before{content:"\e73d"}.mdi-device-devices:before{content:"\e73e"}.mdi-device-dvr:before{content:"\e73f"}.mdi-device-gps-fixed:before{content:"\e740"}.mdi-device-gps-not-fixed:before{content:"\e741"}.mdi-device-gps-off:before{content:"\e742"}.mdi-device-location-disabled:before{content:"\e743"}.mdi-device-location-searching:before{content:"\e744"}.mdi-device-multitrack-audio:before{content:"\e745"}.mdi-device-network-cell:before{content:"\e746"}.mdi-device-network-wifi:before{content:"\e747"}.mdi-device-nfc:before{content:"\e748"}.mdi-device-now-wallpaper:before{content:"\e749"}.mdi-device-now-widgets:before{content:"\e74a"}.mdi-device-screen-lock-landscape:before{content:"\e74b"}.mdi-device-screen-lock-portrait:before{content:"\e74c"}.mdi-device-screen-lock-rotation:before{content:"\e74d"}.mdi-device-screen-rotation:before{content:"\e74e"}.mdi-device-sd-storage:before{content:"\e74f"}.mdi-device-settings-system-daydream:before{content:"\e750"}.mdi-device-signal-cellular-0-bar:before{content:"\e751"}.mdi-device-signal-cellular-1-bar:before{content:"\e752"}.mdi-device-signal-cellular-2-bar:before{content:"\e753"}.mdi-device-signal-cellular-3-bar:before{content:"\e754"}.mdi-device-signal-cellular-4-bar:before{content:"\e755"}.mdi-device-signal-cellular-connected-no-internet-0-bar:before{content:"\e756"}.mdi-device-signal-cellular-connected-no-internet-1-bar:before{content:"\e757"}.mdi-device-signal-cellular-connected-no-internet-2-bar:before{content:"\e758"}.mdi-device-signal-cellular-connected-no-internet-3-bar:before{content:"\e759"}.mdi-device-signal-cellular-connected-no-internet-4-bar:before{content:"\e75a"}.mdi-device-signal-cellular-no-sim:before{content:"\e75b"}.mdi-device-signal-cellular-null:before{content:"\e75c"}.mdi-device-signal-cellular-off:before{content:"\e75d"}.mdi-device-signal-wifi-0-bar:before{content:"\e75e"}.mdi-device-signal-wifi-1-bar:before{content:"\e75f"}.mdi-device-signal-wifi-2-bar:before{content:"\e760"}.mdi-device-signal-wifi-3-bar:before{content:"\e761"}.mdi-device-signal-wifi-4-bar:before{content:"\e762"}.mdi-device-signal-wifi-off:before{content:"\e763"}.mdi-device-storage:before{content:"\e764"}.mdi-device-usb:before{content:"\e765"}.mdi-device-wifi-lock:before{content:"\e766"}.mdi-device-wifi-tethering:before{content:"\e767"}.mdi-editor-attach-file:before{content:"\e768"}.mdi-editor-attach-money:before{content:"\e769"}.mdi-editor-border-all:before{content:"\e76a"}.mdi-editor-border-bottom:before{content:"\e76b"}.mdi-editor-border-clear:before{content:"\e76c"}.mdi-editor-border-color:before{content:"\e76d"}.mdi-editor-border-horizontal:before{content:"\e76e"}.mdi-editor-border-inner:before{content:"\e76f"}.mdi-editor-border-left:before{content:"\e770"}.mdi-editor-border-outer:before{content:"\e771"}.mdi-editor-border-right:before{content:"\e772"}.mdi-editor-border-style:before{content:"\e773"}.mdi-editor-border-top:before{content:"\e774"}.mdi-editor-border-vertical:before{content:"\e775"}.mdi-editor-format-align-center:before{content:"\e776"}.mdi-editor-format-align-justify:before{content:"\e777"}.mdi-editor-format-align-left:before{content:"\e778"}.mdi-editor-format-align-right:before{content:"\e779"}.mdi-editor-format-bold:before{content:"\e77a"}.mdi-editor-format-clear:before{content:"\e77b"}.mdi-editor-format-color-fill:before{content:"\e77c"}.mdi-editor-format-color-reset:before{content:"\e77d"}.mdi-editor-format-color-text:before{content:"\e77e"}.mdi-editor-format-indent-decrease:before{content:"\e77f"}.mdi-editor-format-indent-increase:before{content:"\e780"}.mdi-editor-format-italic:before{content:"\e781"}.mdi-editor-format-line-spacing:before{content:"\e782"}.mdi-editor-format-list-bulleted:before{content:"\e783"}.mdi-editor-format-list-numbered:before{content:"\e784"}.mdi-editor-format-paint:before{content:"\e785"}.mdi-editor-format-quote:before{content:"\e786"}.mdi-editor-format-size:before{content:"\e787"}.mdi-editor-format-strikethrough:before{content:"\e788"}.mdi-editor-format-textdirection-l-to-r:before{content:"\e789"}.mdi-editor-format-textdirection-r-to-l:before{content:"\e78a"}.mdi-editor-format-underline:before{content:"\e78b"}.mdi-editor-functions:before{content:"\e78c"}.mdi-editor-insert-chart:before{content:"\e78d"}.mdi-editor-insert-comment:before{content:"\e78e"}.mdi-editor-insert-drive-file:before{content:"\e78f"}.mdi-editor-insert-emoticon:before{content:"\e790"}.mdi-editor-insert-invitation:before{content:"\e791"}.mdi-editor-insert-link:before{content:"\e792"}.mdi-editor-insert-photo:before{content:"\e793"}.mdi-editor-merge-type:before{content:"\e794"}.mdi-editor-mode-comment:before{content:"\e795"}.mdi-editor-mode-edit:before{content:"\e796"}.mdi-editor-publish:before{content:"\e797"}.mdi-editor-vertical-align-bottom:before{content:"\e798"}.mdi-editor-vertical-align-center:before{content:"\e799"}.mdi-editor-vertical-align-top:before{content:"\e79a"}.mdi-editor-wrap-text:before{content:"\e79b"}.mdi-file-attachment:before{content:"\e79c"}.mdi-file-cloud:before{content:"\e79d"}.mdi-file-cloud-circle:before{content:"\e79e"}.mdi-file-cloud-done:before{content:"\e79f"}.mdi-file-cloud-download:before{content:"\e7a0"}.mdi-file-cloud-off:before{content:"\e7a1"}.mdi-file-cloud-queue:before{content:"\e7a2"}.mdi-file-cloud-upload:before{content:"\e7a3"}.mdi-file-file-download:before{content:"\e7a4"}.mdi-file-file-upload:before{content:"\e7a5"}.mdi-file-folder:before{content:"\e7a6"}.mdi-file-folder-open:before{content:"\e7a7"}.mdi-file-folder-shared:before{content:"\e7a8"}.mdi-hardware-cast:before{content:"\e7a9"}.mdi-hardware-cast-connected:before{content:"\e7aa"}.mdi-hardware-computer:before{content:"\e7ab"}.mdi-hardware-desktop-mac:before{content:"\e7ac"}.mdi-hardware-desktop-windows:before{content:"\e7ad"}.mdi-hardware-dock:before{content:"\e7ae"}.mdi-hardware-gamepad:before{content:"\e7af"}.mdi-hardware-headset:before{content:"\e7b0"}.mdi-hardware-headset-mic:before{content:"\e7b1"}.mdi-hardware-keyboard:before{content:"\e7b2"}.mdi-hardware-keyboard-alt:before{content:"\e7b3"}.mdi-hardware-keyboard-arrow-down:before{content:"\e7b4"}.mdi-hardware-keyboard-arrow-left:before{content:"\e7b5"}.mdi-hardware-keyboard-arrow-right:before{content:"\e7b6"}.mdi-hardware-keyboard-arrow-up:before{content:"\e7b7"}.mdi-hardware-keyboard-backspace:before{content:"\e7b8"}.mdi-hardware-keyboard-capslock:before{content:"\e7b9"}.mdi-hardware-keyboard-control:before{content:"\e7ba"}.mdi-hardware-keyboard-hide:before{content:"\e7bb"}.mdi-hardware-keyboard-return:before{content:"\e7bc"}.mdi-hardware-keyboard-tab:before{content:"\e7bd"}.mdi-hardware-keyboard-voice:before{content:"\e7be"}.mdi-hardware-laptop:before{content:"\e7bf"}.mdi-hardware-laptop-chromebook:before{content:"\e7c0"}.mdi-hardware-laptop-mac:before{content:"\e7c1"}.mdi-hardware-laptop-windows:before{content:"\e7c2"}.mdi-hardware-memory:before{content:"\e7c3"}.mdi-hardware-mouse:before{content:"\e7c4"}.mdi-hardware-phone-android:before{content:"\e7c5"}.mdi-hardware-phone-iphone:before{content:"\e7c6"}.mdi-hardware-phonelink:before{content:"\e7c7"}.mdi-hardware-phonelink-off:before{content:"\e7c8"}.mdi-hardware-security:before{content:"\e7c9"}.mdi-hardware-sim-card:before{content:"\e7ca"}.mdi-hardware-smartphone:before{content:"\e7cb"}.mdi-hardware-speaker:before{content:"\e7cc"}.mdi-hardware-tablet:before{content:"\e7cd"}.mdi-hardware-tablet-android:before{content:"\e7ce"}.mdi-hardware-tablet-mac:before{content:"\e7cf"}.mdi-hardware-tv:before{content:"\e7d0"}.mdi-hardware-watch:before{content:"\e7d1"}.mdi-image-add-to-photos:before{content:"\e7d2"}.mdi-image-adjust:before{content:"\e7d3"}.mdi-image-assistant-photo:before{content:"\e7d4"}.mdi-image-audiotrack:before{content:"\e7d5"}.mdi-image-blur-circular:before{content:"\e7d6"}.mdi-image-blur-linear:before{content:"\e7d7"}.mdi-image-blur-off:before{content:"\e7d8"}.mdi-image-blur-on:before{content:"\e7d9"}.mdi-image-brightness-1:before{content:"\e7da"}.mdi-image-brightness-2:before{content:"\e7db"}.mdi-image-brightness-3:before{content:"\e7dc"}.mdi-image-brightness-4:before{content:"\e7dd"}.mdi-image-brightness-5:before{content:"\e7de"}.mdi-image-brightness-6:before{content:"\e7df"}.mdi-image-brightness-7:before{content:"\e7e0"}.mdi-image-brush:before{content:"\e7e1"}.mdi-image-camera:before{content:"\e7e2"}.mdi-image-camera-alt:before{content:"\e7e3"}.mdi-image-camera-front:before{content:"\e7e4"}.mdi-image-camera-rear:before{content:"\e7e5"}.mdi-image-camera-roll:before{content:"\e7e6"}.mdi-image-center-focus-strong:before{content:"\e7e7"}.mdi-image-center-focus-weak:before{content:"\e7e8"}.mdi-image-collections:before{content:"\e7e9"}.mdi-image-colorize:before{content:"\e7ea"}.mdi-image-color-lens:before{content:"\e7eb"}.mdi-image-compare:before{content:"\e7ec"}.mdi-image-control-point:before{content:"\e7ed"}.mdi-image-control-point-duplicate:before{content:"\e7ee"}.mdi-image-crop:before{content:"\e7ef"}.mdi-image-crop-3-2:before{content:"\e7f0"}.mdi-image-crop-5-4:before{content:"\e7f1"}.mdi-image-crop-7-5:before{content:"\e7f2"}.mdi-image-crop-16-9:before{content:"\e7f3"}.mdi-image-crop-din:before{content:"\e7f4"}.mdi-image-crop-free:before{content:"\e7f5"}.mdi-image-crop-landscape:before{content:"\e7f6"}.mdi-image-crop-original:before{content:"\e7f7"}.mdi-image-crop-portrait:before{content:"\e7f8"}.mdi-image-crop-square:before{content:"\e7f9"}.mdi-image-dehaze:before{content:"\e7fa"}.mdi-image-details:before{content:"\e7fb"}.mdi-image-edit:before{content:"\e7fc"}.mdi-image-exposure:before{content:"\e7fd"}.mdi-image-exposure-minus-1:before{content:"\e7fe"}.mdi-image-exposure-minus-2:before{content:"\e7ff"}.mdi-image-exposure-plus-1:before{content:"\e800"}.mdi-image-exposure-plus-2:before{content:"\e801"}.mdi-image-exposure-zero:before{content:"\e802"}.mdi-image-filter:before{content:"\e803"}.mdi-image-filter-1:before{content:"\e804"}.mdi-image-filter-2:before{content:"\e805"}.mdi-image-filter-3:before{content:"\e806"}.mdi-image-filter-4:before{content:"\e807"}.mdi-image-filter-5:before{content:"\e808"}.mdi-image-filter-6:before{content:"\e809"}.mdi-image-filter-7:before{content:"\e80a"}.mdi-image-filter-8:before{content:"\e80b"}.mdi-image-filter-9:before{content:"\e80c"}.mdi-image-filter-9-plus:before{content:"\e80d"}.mdi-image-filter-b-and-w:before{content:"\e80e"}.mdi-image-filter-center-focus:before{content:"\e80f"}.mdi-image-filter-drama:before{content:"\e810"}.mdi-image-filter-frames:before{content:"\e811"}.mdi-image-filter-hdr:before{content:"\e812"}.mdi-image-filter-none:before{content:"\e813"}.mdi-image-filter-tilt-shift:before{content:"\e814"}.mdi-image-filter-vintage:before{content:"\e815"}.mdi-image-flare:before{content:"\e816"}.mdi-image-flash-auto:before{content:"\e817"}.mdi-image-flash-off:before{content:"\e818"}.mdi-image-flash-on:before{content:"\e819"}.mdi-image-flip:before{content:"\e81a"}.mdi-image-gradient:before{content:"\e81b"}.mdi-image-grain:before{content:"\e81c"}.mdi-image-grid-off:before{content:"\e81d"}.mdi-image-grid-on:before{content:"\e81e"}.mdi-image-hdr-off:before{content:"\e81f"}.mdi-image-hdr-on:before{content:"\e820"}.mdi-image-hdr-strong:before{content:"\e821"}.mdi-image-hdr-weak:before{content:"\e822"}.mdi-image-healing:before{content:"\e823"}.mdi-image-image:before{content:"\e824"}.mdi-image-image-aspect-ratio:before{content:"\e825"}.mdi-image-iso:before{content:"\e826"}.mdi-image-landscape:before{content:"\e827"}.mdi-image-leak-add:before{content:"\e828"}.mdi-image-leak-remove:before{content:"\e829"}.mdi-image-lens:before{content:"\e82a"}.mdi-image-looks:before{content:"\e82b"}.mdi-image-looks-3:before{content:"\e82c"}.mdi-image-looks-4:before{content:"\e82d"}.mdi-image-looks-5:before{content:"\e82e"}.mdi-image-looks-6:before{content:"\e82f"}.mdi-image-looks-one:before{content:"\e830"}.mdi-image-looks-two:before{content:"\e831"}.mdi-image-loupe:before{content:"\e832"}.mdi-image-movie-creation:before{content:"\e833"}.mdi-image-nature:before{content:"\e834"}.mdi-image-nature-people:before{content:"\e835"}.mdi-image-navigate-:before{content:"\e836"}.mdi-image-navigate-next:before{content:"\e837"}.mdi-image-palette:before{content:"\e838"}.mdi-image-panorama:before{content:"\e839"}.mdi-image-panorama-fisheye:before{content:"\e83a"}.mdi-image-panorama-horizontal:before{content:"\e83b"}.mdi-image-panorama-vertical:before{content:"\e83c"}.mdi-image-panorama-wide-angle:before{content:"\e83d"}.mdi-image-photo:before{content:"\e83e"}.mdi-image-photo-album:before{content:"\e83f"}.mdi-image-photo-camera:before{content:"\e840"}.mdi-image-photo-library:before{content:"\e841"}.mdi-image-portrait:before{content:"\e842"}.mdi-image-remove-red-eye:before{content:"\e843"}.mdi-image-rotate-left:before{content:"\e844"}.mdi-image-rotate-right:before{content:"\e845"}.mdi-image-slideshow:before{content:"\e846"}.mdi-image-straighten:before{content:"\e847"}.mdi-image-style:before{content:"\e848"}.mdi-image-switch-camera:before{content:"\e849"}.mdi-image-switch-video:before{content:"\e84a"}.mdi-image-tag-faces:before{content:"\e84b"}.mdi-image-texture:before{content:"\e84c"}.mdi-image-timelapse:before{content:"\e84d"}.mdi-image-timer:before{content:"\e84e"}.mdi-image-timer-3:before{content:"\e84f"}.mdi-image-timer-10:before{content:"\e850"}.mdi-image-timer-auto:before{content:"\e851"}.mdi-image-timer-off:before{content:"\e852"}.mdi-image-tonality:before{content:"\e853"}.mdi-image-transform:before{content:"\e854"}.mdi-image-tune:before{content:"\e855"}.mdi-image-wb-auto:before{content:"\e856"}.mdi-image-wb-cloudy:before{content:"\e857"}.mdi-image-wb-incandescent:before{content:"\e858"}.mdi-image-wb-iridescent:before{content:"\e859"}.mdi-image-wb-sunny:before{content:"\e85a"}.mdi-maps-beenhere:before{content:"\e85b"}.mdi-maps-directions:before{content:"\e85c"}.mdi-maps-directions-bike:before{content:"\e85d"}.mdi-maps-directions-bus:before{content:"\e85e"}.mdi-maps-directions-car:before{content:"\e85f"}.mdi-maps-directions-ferry:before{content:"\e860"}.mdi-maps-directions-subway:before{content:"\e861"}.mdi-maps-directions-train:before{content:"\e862"}.mdi-maps-directions-transit:before{content:"\e863"}.mdi-maps-directions-walk:before{content:"\e864"}.mdi-maps-flight:before{content:"\e865"}.mdi-maps-hotel:before{content:"\e866"}.mdi-maps-layers:before{content:"\e867"}.mdi-maps-layers-clear:before{content:"\e868"}.mdi-maps-local-airport:before{content:"\e869"}.mdi-maps-local-atm:before{content:"\e86a"}.mdi-maps-local-attraction:before{content:"\e86b"}.mdi-maps-local-bar:before{content:"\e86c"}.mdi-maps-local-cafe:before{content:"\e86d"}.mdi-maps-local-car-wash:before{content:"\e86e"}.mdi-maps-local-convenience-store:before{content:"\e86f"}.mdi-maps-local-drink:before{content:"\e870"}.mdi-maps-local-florist:before{content:"\e871"}.mdi-maps-local-gas-station:before{content:"\e872"}.mdi-maps-local-grocery-store:before{content:"\e873"}.mdi-maps-local-hospital:before{content:"\e874"}.mdi-maps-local-hotel:before{content:"\e875"}.mdi-maps-local-laundry-service:before{content:"\e876"}.mdi-maps-local-library:before{content:"\e877"}.mdi-maps-local-mall:before{content:"\e878"}.mdi-maps-local-movies:before{content:"\e879"}.mdi-maps-local-offer:before{content:"\e87a"}.mdi-maps-local-parking:before{content:"\e87b"}.mdi-maps-local-pharmacy:before{content:"\e87c"}.mdi-maps-local-phone:before{content:"\e87d"}.mdi-maps-local-pizza:before{content:"\e87e"}.mdi-maps-local-play:before{content:"\e87f"}.mdi-maps-local-post-office:before{content:"\e880"}.mdi-maps-local-print-shop:before{content:"\e881"}.mdi-maps-local-restaurant:before{content:"\e882"}.mdi-maps-local-see:before{content:"\e883"}.mdi-maps-local-shipping:before{content:"\e884"}.mdi-maps-local-taxi:before{content:"\e885"}.mdi-maps-location-history:before{content:"\e886"}.mdi-maps-map:before{content:"\e887"}.mdi-maps-my-location:before{content:"\e888"}.mdi-maps-navigation:before{content:"\e889"}.mdi-maps-pin-drop:before{content:"\e88a"}.mdi-maps-place:before{content:"\e88b"}.mdi-maps-rate-review:before{content:"\e88c"}.mdi-maps-restaurant-menu:before{content:"\e88d"}.mdi-maps-satellite:before{content:"\e88e"}.mdi-maps-store-mall-directory:before{content:"\e88f"}.mdi-maps-terrain:before{content:"\e890"}.mdi-maps-traffic:before{content:"\e891"}.mdi-navigation-apps:before{content:"\e892"}.mdi-navigation-arrow-back:before{content:"\e893"}.mdi-navigation-arrow-drop-down:before{content:"\e894"}.mdi-navigation-arrow-drop-down-circle:before{content:"\e895"}.mdi-navigation-arrow-drop-up:before{content:"\e896"}.mdi-navigation-arrow-forward:before{content:"\e897"}.mdi-navigation-cancel:before{content:"\e898"}.mdi-navigation-check:before{content:"\e899"}.mdi-navigation-chevron-left:before{content:"\e89a"}.mdi-navigation-chevron-right:before{content:"\e89b"}.mdi-navigation-close:before{content:"\e89c"}.mdi-navigation-expand-less:before{content:"\e89d"}.mdi-navigation-expand-more:before{content:"\e89e"}.mdi-navigation-fullscreen:before{content:"\e89f"}.mdi-navigation-fullscreen-exit:before{content:"\e8a0"}.mdi-navigation-menu:before{content:"\e8a1"}.mdi-navigation-more-horiz:before{content:"\e8a2"}.mdi-navigation-more-vert:before{content:"\e8a3"}.mdi-navigation-refresh:before{content:"\e8a4"}.mdi-navigation-unfold-less:before{content:"\e8a5"}.mdi-navigation-unfold-more:before{content:"\e8a6"}.mdi-notification-adb:before{content:"\e8a7"}.mdi-notification-bluetooth-audio:before{content:"\e8a8"}.mdi-notification-disc-full:before{content:"\e8a9"}.mdi-notification-dnd-forwardslash:before{content:"\e8aa"}.mdi-notification-do-not-disturb:before{content:"\e8ab"}.mdi-notification-drive-eta:before{content:"\e8ac"}.mdi-notification-event-available:before{content:"\e8ad"}.mdi-notification-event-busy:before{content:"\e8ae"}.mdi-notification-event-note:before{content:"\e8af"}.mdi-notification-folder-special:before{content:"\e8b0"}.mdi-notification-mms:before{content:"\e8b1"}.mdi-notification-more:before{content:"\e8b2"}.mdi-notification-network-locked:before{content:"\e8b3"}.mdi-notification-phone-bluetooth-speaker:before{content:"\e8b4"}.mdi-notification-phone-forwarded:before{content:"\e8b5"}.mdi-notification-phone-in-talk:before{content:"\e8b6"}.mdi-notification-phone-locked:before{content:"\e8b7"}.mdi-notification-phone-missed:before{content:"\e8b8"}.mdi-notification-phone-paused:before{content:"\e8b9"}.mdi-notification-play-download:before{content:"\e8ba"}.mdi-notification-play-install:before{content:"\e8bb"}.mdi-notification-sd-card:before{content:"\e8bc"}.mdi-notification-sim-card-alert:before{content:"\e8bd"}.mdi-notification-sms:before{content:"\e8be"}.mdi-notification-sms-failed:before{content:"\e8bf"}.mdi-notification-sync:before{content:"\e8c0"}.mdi-notification-sync-disabled:before{content:"\e8c1"}.mdi-notification-sync-problem:before{content:"\e8c2"}.mdi-notification-system-update:before{content:"\e8c3"}.mdi-notification-tap-and-play:before{content:"\e8c4"}.mdi-notification-time-to-leave:before{content:"\e8c5"}.mdi-notification-vibration:before{content:"\e8c6"}.mdi-notification-voice-chat:before{content:"\e8c7"}.mdi-notification-vpn-lock:before{content:"\e8c8"}.mdi-social-cake:before{content:"\e8c9"}.mdi-social-domain:before{content:"\e8ca"}.mdi-social-group:before{content:"\e8cb"}.mdi-social-group-add:before{content:"\e8cc"}.mdi-social-location-city:before{content:"\e8cd"}.mdi-social-mood:before{content:"\e8ce"}.mdi-social-notifications:before{content:"\e8cf"}.mdi-social-notifications-none:before{content:"\e8d0"}.mdi-social-notifications-off:before{content:"\e8d1"}.mdi-social-notifications-on:before{content:"\e8d2"}.mdi-social-notifications-paused:before{content:"\e8d3"}.mdi-social-pages:before{content:"\e8d4"}.mdi-social-party-mode:before{content:"\e8d5"}.mdi-social-people:before{content:"\e8d6"}.mdi-social-people-outline:before{content:"\e8d7"}.mdi-social-person:before{content:"\e8d8"}.mdi-social-person-add:before{content:"\e8d9"}.mdi-social-person-outline:before{content:"\e8da"}.mdi-social-plus-one:before{content:"\e8db"}.mdi-social-poll:before{content:"\e8dc"}.mdi-social-public:before{content:"\e8dd"}.mdi-social-school:before{content:"\e8de"}.mdi-social-share:before{content:"\e8df"}.mdi-social-whatshot:before{content:"\e8e0"}.mdi-toggle-check-box:before{content:"\e8e1"}.mdi-toggle-check-box-outline-blank:before{content:"\e8e2"}.mdi-toggle-radio-button-off:before{content:"\e8e3"}.mdi-toggle-radio-button-on:before{content:"\e8e4"}[class^="mdi-"],[class*=" mdi-"],.mdi{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.player .control{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}@font-face{font-family:"icomoon";src:url("../fonts/icomoon/fonts/icomoon.eot");src:url("../fonts/icomoon/fonts/icomoon.eot?#iefix") format("embedded-opentype"),url("../fonts/icomoon/fonts/icomoon.woff") format("woff"),url("../fonts/icomoon/fonts/icomoon.ttf") format("truetype");font-weight:normal;font-style:normal}.icomoon-google:before{content:"\e900"}.icomoon-home:before{content:"\e607"}.icomoon-pencil:before{content:"\e608"}.icomoon-image:before{content:"\e609"}.icomoon-music2:before{content:"\e60a"}.icomoon-headphones:before{content:"\e60b"}.icomoon-play:before{content:"\e60c"}.icomoon-film:before{content:"\e60d"}.icomoon-camera:before{content:"\e60e"}.icomoon-pacman:before{content:"\e60f"}.icomoon-tag:before{content:"\e610"}.icomoon-tags:before{content:"\e611"}.icomoon-location:before{content:"\e612"}.icomoon-screen:before{content:"\e613"}.icomoon-mobile:before{content:"\e614"}.icomoon-tv:before{content:"\e615"}.icomoon-bubble:before{content:"\e616"}.icomoon-bubbles:before{content:"\e617"}.icomoon-user:before{content:"\e618"}.icomoon-spinner:before{content:"\e619"}.icomoon-search:before{content:"\e61a"}.icomoon-key:before{content:"\e61b"}.icomoon-settings:before{content:"\e61c"}.icomoon-cog:before{content:"\e61d"}.icomoon-stats:before{content:"\e61e"}.icomoon-switch:before{content:"\e61f"}.icomoon-tree:before{content:"\e620"}.icomoon-cloud:before{content:"\e621"}.icomoon-earth:before{content:"\e622"}.icomoon-link:before{content:"\e623"}.icomoon-attachment:before{content:"\e624"}.icomoon-star:before{content:"\e625"}.icomoon-star2:before{content:"\e626"}.icomoon-heart:before{content:"\e627"}.icomoon-heart2:before{content:"\e628"}.icomoon-smiley:before{content:"\e629"}.icomoon-smiley2:before{content:"\e62a"}.icomoon-info:before{content:"\e62b"}.icomoon-checkmark:before{content:"\e62c"}.icomoon-arrow-right:before{content:"\e62d"}.icomoon-arrow-left:before{content:"\e62e"}.icomoon-arrow-right2:before{content:"\e62f"}.icomoon-arrow-left2:before{content:"\e630"}.icomoon-share:before{content:"\e631"}.icomoon-googleplus:before{content:"\e632"}.icomoon-facebook:before{content:"\e633"}.icomoon-twitter:before{content:"\e634"}.icomoon-feed:before{content:"\e635"}.icomoon-feed2:before{content:"\e636"}.icomoon-youtube:before{content:"\e637"}.icomoon-picasa:before{content:"\e638"}.icomoon-github:before{content:"\e639"}.icomoon-github2:before{content:"\e63a"}.icomoon-github3:before{content:"\e63b"}.icomoon-tux:before{content:"\e63c"}.icomoon-apple:before{content:"\e63d"}.icomoon-android:before{content:"\e63e"}.icomoon-windows8:before{content:"\e63f"}.icomoon-paypal:before{content:"\e640"}.icomoon-file-zip:before{content:"\e641"}.icomoon-file-css:before{content:"\e642"}.icomoon-imdb:before{content:"\e901"}.icomoon-flatscreen:before{content:"\e600"}.icomoon-clapperboard:before{content:"\e601"}.icomoon-kodi-symbol:before{content:"\e602"}.icomoon-kodi-text:before{content:"\e603"}.icomoon-linux:before{content:"\e604"}.icomoon-music:before{content:"\e605"}.icomoon-pi:before{content:"\e606"}.icomoon-network:before{content:"\e643"}.icomoon-rss:before{content:"\e644"}.icomoon-statistics:before{content:"\e645"}.icomoon-pie:before{content:"\e646"}.icomoon-minus:before{content:"\e647"}.icomoon-plus:before{content:"\e648"}.icomoon-info2:before{content:"\e649"}.icomoon-question:before{content:"\e64a"}.icomoon-help:before{content:"\e64b"}.icomoon-warning:before{content:"\e64c"}.icomoon-list:before{content:"\e64d"}.icomoon-flow-tree:before{content:"\e64e"}.icomoon-arrow-left3:before{content:"\e64f"}.icomoon-arrow-right3:before{content:"\e650"}.icomoon-arrow-left4:before{content:"\e651"}.icomoon-arrow-right4:before{content:"\e652"}.icomoon-arrow-left5:before{content:"\e653"}.icomoon-uniE654:before{content:"\e654"}[class^="icomoon-"],[class*=" icomoon-"],.icomoon{display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#logo{display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.table-hover>tbody>tr:hover,.songs-table tr.song.menu-open,.songs-table tr.song:hover{background-color:rgba(255,255,255,0.3)}.table-hover>tbody>tr:hover .crop,.songs-table tr.song.menu-open .crop,.songs-table tr.song:hover .crop{position:relative;white-space:nowrap;overflow:hidden}.table-hover>tbody>tr:hover .crop:after,.songs-table tr.song.menu-open .crop:after,.songs-table tr.song:hover .crop:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E7E7E7', endColorstr='#FFE7E7E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3ZTdlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlN2U3ZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(231,231,231,0)),color-stop(100%, #e7e7e7));background-image:-moz-linear-gradient(left, rgba(231,231,231,0) 0%,#e7e7e7 100%);background-image:-webkit-linear-gradient(left, rgba(231,231,231,0) 0%,#e7e7e7 100%);background-image:linear-gradient(to right, rgba(231,231,231,0) 0%,#e7e7e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.shadow-z-1,.card,.snackbar,.landing-page .region-content h3,.landing-page h3.set-header,.card,.snackbar{box-shadow:0 1px 3px rgba(0,0,0,0.04),0 1px 2px rgba(0,0,0,0.05)}.shadow-z-2-hover,.btn:hover:not(.btn-link),.btn:hover:not(.btn-link){box-shadow:0 3px 6px rgba(0,0,0,0.07),0 2px 4px rgba(0,0,0,0.13)}.table-striped>tbody>tr:nth-child(odd){background-color:rgba(255,255,255,0.5)}.table-striped>tbody>tr>td{border:0}.table>tbody>tr>td{border-top:none}.options-list{padding-bottom:0.5em}.options-list>li{border-bottom:1px solid #ddd}.options-list>li:last-child{border:0}.options-list>li>span,.options-list>li>a{display:block;padding:0.5em 1em;cursor:pointer}.options-list>li>span:hover,.options-list>li>a:hover{background:#12b2e7;color:#fff}.options-list>li>span:hover small,.options-list>li>a:hover small{display:inline}.options-list small{font-size:70%;opacity:0.7;display:none}@media (min-width: 57em){.modal.style-options .modal-dialog{width:300px}}.modal.style-options .modal-footer{display:none}.page-padding,.settings-form .form-content-region,.section-lab .page,.api-method--execute{padding:1em}@media (min-width: 57em){.page-padding,.settings-form .form-content-region,.section-lab .page,.api-method--execute{padding:2em;padding-left:3em}} -.page,.page-secondary,.api-method--execute,.help--page .region-content-wrapper .region-content,.settings-form{max-width:58em;margin-left:0;background:#fff}.page-secondary,.api-method--execute{background:rgba(255,255,255,0.5)}.page-wrapper,.help--page .region-content-wrapper{padding:0;margin-bottom:4em}.page-wrapper .region-content,.help--page .region-content-wrapper .region-content{padding:0}.addon-list .region-first,.browser-page .region-first,.category-list .region-first,.filter-pane,.help--page .region-first,.landing-page .region-first,.local-playlist-list .region-first,.pvr-page .region-first,.epg-page .region-first,.search-page-layout .region-first,.settings-page .region-first{padding:1em 1.5em}.sidebar-section h3,.browser-page .region-first h3,.filters-container h3,.local-playlist-list .region-first h3,.modal .playlist-selection-list h3,.region-first .nav-sub h3{font-size:15px;text-transform:uppercase;margin:1em 0;color:#888;font-weight:bold}.sidebar-section,.browser-page .region-first .source-set,.filters-container .nav-list,.filters-container .selection-list,.filters-container .active-list,.region-first .nav-sub{margin-bottom:2em}.sidebar-section ul,.filters-container .nav-list,.filters-container .selection-list,.local-playlist-list .region-first .lists,.modal .playlist-selection-list .lists,.region-first .nav-sub .items{padding-left:1em}.sidebar-section ul li,.filters-container .nav-list li,.filters-container .selection-list li,.local-playlist-list .region-first .lists li,.modal .playlist-selection-list .lists li,.region-first .nav-sub .items li{padding-bottom:0.5em;position:relative;white-space:nowrap;overflow:hidden;cursor:pointer}.sidebar-section ul li:after,.filters-container .nav-list li:after,.filters-container .selection-list li:after,.local-playlist-list .region-first .lists li:after,.modal .playlist-selection-list .lists li:after,.region-first .nav-sub .items li:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F2F2F2', endColorstr='#FFF2F2F2');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YyZjJmMiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMmYyZjIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(242,242,242,0)),color-stop(100%, #f2f2f2));background-image:-moz-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:-webkit-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:linear-gradient(to right, rgba(242,242,242,0) 0%,#f2f2f2 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.sidebar-section ul li:hover,.filters-container .nav-list li:hover,.filters-container .selection-list li:hover,.local-playlist-list .region-first .lists li:hover,.modal .playlist-selection-list .lists li:hover,.region-first .nav-sub .items li:hover{color:#12b2e7}.sidebar-section ul li a,.filters-container .nav-list li a,.filters-container .selection-list li a,.local-playlist-list .region-first .lists li a,.modal .playlist-selection-list .lists li a,.region-first .nav-sub .items li a{color:#2b2f30}.sidebar-section ul li a.active,.filters-container .nav-list li a.active,.filters-container .selection-list li a.active,.local-playlist-list .region-first .lists li a.active,.modal .playlist-selection-list .lists li a.active,.region-first .nav-sub .items li a.active{color:#12b2e7;font-weight:bold}.active-player-local .sidebar-section ul li a.active,.sidebar-section .active-player-local ul li a.active,.active-player-local .filters-container .nav-list li a.active,.filters-container .active-player-local .nav-list li a.active,.active-player-local .filters-container .selection-list li a.active,.filters-container .active-player-local .selection-list li a.active,.active-player-local .local-playlist-list .region-first .lists li a.active,.local-playlist-list .region-first .active-player-local .lists li a.active,.active-player-local .modal .playlist-selection-list .lists li a.active,.modal .playlist-selection-list .active-player-local .lists li a.active,.active-player-local .region-first .nav-sub .items li a.active,.region-first .nav-sub .active-player-local .items li a.active{color:#db2464}.browser-page .region-first .sources{padding-left:1em;padding-left:0.5em}.browser-page .region-first .sources li{padding-bottom:0.5em;position:relative;white-space:nowrap;overflow:hidden;cursor:pointer}.browser-page .region-first .sources li:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F2F2F2', endColorstr='#FFF2F2F2');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YyZjJmMiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMmYyZjIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(242,242,242,0)),color-stop(100%, #f2f2f2));background-image:-moz-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:-webkit-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:linear-gradient(to right, rgba(242,242,242,0) 0%,#f2f2f2 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.browser-page .region-first .sources li:hover{color:#12b2e7}.browser-page .region-first .sources li a{color:#2b2f30}.browser-page .region-first .sources li a.active{color:#12b2e7;font-weight:bold}.active-player-local .browser-page .region-first .sources li a.active,.browser-page .region-first .active-player-local .sources li a.active{color:#db2464}.browser-page .region-first .sources li>div{display:inline-block;padding-left:0.5em}.browser-page .region-first .sources li:before{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none;opacity:0.3;content:"";font-size:0.9em}@font-face{font-family:"opensans-light";src:url("../fonts/opensans/opensans-light-webfont.eot");src:url("../fonts/opensans/opensans-light-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/opensans/opensans-light-webfont.woff") format("woff"),url("../fonts/opensans/opensans-light-webfont.ttf") format("truetype");font-weight:"normal";font-style:normal}@font-face{font-family:"opensans";src:url("../fonts/opensans/opensans-regular-webfont.eot");src:url("../fonts/opensans/opensans-regular-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/opensans/opensans-regular-webfont.woff") format("woff"),url("../fonts/opensans/opensans-regular-webfont.ttf") format("truetype");font-weight:"normal";font-style:normal}html,body{font-family:"opensans",Helvetica,Arial,sans-serif}body{zoom:0.75}@media (min-width: 25em){body{zoom:0.85}}@media (min-width: 37em){body{zoom:0.95}}@media (min-width: 45em){body{zoom:1}} +@media print{.hidden-print{display:none !important}}.shadow-z-1,.card,.snackbar,.landing-page .region-content h3,.landing-page h3.set-header,.landing-set .set__header{box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24)}.shadow-z-2,.well,.jumbotron,.btn-raised,.btn-group,.btn-group-vertical,.btn-group.btn-group-raised,.btn-group-vertical.btn-group-raised,.modal-content{box-shadow:0 0px 14px -5px rgba(0,0,0,0.06),0 6px 12px -6px rgba(0,0,0,0.13)}.shadow-z-2-hover,.btn:hover:not(.btn-link){box-shadow:0 3px 6px rgba(0,0,0,0.2),0 3px 6px rgba(0,0,0,0.28)}.shadow-z-3,.btn:active:not(.btn-link),.btn-raised:active:not(.btn-link),.btn-group:active:not(.btn-link),.btn-group-vertical:active:not(.btn-link),.btn-group.btn-group-raised:active:not(.btn-link),.btn-group-vertical.btn-group-raised:active:not(.btn-link){box-shadow:0 10px 20px rgba(0,0,0,0.19),0 6px 6px rgba(0,0,0,0.23)}.shadow-z-4,.btn-raised:hover,.btn-group:hover,.btn-group-vertical:hover,.btn-group.btn-group-raised:hover,.btn-group-vertical.btn-group-raised:hover{box-shadow:0 14px 28px rgba(0,0,0,0.25),0 10px 10px rgba(0,0,0,0.22)}.shadow-z-5{box-shadow:0 19px 38px rgba(0,0,0,0.3),0 15px 12px rgba(0,0,0,0.22)}body{background-color:#EEEEEE}body.inverse{background:#333333}body.inverse,body.inverse .form-control{color:rgba(255,255,255,0.84)}.well,.well .form-control,.well:not([class^="well well-material-"]),.well:not([class^="well well-material-"]) .form-control{color:rgba(0,0,0,0.84)}.well .floating-label,.well:not([class^="well well-material-"]) .floating-label{color:#7e7e7e}.well .form-control,.well:not([class^="well well-material-"]) .form-control{border-bottom-color:#7e7e7e}.well .form-control::-webkit-input-placeholder,.well:not([class^="well well-material-"]) .form-control::-webkit-input-placeholder{color:#7e7e7e}.well .form-control::-moz-placeholder,.well:not([class^="well well-material-"]) .form-control::-moz-placeholder{color:#7e7e7e;opacity:1}.well .form-control:-ms-input-placeholder,.well:not([class^="well well-material-"]) .form-control:-ms-input-placeholder{color:#7e7e7e}.well .option,.well .create,.well:not([class^="well well-material-"]) .option,.well:not([class^="well well-material-"]) .create{color:rgba(0,0,0,0.84)}[class^="well well-material-"],[class^="well well-material-"] .form-control,[class^="well well-material-"] .floating-label{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control{border-bottom-color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control::-webkit-input-placeholder{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .form-control::-moz-placeholder{color:rgba(255,255,255,0.84);opacity:1}[class^="well well-material-"] .form-control:-ms-input-placeholder{color:rgba(255,255,255,0.84)}[class^="well well-material-"] .option,[class^="well well-material-"] .create{color:rgba(0,0,0,0.84)}.well,.jumbotron{background-color:#fff;padding:19px;margin-bottom:20px;border-radius:2px;border:0}.well p,.jumbotron p{font-weight:300}.btn{position:relative;padding:8px 30px;border:0;margin:10px 1px;cursor:pointer;border-radius:2px;text-transform:uppercase;text-decoration:none;color:rgba(255,255,255,0.84);transition:box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);outline:none !important}.btn:hover{color:rgba(255,255,255,0.84)}.btn-link,.btn:not([class^="btn btn-"]),.btn-default{color:rgba(0,0,0,0.84)}.btn-link:hover,.btn:not([class^="btn btn-"]):hover,.btn-default:hover{color:rgba(0,0,0,0.84)}.btn:not([class^="btn btn-"]):hover,.btn-default:hover{background-color:rgba(255,255,255,0.5)}.btn-raised{transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-flat{box-shadow:none !important}.btn-flat.btn-default:hover{background:none}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus{background:#10a0cf;border-color:#10a0cf}.btn-group,.btn-group-vertical{position:relative;border-radius:4px;margin:10px 1px;transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-group.open .dropdown-toggle,.btn-group-vertical.open .dropdown-toggle{box-shadow:none}.btn-group.btn-group-raised,.btn-group-vertical.btn-group-raised{transition:box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1)}.btn-group .btn,.btn-group .btn:active,.btn-group .btn-group,.btn-group-vertical .btn,.btn-group-vertical .btn:active,.btn-group-vertical .btn-group{box-shadow:none !important;margin:0}.btn-group .btn:active .caret,.btn-group-vertical .btn:active .caret{margin-left:-1px}.btn-group-flat{box-shadow:none !important}.btn-fab{margin:0;padding:15px;font-size:26px;width:56px;height:56px}.btn-fab,.btn-fab .ripple-wrapper{border-radius:100%}.btn-fab.btn-mini{width:40px;height:40px;padding:13px;font-size:15px}.btn-default{background-color:#fff}.btn-primary{background-color:#12b2e7}.btn-success{background-color:#0f9d58}.btn-info{background-color:#03a9f4}.btn-warning{background-color:#ff5722}.btn-danger{background-color:#f44336}.btn-material-red{background-color:#f44336}.btn-material-pink{background-color:#e91e63}.btn-material-purple{background-color:#9c27b0}.btn-material-deeppurple{background-color:#673ab7}.btn-material-indigo{background-color:#3f51b5}.btn-material-lightblue{background-color:#03a9f4}.btn-material-cyan{background-color:#00bcd4}.btn-material-teal{background-color:#009688}.btn-material-lightgreen{background-color:#8bc34a}.btn-material-lime{background-color:#cddc39}.btn-material-lightyellow{background-color:#ffeb3b}.btn-material-orange{background-color:#ff9800}.btn-material-deeporange{background-color:#ff5722}.btn-material-grey{background-color:#9e9e9e}.btn-material-bluegrey{background-color:#607d8b}.btn-material-brown{background-color:#795548}.btn-material-lightgrey{background-color:#ececec}.form-horizontal .checkbox{padding-top:15px}.checkbox{transform:rotate(0deg)}.checkbox label{cursor:pointer;padding-left:45px;position:relative}.checkbox label span{display:block;position:absolute;left:0px;transition-duration:0.2s}.checkbox label .check:after{display:block;position:absolute;content:"";background-color:rgba(0,0,0,0.84);left:-5px;top:-15px;height:50px;width:50px;border-radius:100%;z-index:1;opacity:0;margin:0}.checkbox label .check:before{display:block;content:"";border:2px solid rgba(0,0,0,0.84);height:20px;width:20px;transition-delay:0.2s}.checkbox input[type=checkbox]{opacity:0}.checkbox input[type=checkbox] ~ .check:before{position:absolute;top:2px;left:11px;width:18px;height:18px;border:solid 2px;border-color:#5a5a5a;animation:uncheck 300ms ease-out forwards}.checkbox input[type=checkbox]:focus ~ .check:after{opacity:0.2}.checkbox input[type=checkbox]:checked ~ .check:before{animation:check 300ms ease-out forwards}.checkbox input[type=checkbox]:not(:checked) ~ .check:after{animation:rippleOff 500ms linear forwards}.checkbox input[type=checkbox]:checked ~ .check:after{animation:rippleOn 500ms linear forwards}.checkbox:not(:hover) input[type=checkbox] ~ .check:before,.checkbox:not(:hover) input[type=checkbox] ~ .check:after{animation-duration:1ms}.checkbox input[type=checkbox][disabled]:not(:checked) ~ .check:before{opacity:0.5}.checkbox input[type=checkbox][disabled] ~ .check:after{background-color:rgba(0,0,0,0.84);transform:rotate(-45deg)}@keyframes uncheck{0%{top:-3px;left:17px;width:10px;height:21px;border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent;transform:rotate(45deg)}50%{top:14px;left:17px;width:4px;height:4px;transform:rotate(45deg);border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent}51%{border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}100%{top:1px;left:12px;width:18px;height:18px;transform:rotate(0deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}}@keyframes check{100%{top:-3px;left:17px;width:10px;height:21px;transform:rotate(45deg);border-color:#0f9d58;border-left-color:transparent;border-top-color:transparent}51%{border-left:transparent;border-top-color:transparent}50%{top:14px;left:17px;width:4px;height:4px;transform:rotate(45deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}0%{top:1px;left:12px;width:18px;height:18px;transform:rotate(0deg);border-color:#5a5a5a;border-left-color:#5a5a5a;border-top-color:#5a5a5a}}@keyframes rippleOn{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}@keyframes rippleOff{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}.togglebutton{vertical-align:middle}.togglebutton,.togglebutton *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.togglebutton label{font-weight:400;cursor:pointer}.togglebutton label input[type=checkbox]:first-child{opacity:0;width:0;height:0}.togglebutton label input[type=checkbox]:first-child:checked+.toggle{background-color:rgba(18,178,231,0.5)}.togglebutton label input[type=checkbox]:first-child:checked+.toggle:after{background-color:#12b2e7}.togglebutton label .toggle,.togglebutton label input[type=checkbox][disabled]:first-child+.toggle{content:"";display:inline-block;width:30px;height:15px;background-color:rgba(80,80,80,0.7);border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle}.togglebutton label .toggle:after{content:"";display:inline-block;width:20px;height:20px;background-color:#F1F1F1;border-radius:20px;position:relative;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-2px;transition:left 0.3s ease, background 0.3s ease, box-shadow 0.1s ease}.togglebutton label input[type=checkbox][disabled]:first-child+.toggle:after,.togglebutton label input[type=checkbox][disabled]:checked:first-child+.toggle:after{background-color:#BDBDBD}.togglebutton label input[type=checkbox]:first-child:checked ~ .toggle:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,149,135,0.1)}.togglebutton label input[type=checkbox]:first-child ~ .toggle:active:after,.togglebutton label input[type=checkbox][disabled]:first-child ~ .toggle:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.1)}.togglebutton label input[type=checkbox]:first-child:checked+.toggle:after{left:15px}.form-horizontal .radio{margin-bottom:10px}.radio label{cursor:pointer;padding-left:45px;position:relative}.radio label span{display:block;position:absolute;left:10px;top:2px;transition-duration:0.2s}.radio label .circle{border:2px solid rgba(0,0,0,0.84);height:15px;width:15px;border-radius:100%}.radio label .check{height:15px;width:15px;border-radius:100%;background-color:rgba(0,0,0,0.84);transform:scale(0)}.radio label .check:after{display:block;position:absolute;content:"";background-color:rgba(0,0,0,0.84);left:-18px;top:-18px;height:50px;width:50px;border-radius:100%;z-index:1;opacity:0;margin:0;transform:scale(1.5)}.radio label input[type=radio]:not(:checked) ~ .check:after{animation:rippleOff 500ms}.radio label input[type=radio]:checked ~ .check:after{animation:rippleOn 500ms}.radio input[type=radio][disabled] ~ .check,.radio input[type=radio][disabled] ~ .circle{opacity:0.5}.radio input[type=radio]{display:none}.radio input[type=radio]:checked ~ .check{transform:scale(0.55)}.radio input[type=radio][disabled] ~ .circle{border-color:rgba(0,0,0,0.84)}.radio input[type=radio][disabled] ~ .check{background-color:rgba(0,0,0,0.84)}@keyframes rippleOn{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}@keyframes rippleOff{0%{opacity:0}50%{opacity:0.2}100%{opacity:0}}fieldset[disabled] .form-control,fieldset[disabled] .form-control:focus,fieldset[disabled] .form-control.focus,.form-control-wrapper .form-control,.form-control-wrapper .form-control:focus,.form-control-wrapper .form-control.focus,.form-control,.form-control:focus,.form-control.focus{padding:0;float:none;border:0;box-shadow:none;border-radius:0;background:transparent;border-bottom:1px solid #757575}fieldset[disabled] .form-control:not(textarea):not(select),fieldset[disabled] .form-control:focus:not(textarea):not(select),fieldset[disabled] .form-control.focus:not(textarea):not(select),.form-control-wrapper .form-control:not(textarea):not(select),.form-control-wrapper .form-control:focus:not(textarea):not(select),.form-control-wrapper .form-control.focus:not(textarea):not(select),.form-control:not(textarea):not(select),.form-control:focus:not(textarea):not(select),.form-control.focus:not(textarea):not(select){height:28px}fieldset[disabled] .form-control:disabled,fieldset[disabled] .form-control:focus:disabled,fieldset[disabled] .form-control.focus:disabled,.form-control-wrapper .form-control:disabled,.form-control-wrapper .form-control:focus:disabled,.form-control-wrapper .form-control.focus:disabled,.form-control:disabled,.form-control:focus:disabled,.form-control.focus:disabled{border-style:dashed}select.form-control{height:23px}select[multiple].form-control,select[multiple].form-control:focus,select[multiple].form-control.focus{height:85px}.form-control-wrapper{position:relative}.form-control-wrapper .form-control:focus,.form-control-wrapper .form-control.focus{outline:none}.form-control-wrapper .floating-label{color:#7E7E7E;font-size:14px;position:absolute;pointer-events:none;left:0px;top:5px;transition:0.2s ease all;opacity:0}.form-control-wrapper .form-control:not(.empty) ~ .floating-label{top:-10px;font-size:10px;opacity:1}.form-control-wrapper .form-control:focus:invalid ~ .floating-label,.form-control-wrapper .form-control.focus:invalid ~ .floating-label{color:#f44336}.form-control-wrapper .form-control:focus ~ .material-input:after,.form-control-wrapper .form-control.focus ~ .material-input:after{background-color:#12b2e7}.form-control-wrapper .form-control:focus:invalid ~ .material-input:before,.form-control-wrapper .form-control:focus:invalid ~ .material-input:after,.form-control-wrapper .form-control.focus:invalid ~ .material-input:before,.form-control-wrapper .form-control.focus:invalid ~ .material-input:after{background-color:#f44336}.form-control-wrapper .form-control.empty ~ .floating-label{opacity:1}.form-control-wrapper .material-input:before{position:absolute;content:"";width:100%;left:0;height:2px;background-color:#12b2e7;bottom:-1px;transform:scaleX(0);transition:transform 0s}.form-control-wrapper .form-control:focus ~ .material-input:before,.form-control-wrapper .form-control.focus ~ .material-input:before{transform:scaleX(1);transition:transform 0.2s ease-out}.form-control-wrapper .material-input:after{content:"";position:absolute;height:18px;width:100px;margin-top:-1px;top:7px;left:0;pointer-events:none;opacity:0.9;transform-origin:left}.form-control-wrapper .input-lg ~ .material-input:after,.form-control-wrapper .input-group-lg>.form-control ~ .material-input:after,.form-control-wrapper .input-group-lg>.input-group-addon ~ .material-input:after,.form-control-wrapper .input-group-lg>.input-group-btn>.btn ~ .material-input:after{height:26px}.form-control-wrapper textarea{resize:inherit}.form-control-wrapper textarea ~ .form-control-highlight{margin-top:-11px}.form-control-wrapper .form-control:focus ~ .material-input:after,.form-control-wrapper .form-control.focus ~ .material-input:after{animation:input-highlight 0.3s ease;animation-fill-mode:forwards;opacity:0}.form-control-wrapper select ~ .material-input:after{display:none}.form-group.has-warning .material-input:before,.form-group.has-warning input.form-control:focus ~ .material-input:after,.form-group.has-warning input.form-control.focus ~ .material-input:after{background:#ff5722}.form-group.has-warning .control-label,.form-group.has-warning input.form-control:not(.empty) ~ .floating-label{color:#ff5722}.form-group.has-error .material-input:before,.form-group.has-error input.form-control:focus ~ .material-input:after,.form-group.has-error input.form-control.focus ~ .material-input:after{background:#f44336}.form-group.has-error .control-label,.form-group.has-error input.form-control:not(.empty) ~ .floating-label{color:#f44336}.form-group.has-success .material-input:before,.form-group.has-success input.form-control:focus ~ .material-input:after,.form-group.has-success input.form-control.focus ~ .material-input:after{background:#0f9d58}.form-group.has-success .control-label,.form-group.has-success input.form-control:not(.empty) ~ .floating-label{color:#0f9d58}.form-group.has-info .material-input:before,.form-group.has-info input.form-control:focus ~ .material-input:after,.form-group.has-info input.form-control.focus ~ .material-input:after{background:#03a9f4}.form-group.has-info .control-label,.form-group.has-info input.form-control:not(.empty) ~ .floating-label{color:#03a9f4}.input-group .form-control-wrapper{margin-right:5px;margin-left:5px;bottom:-10px}.input-group .form-control-wrapper .form-control{float:none}.input-group .input-group-addon{border:0}.input-group .input-group-btn .btn{border-radius:4px}select.form-control{border:0;box-shadow:none;border-bottom:1px solid #757575;border-radius:0}select.form-control:focus,select.form-control.focus{box-shadow:none;border-color:#757575}@keyframes input-highlight{0%{left:20%;transform:scaleX(20%)}99%{transform:scaleX(0);left:0;opacity:1}100%{opacity:0}}.form-control-wrapper input[type=file]{opacity:0;position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}legend{border-bottom:0}.modal-content{border-radius:0;border:0}.modal-content .modal-header{border-bottom:0}.modal-content .modal-footer{border-top:0}.modal-content .modal-footer .btn+.btn{margin-bottom:10px}.list-group{border-radius:0}.list-group .list-group-item{background-color:transparent;overflow:hidden;border:0;border-radius:0;padding:0 16px}.list-group .list-group-item .row-picture,.list-group .list-group-item .row-action-primary{float:left;display:inline-block;padding-right:16px}.list-group .list-group-item .row-picture img,.list-group .list-group-item .row-picture i,.list-group .list-group-item .row-picture label,.list-group .list-group-item .row-action-primary img,.list-group .list-group-item .row-action-primary i,.list-group .list-group-item .row-action-primary label{display:block;width:56px;height:56px}.list-group .list-group-item .row-picture img,.list-group .list-group-item .row-action-primary img{background:rgba(0,0,0,0.1);padding:1px}.list-group .list-group-item .row-picture img.circle,.list-group .list-group-item .row-action-primary img.circle{border-radius:100%}.list-group .list-group-item .row-picture i,.list-group .list-group-item .row-action-primary i{background:rgba(0,0,0,0.25);border-radius:100%;text-align:center;line-height:56px;font-size:20px;color:white}.list-group .list-group-item .row-picture label,.list-group .list-group-item .row-action-primary label{margin-left:7px;margin-right:-7px;margin-top:5px;margin-bottom:-5px}.list-group .list-group-item .row-content{display:inline-block;width:calc(100% - 92px);min-height:66px}.list-group .list-group-item .row-content .action-secondary{position:absolute;right:16px;top:16px}.list-group .list-group-item .row-content .action-secondary i{font-size:20px;color:rgba(0,0,0,0.25);cursor:pointer}.list-group .list-group-item .row-content .action-secondary ~ *{max-width:calc(100% - 30px)}.list-group .list-group-item .row-content .least-content{position:absolute;right:16px;top:0px;color:rgba(0,0,0,0.54);font-size:14px}.list-group .list-group-item .list-group-item-heading{color:rgba(0,0,0,0.77);font-size:20px;line-height:29px}.list-group .list-group-separator{clear:both;overflow:hidden;margin-top:10px;margin-bottom:10px}.list-group .list-group-separator:before{content:"";width:calc(100% - 90px);border-bottom:1px solid rgba(0,0,0,0.1);float:right}.navbar{background-color:#12b2e7;border:0;border-radius:0}.navbar .navbar-brand{position:relative;height:60px;line-height:30px;color:rgba(255,255,255,0.84)}.navbar .navbar-brand:hover,.navbar .navbar-brand:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-text{color:rgba(255,255,255,0.84);margin-top:20px;margin-bottom:20px}.navbar .navbar-nav>li>a{color:rgba(255,255,255,0.84);padding-top:20px;padding-bottom:20px}.navbar .navbar-nav>li>a:hover,.navbar .navbar-nav>li>a:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-nav>.active>a,.navbar .navbar-nav>.active>a:hover,.navbar .navbar-nav>.active>a:focus{color:rgba(255,255,255,0.84);background-color:rgba(0,0,0,0.05)}.navbar .navbar-nav>.disabled>a,.navbar .navbar-nav>.disabled>a:hover,.navbar .navbar-nav>.disabled>a:focus{color:#e5e5e5;background-color:transparent}.navbar .navbar-toggle{border-color:rgba(255,255,255,0.84)}.navbar .navbar-toggle:hover,.navbar .navbar-toggle:focus{background-color:transparent}.navbar .navbar-toggle .icon-bar{background-color:rgba(255,255,255,0.84)}.navbar .navbar-collapse,.navbar .navbar-form{border-color:rgba(0,0,0,0.1)}.navbar .navbar-nav>.open>a,.navbar .navbar-nav>.open>a:hover,.navbar .navbar-nav>.open>a:focus{background-color:rgba(0,0,0,0.05);color:rgba(255,255,255,0.84)}@media (max-width: 767px){.navbar .navbar-nav .open .dropdown-menu>.dropdown-header{border:0;color:rgba(212,212,212,0.84)}.navbar .navbar-nav .open .dropdown-menu .divider{background-color:rgba(255,255,255,0.84)}.navbar .navbar-nav .open .dropdown-menu>li>a{color:rgba(255,255,255,0.84)}.navbar .navbar-nav .open .dropdown-menu>li>a:hover,.navbar .navbar-nav .open .dropdown-menu>li>a:focus{color:rgba(255,255,255,0.84);background-color:transparent}.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:rgba(255,255,255,0.84);background-color:rgba(0,0,0,0.05)}.navbar .navbar-nav .open .dropdown-menu>.disabled>a,.navbar .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#e5e5e5;background-color:transparent}}.navbar .navbar-link{color:rgba(255,255,255,0.84)}.navbar .navbar-link:hover{color:rgba(255,255,255,0.84)}.navbar .navbar-link{color:rgba(255,255,255,0.84)}.navbar .navbar-link:hover,.navbar .navbar-link:focus{color:rgba(255,255,255,0.84)}.navbar .navbar-link[disabled]:hover,.navbar .navbar-link[disabled]:focus,fieldset[disabled] .navbar .navbar-link:hover,fieldset[disabled] .navbar .navbar-link:focus{color:#e5e5e5}.navbar .navbar-form{margin-top:16px}.navbar .navbar-form .form-control-wrapper .form-control,.navbar .navbar-form .form-control{border-color:rgba(255,255,255,0.84);color:rgba(255,255,255,0.84)}.navbar .navbar-form .form-control-wrapper .material-input:before,.navbar .navbar-form .form-control-wrapper input:focus ~ .material-input:after{background-color:rgba(255,255,255,0.84)}.navbar .navbar-form ::-webkit-input-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form :-moz-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form ::-moz-placeholder{color:rgba(255,255,255,0.84)}.navbar .navbar-form :-ms-input-placeholder{color:rgba(255,255,255,0.84)}.navbar-inverse{background-color:#5264ae}.navbar-white{background-color:#FFF}.navbar-white .navbar-brand,.navbar-white .navbar-brand:hover,.navbar-white .navbar-brand:focus{color:rgba(0,0,0,0.84)}.navbar-white .navbar-nav>li>a{color:rgba(0,0,0,0.84)}.navbar-white .navbar-nav>li>a:hover,.navbar-white .navbar-nav>li>a:focus{color:rgba(0,0,0,0.84);background-color:transparent}.navbar-white .navbar-nav>.active>a,.navbar-white .navbar-nav>.active>a:hover,.navbar-white .navbar-nav>.active>a:focus{color:rgba(0,0,0,0.84);background-color:rgba(0,0,0,0.05)}.navbar-white .navbar-nav>.disabled>a,.navbar-white .navbar-nav>.disabled>a:hover,.navbar-white .navbar-nav>.disabled>a:focus{color:rgba(0,0,0,0.84);background-color:transparent}.navbar-white .navbar-nav>.open>a,.navbar-white .navbar-nav>.open>a:hover,.navbar-white .navbar-nav>.open>a:focus{background-color:rgba(0,0,0,0.05);color:rgba(0,0,0,0.84)}.navbar-default{background-color:#12b2e7}.navbar-primary{background-color:#12b2e7}.navbar-success{background-color:#0f9d58}.navbar-info{background-color:#03a9f4}.navbar-warning{background-color:#ff5722}.navbar-danger{background-color:#f44336}.navbar-material-red{background-color:#f44336}.navbar-material-pink{background-color:#e91e63}.navbar-material-purple{background-color:#9c27b0}.navbar-material-deeppurple{background-color:#673ab7}.navbar-material-indigo{background-color:#3f51b5}.navbar-material-lightblue{background-color:#03a9f4}.navbar-material-cyan{background-color:#00bcd4}.navbar-material-teal{background-color:#009688}.navbar-material-lightgreen{background-color:#8bc34a}.navbar-material-lime{background-color:#cddc39}.navbar-material-lightyellow{background-color:#ffeb3b}.navbar-material-orange{background-color:#ff9800}.navbar-material-deeporange{background-color:#ff5722}.navbar-material-grey{background-color:#9e9e9e}.navbar-material-bluegrey{background-color:#607d8b}.navbar-material-brown{background-color:#795548}.navbar-material-lightgrey{background-color:#ececec}.dropdown-menu{border:0;box-shadow:0 2px 5px 0 rgba(0,0,0,0.26)}.dropdown-menu .divider{background-color:rgba(229,229,229,0.12)}.dropdown-menu li{overflow:hidden;position:relative}.dropdown-menu li a:hover{background:rgba(0,0,0,0.08)}.alert{border:0px;border-radius:0}.alert a,.alert .alert-link{color:#FFFFFF}.alert-default{background-color:rgba(255,255,255,0.35);color:rgba(0,0,0,0.84)}.alert-default a,.alert-default .alert-link{color:#000000}.alert-primary{color:#FFFFFF;background-color:rgba(18,178,231,0.35);color:rgba(0,0,0,0.84)}.alert-success{color:#FFFFFF;background-color:rgba(15,157,88,0.35);color:rgba(0,0,0,0.84)}.alert-info{color:#FFFFFF;background-color:rgba(3,169,244,0.35);color:rgba(0,0,0,0.84)}.alert-warning{color:#FFFFFF;background-color:rgba(255,87,34,0.35);color:rgba(0,0,0,0.84)}.alert-danger{background-color:rgba(244,67,54,0.35);color:rgba(0,0,0,0.84)}.alert-material-red{background-color:rgba(244,67,54,0.35);color:rgba(0,0,0,0.84)}.alert-material-pink{background-color:rgba(233,30,99,0.35);color:rgba(0,0,0,0.84)}.alert-material-purple{background-color:rgba(156,39,176,0.35);color:rgba(0,0,0,0.84)}.alert-material-deeppurple{background-color:rgba(103,58,183,0.35);color:rgba(0,0,0,0.84)}.alert-material-indigo{background-color:rgba(63,81,181,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightblue{background-color:rgba(3,169,244,0.35);color:rgba(0,0,0,0.84)}.alert-material-cyan{background-color:rgba(0,188,212,0.35);color:rgba(0,0,0,0.84)}.alert-material-teal{background-color:rgba(0,150,136,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightgreen{background-color:rgba(139,195,74,0.35);color:rgba(0,0,0,0.84)}.alert-material-lime{background-color:rgba(205,220,57,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightyellow{background-color:rgba(255,235,59,0.35);color:rgba(0,0,0,0.84)}.alert-material-orange{background-color:rgba(255,152,0,0.35);color:rgba(0,0,0,0.84)}.alert-material-deeporange{background-color:rgba(255,87,34,0.35);color:rgba(0,0,0,0.84)}.alert-material-grey{background-color:rgba(158,158,158,0.35);color:rgba(0,0,0,0.84)}.alert-material-bluegrey{background-color:rgba(96,125,139,0.35);color:rgba(0,0,0,0.84)}.alert-material-brown{background-color:rgba(121,85,72,0.35);color:rgba(0,0,0,0.84)}.alert-material-lightgrey{background-color:rgba(236,236,236,0.35);color:rgba(0,0,0,0.84)}.progress{height:4px;border-radius:0;box-shadow:none;background:#c8c8c8}.progress .progress-bar{box-shadow:none}.progress .progress-bar-default{background-color:#12b2e7}.progress .progress-bar-primary{background-color:#12b2e7}.progress .progress-bar-success{background-color:#0f9d58}.progress .progress-bar-info{background-color:#03a9f4}.progress .progress-bar-warning{background-color:#ff5722}.progress .progress-bar-danger{background-color:#f44336}.progress .progress-bar-material-red{background-color:#f44336}.progress .progress-bar-material-pink{background-color:#e91e63}.progress .progress-bar-material-purple{background-color:#9c27b0}.progress .progress-bar-material-deeppurple{background-color:#673ab7}.progress .progress-bar-material-indigo{background-color:#3f51b5}.progress .progress-bar-material-lightblue{background-color:#03a9f4}.progress .progress-bar-material-cyan{background-color:#00bcd4}.progress .progress-bar-material-teal{background-color:#009688}.progress .progress-bar-material-lightgreen{background-color:#8bc34a}.progress .progress-bar-material-lime{background-color:#cddc39}.progress .progress-bar-material-lightyellow{background-color:#ffeb3b}.progress .progress-bar-material-orange{background-color:#ff9800}.progress .progress-bar-material-deeporange{background-color:#ff5722}.progress .progress-bar-material-grey{background-color:#9e9e9e}.progress .progress-bar-material-bluegrey{background-color:#607d8b}.progress .progress-bar-material-brown{background-color:#795548}.progress .progress-bar-material-lightgrey{background-color:#ececec}.card{border-radius:2px;margin-bottom:20px}.card h1,.card h2,.card h3,.card h4,.card h5,.card h6{font-weight:100;margin:10px 0}.card .card-body{padding:15px}.card .card-actions{padding:15px;text-transform:uppercase}.card .card-actions .main{font-weight:bold}.card .card-actions a{font-size:15px;margin:0 15px 0 0}.card .card-actions a:hover{text-decoration:none}.card img{max-width:100%;max-height:100%}.card .card-footer{padding:15px;border-top:1px solid;border-color:#ececec}.card .card-footer .icon{font-size:25px;transition:ease transform 0.5s}.card .card-footer .icon:hover{text-decoration:none;transform:transform3d(0, 0, 0, -1px)}.card-default{background-color:#fff;color:#000}.card-default .card-footer,.card-default .card-header{border-color:#e6e6e6}.card-default a{color:#000}.card-primary{background-color:#12b2e7;color:#fff}.card-primary .card-footer,.card-primary .card-header{border-color:#ececec}.card-primary a{color:#fff}.card-success{background-color:#0f9d58;color:#fff}.card-success .card-footer,.card-success .card-header{border-color:#0b6e3e}.card-success a{color:#fff}.card-info{background-color:#03a9f4;color:#fff}.card-info .card-footer,.card-info .card-header{border-color:#0286c2}.card-info a{color:#fff}.card-warning{background-color:#ff5722;color:#fff}.card-warning .card-footer,.card-warning .card-header{border-color:#ff7e55}.card-warning a{color:#fff}.card-danger{background-color:#f44336;color:#fff}.card-danger .card-footer,.card-danger .card-header{border-color:#ea1c0d}.card-danger a{color:#fff}.card-material-red{background-color:#f44336;color:#fff}.card-material-red .card-footer,.card-material-red .card-header{border-color:#f77066}.card-material-red a{color:#fff}.card-material-pink{background-color:#e91e63;color:#fff}.card-material-pink .card-footer,.card-material-pink .card-header{border-color:#c1134e}.card-material-pink a{color:#fff}.card-material-purple{background-color:#9c27b0;color:#fff}.card-material-purple .card-footer,.card-material-purple .card-header{border-color:#771e86}.card-material-purple a{color:#fff}.card-material-deeppurple{background-color:#673ab7;color:#fff}.card-material-deeppurple .card-footer,.card-material-deeppurple .card-header{border-color:#8259cb}.card-material-deeppurple a{color:#fff}.card-material-indigo{background-color:#3f51b5;color:#fff}.card-material-indigo .card-footer,.card-material-indigo .card-header{border-color:#606fc7}.card-material-indigo a{color:#fff}.card-material-lightblue{background-color:#03a9f4;color:#fff}.card-material-lightblue .card-footer,.card-material-lightblue .card-header{border-color:#0286c2}.card-material-lightblue a{color:#fff}.card-material-cyan{background-color:#00bcd4;color:#fff}.card-material-cyan .card-footer,.card-material-cyan .card-header{border-color:#008fa1}.card-material-cyan a{color:#fff}.card-material-teal{background-color:#009688;color:#fff}.card-material-teal .card-footer,.card-material-teal .card-header{border-color:#00635a}.card-material-teal a{color:#fff}.card-material-lightgreen{background-color:#8bc34a;color:#fff}.card-material-lightgreen .card-footer,.card-material-lightgreen .card-header{border-color:#71a436}.card-material-lightgreen a{color:#fff}.card-material-lime{background-color:#cddc39;color:#fff}.card-material-lime .card-footer,.card-material-lime .card-header{border-color:#b2c022}.card-material-lime a{color:#fff}.card-material-lightyellow{background-color:#ffeb3b;color:#080700}.card-material-lightyellow .card-footer,.card-material-lightyellow .card-header{border-color:#ffe608}.card-material-lightyellow a{color:#080700}.card-material-orange{background-color:#ff9800;color:#fff}.card-material-orange .card-footer,.card-material-orange .card-header{border-color:#cc7a00}.card-material-orange a{color:#fff}.card-material-deeporange{background-color:#ff5722;color:#fff}.card-material-deeporange .card-footer,.card-material-deeporange .card-header{border-color:#ee3900}.card-material-deeporange a{color:#fff}.card-material-grey{background-color:#9e9e9e;color:#fff}.card-material-grey .card-footer,.card-material-grey .card-header{border-color:#858585}.card-material-grey a{color:#fff}.card-material-bluegrey{background-color:#607d8b;color:#fff}.card-material-bluegrey .card-footer,.card-material-bluegrey .card-header{border-color:#4b626d}.card-material-bluegrey a{color:#fff}.card-material-brown{background-color:#795548;color:#fff}.card-material-brown .card-footer,.card-material-brown .card-header{border-color:#996b5b}.card-material-brown a{color:#fff}.card-material-lightgrey{background-color:#ececec;color:#e6e6e6}.card-material-lightgrey .card-footer,.card-material-lightgrey .card-header{border-color:#d3d3d3}.card-material-lightgrey a{color:#e6e6e6}.text-warning{color:#ff5722}.text-primary{color:#12b2e7}.text-danger{color:#f44336}.text-success{color:#0f9d58}.text-info{color:#03a9f4}.nav-tabs{background:#12b2e7}.nav-tabs>li>a{color:#FFFFFF;border:0;margin:0}.nav-tabs>li>a:hover{background:transparent;border:0}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.open>a,.nav-tabs>li.open>a:hover{background:transparent !important;border:0 !important;color:#FFFFFF !important;font-weight:500}.nav-tabs>li.disabled>a,.nav-tabs>li.disabled>a:hover{color:rgba(255,255,255,0.5)}.popover,.tooltip-inner{background:#323232;color:#FFF;border-radius:2px}.tooltip,.tooltip.in{opacity:1}.popover.left .arrow:after,.popover.left .tooltip-arrow,.tooltip.left .arrow:after,.tooltip.left .tooltip-arrow{border-left-color:#323232}.popover.right .arrow:after,.popover.right .tooltip-arrow,.tooltip.right .arrow:after,.tooltip.right .tooltip-arrow{border-right-color:#323232}.popover.top .arrow:after,.popover.top .tooltip-arrow,.tooltip.top .arrow:after,.tooltip.top .tooltip-arrow{border-top-color:#323232}.popover.bottom .arrow:after,.popover.bottom .tooltip-arrow,.tooltip.bottom .arrow:after,.tooltip.bottom .tooltip-arrow{border-bottom-color:#323232}.icon-default{color:rgba(0,0,0,0.84)}.icon-primary{color:#12b2e7}.icon-success{color:#0f9d58}.icon-info{color:#03a9f4}.icon-warning{color:#ff5722}.icon-danger{color:#f44336}.icon-material-red{color:#f44336}.icon-material-pink{color:#e91e63}.icon-material-purple{color:#9c27b0}.icon-material-deeppurple{color:#673ab7}.icon-material-indigo{color:#3f51b5}.icon-material-lightblue{color:#03a9f4}.icon-material-cyan{color:#00bcd4}.icon-material-teal{color:#009688}.icon-material-lightgreen{color:#8bc34a}.icon-material-lime{color:#cddc39}.icon-material-lightyellow{color:#ffeb3b}.icon-material-orange{color:#ff9800}.icon-material-deeporange{color:#ff5722}.icon-material-grey{color:#9e9e9e}.icon-material-bluegrey{color:#607d8b}.icon-material-brown{color:#795548}.icon-material-lightgrey{color:#ececec}.snackbar{background-color:#323232;color:rgba(255,255,255,0.84);font-size:14px;border-radius:2px;height:0;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, padding 0 linear 0.2s, height 0 linear 0.2s;transform:translateY(200%)}.snackbar.snackbar-opened{padding:14px 15px;margin-bottom:20px;height:auto;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, height 0 linear 0.2s;transform:none}.snackbar.toast{border-radius:200px}.noUi-target,.noUi-target *{-webkit-touch-callout:none;-ms-touch-action:none;user-select:none;box-sizing:border-box}.noUi-base{width:100%;height:100%;position:relative}.noUi-origin{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-handle{position:relative;z-index:1;box-sizing:border-box}.noUi-stacking .noUi-handle{z-index:10}.noUi-stacking+.noUi-origin{*z-index:-1}.noUi-state-tap .noUi-origin{transition:left 0.3s, top 0.3s}.noUi-state-drag *{cursor:inherit !important}.noUi-horizontal{height:10px}.noUi-horizontal .noUi-handle{box-sizing:border-box;width:12px;height:12px;left:-10px;top:-5px}.noUi-horizontal.noUi-extended{padding:0 15px}.noUi-horizontal.noUi-extended .noUi-origin{right:-15px}.noUi-background{height:2px;margin:20px 0}.noUi-origin{margin:0;border-radius:0;height:2px;background:#c8c8c8}.noUi-origin[style^="left: 0"] .noUi-handle{background-color:#fff;border:2px solid #c8c8c8}.noUi-target{border-radius:2px}.noUi-handle{border-radius:100%;cursor:default;transition:all 0.2s ease-out;border:1px solid}.noUi-horizontal{height:2px;margin:15px 0}[disabled].noUi-slider{opacity:0.5}[disabled] .noUi-handle{cursor:not-allowed}.slider{background:#c8c8c8}.withripple{position:relative}.ripple-wrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:2px}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:rgba(0,0,0,0.05);transform:scale(1);transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{transition:opacity 0.15s ease-in 0s,transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;opacity:1}.ripple.ripple-out{transition:opacity 0.1s linear 0s !important;opacity:0}.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-user-select:none;-ms-touch-action:none;-ms-user-select:none;-moz-user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base{width:100%;height:100%;position:relative}.noUi-origin{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-handle{position:relative;z-index:1}.noUi-stacking .noUi-handle{z-index:10}.noUi-stacking+.noUi-origin{*z-index:-1}.noUi-state-tap .noUi-origin{-webkit-transition:left 0.3s, top 0.3s;transition:left 0.3s, top 0.3s}.noUi-state-drag *{cursor:inherit !important}.noUi-base{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}.noUi-connect{-webkit-transition:background 450ms;transition:background 450ms}.noUi-dragable{cursor:w-resize}.noUi-vertical .noUi-dragable{cursor:n-resize}[disabled] .noUi-handle{cursor:not-allowed}.xbbcode-b{font-weight:bold}.xbbcode-center{margin-left:auto;margin-right:auto;display:block;text-align:center}.xbbcode-code{white-space:pre-wrap;font-family:monospace}.xbbcode-i{font-style:italic}.xbbcode-justify{display:block;text-align:justify}.xbbcode-left{display:block;text-align:left}.xbbcode-right{display:block;text-align:right}.xbbcode-s{text-decoration:line-through}.xbbcode-size-4{font-size:4px}.xbbcode-size-5{font-size:5px}.xbbcode-size-6{font-size:6px}.xbbcode-size-7{font-size:7px}.xbbcode-size-8{font-size:8px}.xbbcode-size-9{font-size:9px}.xbbcode-size-10{font-size:10px}.xbbcode-size-11{font-size:11px}.xbbcode-size-12{font-size:12px}.xbbcode-size-13{font-size:13px}.xbbcode-size-14{font-size:14px}.xbbcode-size-15{font-size:15px}.xbbcode-size-16{font-size:16px}.xbbcode-size-17{font-size:17px}.xbbcode-size-18{font-size:18px}.xbbcode-size-19{font-size:19px}.xbbcode-size-20{font-size:20px}.xbbcode-size-21{font-size:21px}.xbbcode-size-22{font-size:22px}.xbbcode-size-23{font-size:23px}.xbbcode-size-24{font-size:24px}.xbbcode-size-25{font-size:25px}.xbbcode-size-26{font-size:26px}.xbbcode-size-27{font-size:27px}.xbbcode-size-28{font-size:28px}.xbbcode-size-29{font-size:29px}.xbbcode-size-30{font-size:30px}.xbbcode-size-31{font-size:31px}.xbbcode-size-32{font-size:32px}.xbbcode-size-33{font-size:33px}.xbbcode-size-34{font-size:34px}.xbbcode-size-35{font-size:35px}.xbbcode-size-36{font-size:36px}.xbbcode-size-37{font-size:37px}.xbbcode-size-38{font-size:38px}.xbbcode-size-39{font-size:39px}.xbbcode-size-40{font-size:40px}.xbbcode-u{text-decoration:underline}.xbbcode-table{border-collapse:collapse}.xbbcode-table,.xbbcode-th,.xbbcode-td{border:1px solid #666}*,*:before,*:after{-webkit-box-sizing:"border-box";-moz-box-sizing:"border-box";box-sizing:"border-box"}img,video{max-width:100%;height:auto}.youtube-list .flat-btn,.filters-container .filter-btn,.filters-container .filter-btn:before,.local-playlist-list .region-first .new-list,.local-playlist-list .region-first .new-list:before,.player .controls-primary .control,.player .controls-secondary .control,.player .slider-bar,.set-page .entity-set .more a,.set-page .entity-set .more a:before,.landing-set .set__more a,.landing-set .set__more a:before,.imdblink,.imdblink:before,.btn-flat-play,.btn-flat-play:before,.btn-flat-add,.btn-flat-add:before,.btn-flat-stream,.btn-flat-stream:before,.btn-flat-download,.btn-flat-download:before,.btn-flat-more,.btn-flat-more:before,.btn-flat-watched,.btn-flat-watched:before{-webkit-transition:0.3s all linear;-o-transition:0.3s all linear;transition:0.3s all linear}@-moz-keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}@-webkit-keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}@keyframes wave{0%{background-position:0% bottom}100%{background-position:100% bottom}}#files-container .loading-box{-webkit-animation:none;-o-animation:none;animation:none}@-moz-keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}@-webkit-keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}@keyframes pulsate{50%{text-shadow:0 0 25px rgba(255,255,255,0.55);color:#fff}}.filters-container .options-search-wrapper,.search-box{position:relative;padding-right:1em}.filters-container .options-search-wrapper:before,.search-box:before{content:"\e65f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .options-search-wrapper:before,.search-box:before{top:8px;left:6px;position:absolute;z-index:20;font-size:130%;opacity:0.8}.filters-container .options-search-wrapper input,.search-box input{color:#666;border:none;width:100%;padding:0.5em;padding-left:2em;background:rgba(255,255,255,0.5);margin-bottom:1em}.filters-container .options-search-wrapper input:focus,.search-box input:focus{background:rgba(255,255,255,0.9);outline:none}.card-detail .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.landing-page .landing-section,.region-content,.landing-set .set__collection,.landing-set .set__more{position:relative;padding:12px 12px 30px 12px}.with-header .landing-page .landing-section,.landing-page .with-header .landing-section,.with-header .region-content,.with-header .landing-set .set__collection,.landing-set .with-header .set__collection,.with-header .landing-set .set__more,.landing-set .with-header .set__more{padding:10px 20px 50px 20px}.edit-form .form-tabs,.form-imageselect__tabs,.folder-layout .folder-container,#modal-window.style-edit-form .form-content-region,.form-imageselect__thumbs,.form-imageselect__loader,.youtube-list li,form .inline-list,.help--page .help--overview--report ul li,.details-header .region-details-top,.content-container.with-sidebar,.section-content,.kodi-remote .secondary-controls,.icon-browser ul{*zoom:1}.edit-form .form-tabs:after,.form-imageselect__tabs:after,.folder-layout .folder-container:after,#modal-window.style-edit-form .form-content-region:after,.form-imageselect__thumbs:after,.form-imageselect__loader:after,.youtube-list li:after,form .inline-list:after,.help--page .help--overview--report ul li:after,.details-header .region-details-top:after,.content-container.with-sidebar:after,.section-content:after,.kodi-remote .secondary-controls:after,.icon-browser ul:after{content:"";display:table;clear:both}.help--page .region-content-wrapper h2,.help--page .region-content-wrapper h3,.help--page .region-content-wrapper h4{margin-top:1.5em}.help--page .region-content-wrapper h2{font-size:1.6em;font-weight:bold;border-bottom:1px dotted #ddd;padding-bottom:0.5em;margin-top:2em}.help--page .region-content-wrapper h3{font-size:1.3em;color:#666;margin-bottom:1em}.help--page .region-content-wrapper h4{font-size:1.2em}.help--page .region-content-wrapper p,.help--page .region-content-wrapper li{line-height:1.8}.help--page .region-content-wrapper ul,.help--page .region-content-wrapper ol{padding-left:1.5em}.help--page .region-content-wrapper ul li,.help--page .region-content-wrapper ol li{list-style:disc;margin:0.5em 0}.help--page .region-content-wrapper ol li{list-style-type:decimal}.help--page .region-content-wrapper code{border:1px solid rgba(186,193,200,0.33);background:rgba(221,221,221,0.5);color:#2b2f30}.help--page .region-content-wrapper code:hover{color:#12b2e7;border-color:#12b2e7}.help--page .region-content-wrapper pre{border:1px dashed #bac1c8;margin:1em;margin-left:0}.help--page .region-content-wrapper pre code{background:none;border:none}.help--page .region-content-wrapper pre code:hover{color:inherit;border-color:inherit}.help--page .region-content-wrapper img{width:100%;max-width:1000px}.options-list,.mobile-menu{margin:0;padding:0}.options-list li,.mobile-menu li{margin:0;padding:0;list-style:none}.sidebar-section h3,.browser-page .region-first h3,.filters-container h3,.local-playlist-list .region-first h3,.region-first .nav-sub h3{font-size:15px;text-transform:uppercase;margin:1em 0;color:#888;font-weight:bold}.text-dim,.folder-layout .empty--page-content{opacity:0.4;font-size:0.85em}.landing-page .region-content h3,.landing-page h3.set-header,.landing-set .set__header{background:rgba(255,255,255,0.75);padding:1em 1em;position:relative}.landing-page .region-content h3,.landing-page h3.set-header,.landing-set .set__header,.landing-page .region-content h3 h2,.landing-page h3.set-header h2,.landing-set .set__header h2,.landing-page .region-content h3 h3,.landing-page h3.set-header h3,.landing-set .set__header h3{font-size:18px;margin:0}.landing-page .region-content h3 h2,.landing-page h3.set-header h2,.landing-set .set__header h2,.landing-page .region-content h3 h3,.landing-page h3.set-header h3,.landing-set .set__header h3{text-transform:capitalize}.empty-result h2,.search-no-result{text-align:center;margin-top:10%;font-size:1.8em;color:#a8a7a6}.modal ul.options{margin:0;padding:0}.modal ul.options li{-webkit-transition:0.2s all linear;-o-transition:0.2s all linear;transition:0.2s all linear;padding:0.5em;border-bottom:1px solid rgba(229,229,229,0.6);cursor:pointer;text-transform:capitalize}.modal ul.options li:hover{background:rgba(229,229,229,0.7)}.modal ul.options li:last-child{border:0}.edit-form .form-tabs,.form-imageselect__tabs{background:#ddd;margin-bottom:1em;padding:0.5em 0.5em 0}.edit-form .form-tabs li,.form-imageselect__tabs li{cursor:pointer;float:left;padding:0.5em 1em}.edit-form .form-tabs li.active,.form-imageselect__tabs li.active{background:#fff;color:#12b2e7}.edit-form .form-tabs li:hover,.form-imageselect__tabs li:hover{color:#12b2e7}.card-grid--square .card{color:#888;width:159px;height:216px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--square .card a{color:#888}.card-grid--square .card .title a{color:#2b2f30}.card-grid--square .card .subtitle{font-size:85%;margin-top:5px}.card-grid--square .card .dropdown i,.card-grid--square .card .actions li,.card-grid--square .card .play{color:rgba(255,255,255,0.8)}.card-grid--square .card .dropdown i:hover,.card-grid--square .card .actions li:hover,.card-grid--square .card .play:hover{color:#fff}.card-grid--square .card .record{color:rgba(255,255,255,0.8)}.card-grid--square .card .record:hover{color:#bf0a07}.card-grid--square .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--square .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:159px;height:159px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--square .card .artwork img{display:block;vertical-align:middle;width:159px;margin-top:0}.card-grid--square .card .artwork .thumb{width:159px;height:159px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--square .card .artwork a{display:block}.card-grid--square .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:216px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--square .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--square .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--square .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--square .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--square .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--square .card .watched,.card-grid--square .thumbs-page .card .watched{display:none}.card-grid--square .is-watched.card .watched{color:#12b2e7}.card-grid--square .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--square .card .meta{position:relative;padding:8px 10px;width:159px}.card-grid--square .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--square .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--square .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--square .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--square .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--square .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--square .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .dropdown{top:5px;right:0;position:absolute}.card-grid--square .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--square .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--square .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--square .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--square .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--square .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--square .card .actions .thumbs,.card-grid--square .disable-thumbs .card .actions .thumbs{display:none}.card-grid--square .card .actions li{float:left;margin-left:3px}.card-grid--square .card .actions li:before{display:table-cell !important}.card-grid--square .card:hover .artwork .thumb:after{opacity:1}.card-grid--square .card:hover .actions,.card-grid--square .card:hover .dropdown i,.card-grid--square .card:hover .play{display:table}.card-grid--square .card:hover .record{display:table}.card-grid--square .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--square .selected.card,.card-grid--square .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--square .selected.card:before,.card-grid--square .active-player-local .selected.card:before{border-color:#db2464}.card-grid--square .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--square .selected.card .current-progress{display:none}.card-grid--square .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--square .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--wide .card{color:#888;width:276px;height:170px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--wide .card a{color:#888}.card-grid--wide .card .title a{color:#2b2f30}.card-grid--wide .card .subtitle{font-size:85%;margin-top:5px}.card-grid--wide .card .dropdown i,.card-grid--wide .card .actions li,.card-grid--wide .card .play{color:rgba(255,255,255,0.8)}.card-grid--wide .card .dropdown i:hover,.card-grid--wide .card .actions li:hover,.card-grid--wide .card .play:hover{color:#fff}.card-grid--wide .card .record{color:rgba(255,255,255,0.8)}.card-grid--wide .card .record:hover{color:#bf0a07}.card-grid--wide .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--wide .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:276px;height:138px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--wide .card .artwork img{display:block;vertical-align:middle;width:276px;margin-top:20%}.card-grid--wide .card .artwork .thumb{width:276px;height:138px;background-position:50% 20%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--wide .card .artwork a{display:block}.card-grid--wide .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:170px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--wide .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--wide .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--wide .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--wide .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--wide .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--wide .card .watched,.card-grid--wide .thumbs-page .card .watched{display:none}.card-grid--wide .is-watched.card .watched{color:#12b2e7}.card-grid--wide .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--wide .card .meta{position:relative;padding:8px 10px;width:276px}.card-grid--wide .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--wide .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--wide .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--wide .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--wide .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--wide .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--wide .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .dropdown{top:5px;right:0;position:absolute}.card-grid--wide .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--wide .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--wide .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--wide .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--wide .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--wide .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--wide .card .actions .thumbs,.card-grid--wide .disable-thumbs .card .actions .thumbs{display:none}.card-grid--wide .card .actions li{float:left;margin-left:3px}.card-grid--wide .card .actions li:before{display:table-cell !important}.card-grid--wide .card:hover .artwork .thumb:after{opacity:1}.card-grid--wide .card:hover .actions,.card-grid--wide .card:hover .dropdown i,.card-grid--wide .card:hover .play{display:table}.card-grid--wide .card:hover .record{display:table}.card-grid--wide .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--wide .selected.card,.card-grid--wide .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--wide .selected.card:before,.card-grid--wide .active-player-local .selected.card:before{border-color:#db2464}.card-grid--wide .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--wide .selected.card .current-progress{display:none}.card-grid--wide .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--wide .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--musicvideo .card,.card-grid--episode .card{color:#888;width:275px;height:196px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--musicvideo .card a,.card-grid--episode .card a{color:#888}.card-grid--musicvideo .card .title a,.card-grid--episode .card .title a{color:#2b2f30}.card-grid--musicvideo .card .subtitle,.card-grid--episode .card .subtitle{font-size:85%;margin-top:5px}.card-grid--musicvideo .card .dropdown i,.card-grid--episode .card .dropdown i,.card-grid--musicvideo .card .actions li,.card-grid--episode .card .actions li,.card-grid--musicvideo .card .play,.card-grid--episode .card .play{color:rgba(255,255,255,0.8)}.card-grid--musicvideo .card .dropdown i:hover,.card-grid--episode .card .dropdown i:hover,.card-grid--musicvideo .card .actions li:hover,.card-grid--episode .card .actions li:hover,.card-grid--musicvideo .card .play:hover,.card-grid--episode .card .play:hover{color:#fff}.card-grid--musicvideo .card .record,.card-grid--episode .card .record{color:rgba(255,255,255,0.8)}.card-grid--musicvideo .card .record:hover,.card-grid--episode .card .record:hover{color:#bf0a07}.card-grid--musicvideo .ph.card,.card-grid--episode .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--musicvideo .card .artwork,.card-grid--episode .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:275px;height:138px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--musicvideo .card .artwork img,.card-grid--episode .card .artwork img{display:block;vertical-align:middle;width:275px;margin-top:50%}.card-grid--musicvideo .card .artwork .thumb,.card-grid--episode .card .artwork .thumb{width:275px;height:138px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--musicvideo .card .artwork a,.card-grid--episode .card .artwork a{display:block}.card-grid--musicvideo .card .artwork .thumb:after,.card-grid--episode .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:196px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--musicvideo .card .entity-progress,.card-grid--episode .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--musicvideo .card .entity-progress .current-progress,.card-grid--episode .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--musicvideo .card .watched-tick,.card-grid--episode .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--musicvideo .card .watched-tick:before,.card-grid--episode .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .watched,.card-grid--episode .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--musicvideo .card .watched:before,.card-grid--episode .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .watched:before,.card-grid--episode .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--musicvideo .card .watched,.card-grid--musicvideo .thumbs-page .card .watched,.thumbs-page .card-grid--episode .card .watched,.card-grid--episode .thumbs-page .card .watched{display:none}.card-grid--musicvideo .is-watched.card .watched,.card-grid--episode .is-watched.card .watched{color:#12b2e7}.card-grid--musicvideo .is-watched.card .watched:before,.card-grid--episode .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .thumb,.card-grid--episode .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--musicvideo .card .meta,.card-grid--episode .card .meta{position:relative;padding:8px 10px;width:275px}.card-grid--musicvideo .card .meta .title,.card-grid--episode .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--musicvideo .card .meta .title:after,.card-grid--episode .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--musicvideo .card .meta .subtitle,.card-grid--episode .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--musicvideo .card .meta .subtitle:after,.card-grid--episode .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--musicvideo .card .play,.card-grid--episode .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--musicvideo .card .play:before,.card-grid--episode .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .play:before,.card-grid--episode .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--musicvideo .card .record,.card-grid--episode .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--musicvideo .card .record:before,.card-grid--episode .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .record:before,.card-grid--episode .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--musicvideo .card .dropdown,.card-grid--episode .card .dropdown{top:5px;right:0;position:absolute}.card-grid--musicvideo .card .dropdown i,.card-grid--episode .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--musicvideo .card .dropdown i:before,.card-grid--episode .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .dropdown i:before,.card-grid--episode .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--musicvideo .card .actions,.card-grid--episode .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--musicvideo .card .actions .thumbs,.card-grid--episode .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--musicvideo .card .actions .thumbs:before,.card-grid--episode .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--musicvideo .card .actions .thumbs:before,.card-grid--episode .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--musicvideo .card .actions .thumbs,.card-grid--musicvideo .disable-thumbs .card .actions .thumbs,.disable-thumbs .card-grid--episode .card .actions .thumbs,.card-grid--episode .disable-thumbs .card .actions .thumbs{display:none}.card-grid--musicvideo .card .actions li,.card-grid--episode .card .actions li{float:left;margin-left:3px}.card-grid--musicvideo .card .actions li:before,.card-grid--episode .card .actions li:before{display:table-cell !important}.card-grid--musicvideo .card:hover .artwork .thumb:after,.card-grid--episode .card:hover .artwork .thumb:after{opacity:1}.card-grid--musicvideo .card:hover .actions,.card-grid--episode .card:hover .actions,.card-grid--musicvideo .card:hover .dropdown i,.card-grid--episode .card:hover .dropdown i,.card-grid--musicvideo .card:hover .play,.card-grid--episode .card:hover .play{display:table}.card-grid--musicvideo .card:hover .record,.card-grid--episode .card:hover .record{display:table}.card-grid--musicvideo .selected.card,.card-grid--episode .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--musicvideo .selected.card,.card-grid--musicvideo .active-player-local .selected.card,.active-player-local .card-grid--episode .selected.card,.card-grid--episode .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--musicvideo .selected.card:before,.card-grid--musicvideo .active-player-local .selected.card:before,.active-player-local .card-grid--episode .selected.card:before,.card-grid--episode .active-player-local .selected.card:before{border-color:#db2464}.card-grid--musicvideo .selected.card:before,.card-grid--episode .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--musicvideo .selected.card .current-progress,.card-grid--episode .selected.card .current-progress{display:none}.card-grid--musicvideo .card .dropdown-menu,.card-grid--episode .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--musicvideo .thumbs-up.card .actions .thumbs,.card-grid--episode .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--tall .card{color:#888;width:159px;height:300px;margin:5px;background:#fff;position:relative;overflow:hidden}.card-grid--tall .card a{color:#888}.card-grid--tall .card .title a{color:#2b2f30}.card-grid--tall .card .subtitle{font-size:85%;margin-top:5px}.card-grid--tall .card .dropdown i,.card-grid--tall .card .actions li,.card-grid--tall .card .play{color:rgba(255,255,255,0.8)}.card-grid--tall .card .dropdown i:hover,.card-grid--tall .card .actions li:hover,.card-grid--tall .card .play:hover{color:#fff}.card-grid--tall .card .record{color:rgba(255,255,255,0.8)}.card-grid--tall .card .record:hover{color:#bf0a07}.card-grid--tall .ph.card{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-grid--tall .card .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:159px;height:235px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-grid--tall .card .artwork img{display:block;vertical-align:middle;width:159px;margin-top:0}.card-grid--tall .card .artwork .thumb{width:159px;height:235px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-grid--tall .card .artwork a{display:block}.card-grid--tall .card .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:300px;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-grid--tall .card .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-grid--tall .card .entity-progress .current-progress{height:2px;background:#12b2e7}.card-grid--tall .card .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-grid--tall .card .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--tall .card .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-grid--tall .card .watched,.card-grid--tall .thumbs-page .card .watched{display:none}.card-grid--tall .is-watched.card .watched{color:#12b2e7}.card-grid--tall .is-watched.card .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-grid--tall .card .meta{position:relative;padding:8px 10px;width:159px}.card-grid--tall .card .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-grid--tall .card .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--tall .card .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-grid--tall .card .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-grid--tall .card .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-grid--tall .card .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-grid--tall .card .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .dropdown{top:5px;right:0;position:absolute}.card-grid--tall .card .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-grid--tall .card .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-grid--tall .card .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-grid--tall .card .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-grid--tall .card .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-grid--tall .card .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-grid--tall .card .actions .thumbs,.card-grid--tall .disable-thumbs .card .actions .thumbs{display:none}.card-grid--tall .card .actions li{float:left;margin-left:3px}.card-grid--tall .card .actions li:before{display:table-cell !important}.card-grid--tall .card:hover .artwork .thumb:after{opacity:1}.card-grid--tall .card:hover .actions,.card-grid--tall .card:hover .dropdown i,.card-grid--tall .card:hover .play{display:table}.card-grid--tall .card:hover .record{display:table}.card-grid--tall .selected.card{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-grid--tall .selected.card,.card-grid--tall .active-player-local .selected.card{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-grid--tall .selected.card:before,.card-grid--tall .active-player-local .selected.card:before{border-color:#db2464}.card-grid--tall .selected.card:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-grid--tall .selected.card .current-progress{display:none}.card-grid--tall .card .dropdown-menu{left:auto;right:0px;top:-7px}.card-grid--tall .thumbs-up.card .actions .thumbs{color:#12b2e7}.card-grid--square .card,.card-grid--wide .card,.card-grid--musicvideo .card,.card-grid--episode .card,.card-grid--tall .card{display:inline-block}body{background:#fff}*{box-sizing:border-box}img{width:100%;max-width:auto;height:auto}ul,ol{margin:0;padding:0}ul li,ol li{margin:0;padding:0;list-style:none}a{color:#12b2e7;cursor:pointer}.hidden{display:none}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:inherit}.form-control-wrapper textarea,.form-control-wrapper textarea.form-control,textarea,textarea.form-control{resize:vertical;height:auto !important}@font-face{font-family:"Material-Design-Icons";src:url("../fonts/material/Material-Design-Icons.eot");src:url("../fonts/material/Material-Design-Icons.eot?#iefix") format("embedded-opentype"),url("../fonts/material/Material-Design-Icons.woff") format("woff"),url("../fonts/material/Material-Design-Icons.ttf") format("truetype");font-weight:normal;font-style:normal}.mdi-action-3d-rotation:before{content:"\e600"}.mdi-action-accessibility:before{content:"\e601"}.mdi-action-account-balance:before{content:"\e602"}.mdi-action-account-balance-wallet:before{content:"\e603"}.mdi-action-account-box:before{content:"\e604"}.mdi-action-account-child:before{content:"\e605"}.mdi-action-account-circle:before{content:"\e606"}.mdi-action-add-shopping-cart:before{content:"\e607"}.mdi-action-alarm:before{content:"\e608"}.mdi-action-alarm-add:before{content:"\e609"}.mdi-action-alarm-off:before{content:"\e60a"}.mdi-action-alarm-on:before{content:"\e60b"}.mdi-action-android:before{content:"\e60c"}.mdi-action-announcement:before{content:"\e60d"}.mdi-action-aspect-ratio:before{content:"\e60e"}.mdi-action-assessment:before{content:"\e60f"}.mdi-action-assignment:before{content:"\e610"}.mdi-action-assignment-ind:before{content:"\e611"}.mdi-action-assignment-late:before{content:"\e612"}.mdi-action-assignment-return:before{content:"\e613"}.mdi-action-assignment-returned:before{content:"\e614"}.mdi-action-assignment-turned-in:before{content:"\e615"}.mdi-action-autorenew:before{content:"\e616"}.mdi-action-backup:before{content:"\e617"}.mdi-action-book:before{content:"\e618"}.mdi-action-bookmark:before{content:"\e619"}.mdi-action-bookmark-outline:before{content:"\e61a"}.mdi-action-bug-report:before{content:"\e61b"}.mdi-action-cached:before{content:"\e61c"}.mdi-action-class:before{content:"\e61d"}.mdi-action-credit-card:before{content:"\e61e"}.mdi-action-dashboard:before{content:"\e61f"}.mdi-action-delete:before{content:"\e620"}.mdi-action-description:before{content:"\e621"}.mdi-action-dns:before{content:"\e622"}.mdi-action-done:before{content:"\e623"}.mdi-action-done-all:before{content:"\e624"}.mdi-action-event:before{content:"\e625"}.mdi-action-exit-to-app:before{content:"\e626"}.mdi-action-explore:before{content:"\e627"}.mdi-action-extension:before{content:"\e628"}.mdi-action-face-unlock:before{content:"\e629"}.mdi-action-favorite:before{content:"\e62a"}.mdi-action-favorite-outline:before{content:"\e62b"}.mdi-action-find-in-page:before{content:"\e62c"}.mdi-action-find-replace:before{content:"\e62d"}.mdi-action-flip-to-back:before{content:"\e62e"}.mdi-action-flip-to-front:before{content:"\e62f"}.mdi-action-get-app:before{content:"\e630"}.mdi-action-grade:before{content:"\e631"}.mdi-action-group-work:before{content:"\e632"}.mdi-action-help:before{content:"\e633"}.mdi-action-highlight-remove:before{content:"\e634"}.mdi-action-history:before{content:"\e635"}.mdi-action-home:before{content:"\e636"}.mdi-action-https:before{content:"\e637"}.mdi-action-info:before{content:"\e638"}.mdi-action-info-outline:before{content:"\e639"}.mdi-action-input:before{content:"\e63a"}.mdi-action-invert-colors:before{content:"\e63b"}.mdi-action-label:before{content:"\e63c"}.mdi-action-label-outline:before{content:"\e63d"}.mdi-action-language:before{content:"\e63e"}.mdi-action-launch:before{content:"\e63f"}.mdi-action-list:before{content:"\e640"}.mdi-action-lock:before{content:"\e641"}.mdi-action-lock-open:before{content:"\e642"}.mdi-action-lock-outline:before{content:"\e643"}.mdi-action-loyalty:before{content:"\e644"}.mdi-action-markunread-mailbox:before{content:"\e645"}.mdi-action-note-add:before{content:"\e646"}.mdi-action-open-in-browser:before{content:"\e647"}.mdi-action-open-in-new:before{content:"\e648"}.mdi-action-open-with:before{content:"\e649"}.mdi-action-pageview:before{content:"\e64a"}.mdi-action-payment:before{content:"\e64b"}.mdi-action-perm-camera-mic:before{content:"\e64c"}.mdi-action-perm-contact-cal:before{content:"\e64d"}.mdi-action-perm-data-setting:before{content:"\e64e"}.mdi-action-perm-device-info:before{content:"\e64f"}.mdi-action-perm-identity:before{content:"\e650"}.mdi-action-perm-media:before{content:"\e651"}.mdi-action-perm-phone-msg:before{content:"\e652"}.mdi-action-perm-scan-wifi:before{content:"\e653"}.mdi-action-picture-in-picture:before{content:"\e654"}.mdi-action-polymer:before{content:"\e655"}.mdi-action-print:before{content:"\e656"}.mdi-action-query-builder:before{content:"\e657"}.mdi-action-question-answer:before{content:"\e658"}.mdi-action-receipt:before{content:"\e659"}.mdi-action-redeem:before{content:"\e65a"}.mdi-action-report-problem:before{content:"\e65b"}.mdi-action-restore:before{content:"\e65c"}.mdi-action-room:before{content:"\e65d"}.mdi-action-schedule:before{content:"\e65e"}.mdi-action-search:before{content:"\e65f"}.mdi-action-settings:before{content:"\e660"}.mdi-action-settings-applications:before{content:"\e661"}.mdi-action-settings-backup-restore:before{content:"\e662"}.mdi-action-settings-bluetooth:before{content:"\e663"}.mdi-action-settings-cell:before{content:"\e664"}.mdi-action-settings-display:before{content:"\e665"}.mdi-action-settings-ethernet:before{content:"\e666"}.mdi-action-settings-input-antenna:before{content:"\e667"}.mdi-action-settings-input-component:before{content:"\e668"}.mdi-action-settings-input-composite:before{content:"\e669"}.mdi-action-settings-input-hdmi:before{content:"\e66a"}.mdi-action-settings-input-svideo:before{content:"\e66b"}.mdi-action-settings-overscan:before{content:"\e66c"}.mdi-action-settings-phone:before{content:"\e66d"}.mdi-action-settings-power:before{content:"\e66e"}.mdi-action-settings-remote:before{content:"\e66f"}.mdi-action-settings-voice:before{content:"\e670"}.mdi-action-shop:before{content:"\e671"}.mdi-action-shopping-basket:before{content:"\e672"}.mdi-action-shopping-cart:before{content:"\e673"}.mdi-action-shop-two:before{content:"\e674"}.mdi-action-speaker-notes:before{content:"\e675"}.mdi-action-spellcheck:before{content:"\e676"}.mdi-action-star-rate:before{content:"\e677"}.mdi-action-stars:before{content:"\e678"}.mdi-action-store:before{content:"\e679"}.mdi-action-subject:before{content:"\e67a"}.mdi-action-swap-horiz:before{content:"\e67b"}.mdi-action-swap-vert:before{content:"\e67c"}.mdi-action-swap-vert-circle:before{content:"\e67d"}.mdi-action-system-update-tv:before{content:"\e67e"}.mdi-action-tab:before{content:"\e67f"}.mdi-action-tab-unselected:before{content:"\e680"}.mdi-action-theaters:before{content:"\e681"}.mdi-action-thumb-down:before{content:"\e682"}.mdi-action-thumbs-up-down:before{content:"\e683"}.mdi-action-thumb-up:before{content:"\e684"}.mdi-action-toc:before{content:"\e685"}.mdi-action-today:before{content:"\e686"}.mdi-action-track-changes:before{content:"\e687"}.mdi-action-translate:before{content:"\e688"}.mdi-action-trending-down:before{content:"\e689"}.mdi-action-trending-neutral:before{content:"\e68a"}.mdi-action-trending-up:before{content:"\e68b"}.mdi-action-turned-in:before{content:"\e68c"}.mdi-action-turned-in-not:before{content:"\e68d"}.mdi-action-verified-user:before{content:"\e68e"}.mdi-action-view-agenda:before{content:"\e68f"}.mdi-action-view-array:before{content:"\e690"}.mdi-action-view-carousel:before{content:"\e691"}.mdi-action-view-column:before{content:"\e692"}.mdi-action-view-day:before{content:"\e693"}.mdi-action-view-headline:before{content:"\e694"}.mdi-action-view-list:before{content:"\e695"}.mdi-action-view-module:before{content:"\e696"}.mdi-action-view-quilt:before{content:"\e697"}.mdi-action-view-stream:before{content:"\e698"}.mdi-action-view-week:before{content:"\e699"}.mdi-action-visibility:before{content:"\e69a"}.mdi-action-visibility-off:before{content:"\e69b"}.mdi-action-wallet-giftcard:before{content:"\e69c"}.mdi-action-wallet-membership:before{content:"\e69d"}.mdi-action-wallet-travel:before{content:"\e69e"}.mdi-action-work:before{content:"\e69f"}.mdi-alert-error:before{content:"\e6a0"}.mdi-alert-warning:before{content:"\e6a1"}.mdi-av-album:before{content:"\e6a2"}.mdi-av-timer:before{content:"\e6a3"}.mdi-av-closed-caption:before{content:"\e6a4"}.mdi-av-equalizer:before{content:"\e6a5"}.mdi-av-explicit:before{content:"\e6a6"}.mdi-av-fast-forward:before{content:"\e6a7"}.mdi-av-fast-rewind:before{content:"\e6a8"}.mdi-av-games:before{content:"\e6a9"}.mdi-av-hearing:before{content:"\e6aa"}.mdi-av-high-quality:before{content:"\e6ab"}.mdi-av-loop:before{content:"\e6ac"}.mdi-av-mic:before{content:"\e6ad"}.mdi-av-mic-none:before{content:"\e6ae"}.mdi-av-mic-off:before{content:"\e6af"}.mdi-av-movie:before{content:"\e6b0"}.mdi-av-my-library-add:before{content:"\e6b1"}.mdi-av-my-library-books:before{content:"\e6b2"}.mdi-av-my-library-music:before{content:"\e6b3"}.mdi-av-new-releases:before{content:"\e6b4"}.mdi-av-not-interested:before{content:"\e6b5"}.mdi-av-pause:before{content:"\e6b6"}.mdi-av-pause-circle-fill:before{content:"\e6b7"}.mdi-av-pause-circle-outline:before{content:"\e6b8"}.mdi-av-play-arrow:before{content:"\e6b9"}.mdi-av-play-circle-fill:before{content:"\e6ba"}.mdi-av-play-circle-outline:before{content:"\e6bb"}.mdi-av-playlist-add:before{content:"\e6bc"}.mdi-av-play-shopping-bag:before{content:"\e6bd"}.mdi-av-queue:before{content:"\e6be"}.mdi-av-queue-music:before{content:"\e6bf"}.mdi-av-radio:before{content:"\e6c0"}.mdi-av-recent-actors:before{content:"\e6c1"}.mdi-av-repeat:before{content:"\e6c2"}.mdi-av-repeat-one:before{content:"\e6c3"}.mdi-av-replay:before{content:"\e6c4"}.mdi-av-shuffle:before{content:"\e6c5"}.mdi-av-skip-next:before{content:"\e6c6"}.mdi-av-skip-previous:before{content:"\e6c7"}.mdi-av-snooze:before{content:"\e6c8"}.mdi-av-stop:before{content:"\e6c9"}.mdi-av-subtitles:before{content:"\e6ca"}.mdi-av-surround-sound:before{content:"\e6cb"}.mdi-av-videocam:before{content:"\e6cc"}.mdi-av-videocam-off:before{content:"\e6cd"}.mdi-av-video-collection:before{content:"\e6ce"}.mdi-av-volume-down:before{content:"\e6cf"}.mdi-av-volume-mute:before{content:"\e6d0"}.mdi-av-volume-off:before{content:"\e6d1"}.mdi-av-volume-up:before{content:"\e6d2"}.mdi-av-web:before{content:"\e6d3"}.mdi-communication-business:before{content:"\e6d4"}.mdi-communication-call:before{content:"\e6d5"}.mdi-communication-call-end:before{content:"\e6d6"}.mdi-communication-call-made:before{content:"\e6d7"}.mdi-communication-call-merge:before{content:"\e6d8"}.mdi-communication-call-missed:before{content:"\e6d9"}.mdi-communication-call-received:before{content:"\e6da"}.mdi-communication-call-split:before{content:"\e6db"}.mdi-communication-chat:before{content:"\e6dc"}.mdi-communication-clear-all:before{content:"\e6dd"}.mdi-communication-comment:before{content:"\e6de"}.mdi-communication-contacts:before{content:"\e6df"}.mdi-communication-dialer-sip:before{content:"\e6e0"}.mdi-communication-dialpad:before{content:"\e6e1"}.mdi-communication-dnd-on:before{content:"\e6e2"}.mdi-communication-email:before{content:"\e6e3"}.mdi-communication-forum:before{content:"\e6e4"}.mdi-communication-import-export:before{content:"\e6e5"}.mdi-communication-invert-colors-off:before{content:"\e6e6"}.mdi-communication-invert-colors-on:before{content:"\e6e7"}.mdi-communication-live-help:before{content:"\e6e8"}.mdi-communication-location-off:before{content:"\e6e9"}.mdi-communication-location-on:before{content:"\e6ea"}.mdi-communication-message:before{content:"\e6eb"}.mdi-communication-messenger:before{content:"\e6ec"}.mdi-communication-no-sim:before{content:"\e6ed"}.mdi-communication-phone:before{content:"\e6ee"}.mdi-communication-portable-wifi-off:before{content:"\e6ef"}.mdi-communication-quick-contacts-dialer:before{content:"\e6f0"}.mdi-communication-quick-contacts-mail:before{content:"\e6f1"}.mdi-communication-ring-volume:before{content:"\e6f2"}.mdi-communication-stay-current-landscape:before{content:"\e6f3"}.mdi-communication-stay-current-portrait:before{content:"\e6f4"}.mdi-communication-stay-primary-landscape:before{content:"\e6f5"}.mdi-communication-stay-primary-portrait:before{content:"\e6f6"}.mdi-communication-swap-calls:before{content:"\e6f7"}.mdi-communication-textsms:before{content:"\e6f8"}.mdi-communication-voicemail:before{content:"\e6f9"}.mdi-communication-vpn-key:before{content:"\e6fa"}.mdi-content-add:before{content:"\e6fb"}.mdi-content-add-box:before{content:"\e6fc"}.mdi-content-add-circle:before{content:"\e6fd"}.mdi-content-add-circle-outline:before{content:"\e6fe"}.mdi-content-archive:before{content:"\e6ff"}.mdi-content-backspace:before{content:"\e700"}.mdi-content-block:before{content:"\e701"}.mdi-content-clear:before{content:"\e702"}.mdi-content-content-copy:before{content:"\e703"}.mdi-content-content-cut:before{content:"\e704"}.mdi-content-content-paste:before{content:"\e705"}.mdi-content-create:before{content:"\e706"}.mdi-content-drafts:before{content:"\e707"}.mdi-content-filter-list:before{content:"\e708"}.mdi-content-flag:before{content:"\e709"}.mdi-content-forward:before{content:"\e70a"}.mdi-content-gesture:before{content:"\e70b"}.mdi-content-inbox:before{content:"\e70c"}.mdi-content-link:before{content:"\e70d"}.mdi-content-mail:before{content:"\e70e"}.mdi-content-markunread:before{content:"\e70f"}.mdi-content-redo:before{content:"\e710"}.mdi-content-remove:before{content:"\e711"}.mdi-content-remove-circle:before{content:"\e712"}.mdi-content-remove-circle-outline:before{content:"\e713"}.mdi-content-reply:before{content:"\e714"}.mdi-content-reply-all:before{content:"\e715"}.mdi-content-report:before{content:"\e716"}.mdi-content-save:before{content:"\e717"}.mdi-content-select-all:before{content:"\e718"}.mdi-content-send:before{content:"\e719"}.mdi-content-sort:before{content:"\e71a"}.mdi-content-text-format:before{content:"\e71b"}.mdi-content-undo:before{content:"\e71c"}.mdi-device-access-alarm:before{content:"\e71d"}.mdi-device-access-alarms:before{content:"\e71e"}.mdi-device-access-time:before{content:"\e71f"}.mdi-device-add-alarm:before{content:"\e720"}.mdi-device-airplanemode-off:before{content:"\e721"}.mdi-device-airplanemode-on:before{content:"\e722"}.mdi-device-battery-20:before{content:"\e723"}.mdi-device-battery-30:before{content:"\e724"}.mdi-device-battery-50:before{content:"\e725"}.mdi-device-battery-60:before{content:"\e726"}.mdi-device-battery-80:before{content:"\e727"}.mdi-device-battery-90:before{content:"\e728"}.mdi-device-battery-alert:before{content:"\e729"}.mdi-device-battery-charging-20:before{content:"\e72a"}.mdi-device-battery-charging-30:before{content:"\e72b"}.mdi-device-battery-charging-50:before{content:"\e72c"}.mdi-device-battery-charging-60:before{content:"\e72d"}.mdi-device-battery-charging-80:before{content:"\e72e"}.mdi-device-battery-charging-90:before{content:"\e72f"}.mdi-device-battery-charging-full:before{content:"\e730"}.mdi-device-battery-full:before{content:"\e731"}.mdi-device-battery-std:before{content:"\e732"}.mdi-device-battery-unknown:before{content:"\e733"}.mdi-device-bluetooth:before{content:"\e734"}.mdi-device-bluetooth-connected:before{content:"\e735"}.mdi-device-bluetooth-disabled:before{content:"\e736"}.mdi-device-bluetooth-searching:before{content:"\e737"}.mdi-device-brightness-auto:before{content:"\e738"}.mdi-device-brightness-high:before{content:"\e739"}.mdi-device-brightness-low:before{content:"\e73a"}.mdi-device-brightness-medium:before{content:"\e73b"}.mdi-device-data-usage:before{content:"\e73c"}.mdi-device-developer-mode:before{content:"\e73d"}.mdi-device-devices:before{content:"\e73e"}.mdi-device-dvr:before{content:"\e73f"}.mdi-device-gps-fixed:before{content:"\e740"}.mdi-device-gps-not-fixed:before{content:"\e741"}.mdi-device-gps-off:before{content:"\e742"}.mdi-device-location-disabled:before{content:"\e743"}.mdi-device-location-searching:before{content:"\e744"}.mdi-device-multitrack-audio:before{content:"\e745"}.mdi-device-network-cell:before{content:"\e746"}.mdi-device-network-wifi:before{content:"\e747"}.mdi-device-nfc:before{content:"\e748"}.mdi-device-now-wallpaper:before{content:"\e749"}.mdi-device-now-widgets:before{content:"\e74a"}.mdi-device-screen-lock-landscape:before{content:"\e74b"}.mdi-device-screen-lock-portrait:before{content:"\e74c"}.mdi-device-screen-lock-rotation:before{content:"\e74d"}.mdi-device-screen-rotation:before{content:"\e74e"}.mdi-device-sd-storage:before{content:"\e74f"}.mdi-device-settings-system-daydream:before{content:"\e750"}.mdi-device-signal-cellular-0-bar:before{content:"\e751"}.mdi-device-signal-cellular-1-bar:before{content:"\e752"}.mdi-device-signal-cellular-2-bar:before{content:"\e753"}.mdi-device-signal-cellular-3-bar:before{content:"\e754"}.mdi-device-signal-cellular-4-bar:before{content:"\e755"}.mdi-device-signal-cellular-connected-no-internet-0-bar:before{content:"\e756"}.mdi-device-signal-cellular-connected-no-internet-1-bar:before{content:"\e757"}.mdi-device-signal-cellular-connected-no-internet-2-bar:before{content:"\e758"}.mdi-device-signal-cellular-connected-no-internet-3-bar:before{content:"\e759"}.mdi-device-signal-cellular-connected-no-internet-4-bar:before{content:"\e75a"}.mdi-device-signal-cellular-no-sim:before{content:"\e75b"}.mdi-device-signal-cellular-null:before{content:"\e75c"}.mdi-device-signal-cellular-off:before{content:"\e75d"}.mdi-device-signal-wifi-0-bar:before{content:"\e75e"}.mdi-device-signal-wifi-1-bar:before{content:"\e75f"}.mdi-device-signal-wifi-2-bar:before{content:"\e760"}.mdi-device-signal-wifi-3-bar:before{content:"\e761"}.mdi-device-signal-wifi-4-bar:before{content:"\e762"}.mdi-device-signal-wifi-off:before{content:"\e763"}.mdi-device-storage:before{content:"\e764"}.mdi-device-usb:before{content:"\e765"}.mdi-device-wifi-lock:before{content:"\e766"}.mdi-device-wifi-tethering:before{content:"\e767"}.mdi-editor-attach-file:before{content:"\e768"}.mdi-editor-attach-money:before{content:"\e769"}.mdi-editor-border-all:before{content:"\e76a"}.mdi-editor-border-bottom:before{content:"\e76b"}.mdi-editor-border-clear:before{content:"\e76c"}.mdi-editor-border-color:before{content:"\e76d"}.mdi-editor-border-horizontal:before{content:"\e76e"}.mdi-editor-border-inner:before{content:"\e76f"}.mdi-editor-border-left:before{content:"\e770"}.mdi-editor-border-outer:before{content:"\e771"}.mdi-editor-border-right:before{content:"\e772"}.mdi-editor-border-style:before{content:"\e773"}.mdi-editor-border-top:before{content:"\e774"}.mdi-editor-border-vertical:before{content:"\e775"}.mdi-editor-format-align-center:before{content:"\e776"}.mdi-editor-format-align-justify:before{content:"\e777"}.mdi-editor-format-align-left:before{content:"\e778"}.mdi-editor-format-align-right:before{content:"\e779"}.mdi-editor-format-bold:before{content:"\e77a"}.mdi-editor-format-clear:before{content:"\e77b"}.mdi-editor-format-color-fill:before{content:"\e77c"}.mdi-editor-format-color-reset:before{content:"\e77d"}.mdi-editor-format-color-text:before{content:"\e77e"}.mdi-editor-format-indent-decrease:before{content:"\e77f"}.mdi-editor-format-indent-increase:before{content:"\e780"}.mdi-editor-format-italic:before{content:"\e781"}.mdi-editor-format-line-spacing:before{content:"\e782"}.mdi-editor-format-list-bulleted:before{content:"\e783"}.mdi-editor-format-list-numbered:before{content:"\e784"}.mdi-editor-format-paint:before{content:"\e785"}.mdi-editor-format-quote:before{content:"\e786"}.mdi-editor-format-size:before{content:"\e787"}.mdi-editor-format-strikethrough:before{content:"\e788"}.mdi-editor-format-textdirection-l-to-r:before{content:"\e789"}.mdi-editor-format-textdirection-r-to-l:before{content:"\e78a"}.mdi-editor-format-underline:before{content:"\e78b"}.mdi-editor-functions:before{content:"\e78c"}.mdi-editor-insert-chart:before{content:"\e78d"}.mdi-editor-insert-comment:before{content:"\e78e"}.mdi-editor-insert-drive-file:before{content:"\e78f"}.mdi-editor-insert-emoticon:before{content:"\e790"}.mdi-editor-insert-invitation:before{content:"\e791"}.mdi-editor-insert-link:before{content:"\e792"}.mdi-editor-insert-photo:before{content:"\e793"}.mdi-editor-merge-type:before{content:"\e794"}.mdi-editor-mode-comment:before{content:"\e795"}.mdi-editor-mode-edit:before{content:"\e796"}.mdi-editor-publish:before{content:"\e797"}.mdi-editor-vertical-align-bottom:before{content:"\e798"}.mdi-editor-vertical-align-center:before{content:"\e799"}.mdi-editor-vertical-align-top:before{content:"\e79a"}.mdi-editor-wrap-text:before{content:"\e79b"}.mdi-file-attachment:before{content:"\e79c"}.mdi-file-cloud:before{content:"\e79d"}.mdi-file-cloud-circle:before{content:"\e79e"}.mdi-file-cloud-done:before{content:"\e79f"}.mdi-file-cloud-download:before{content:"\e7a0"}.mdi-file-cloud-off:before{content:"\e7a1"}.mdi-file-cloud-queue:before{content:"\e7a2"}.mdi-file-cloud-upload:before{content:"\e7a3"}.mdi-file-file-download:before{content:"\e7a4"}.mdi-file-file-upload:before{content:"\e7a5"}.mdi-file-folder:before{content:"\e7a6"}.mdi-file-folder-open:before{content:"\e7a7"}.mdi-file-folder-shared:before{content:"\e7a8"}.mdi-hardware-cast:before{content:"\e7a9"}.mdi-hardware-cast-connected:before{content:"\e7aa"}.mdi-hardware-computer:before{content:"\e7ab"}.mdi-hardware-desktop-mac:before{content:"\e7ac"}.mdi-hardware-desktop-windows:before{content:"\e7ad"}.mdi-hardware-dock:before{content:"\e7ae"}.mdi-hardware-gamepad:before{content:"\e7af"}.mdi-hardware-headset:before{content:"\e7b0"}.mdi-hardware-headset-mic:before{content:"\e7b1"}.mdi-hardware-keyboard:before{content:"\e7b2"}.mdi-hardware-keyboard-alt:before{content:"\e7b3"}.mdi-hardware-keyboard-arrow-down:before{content:"\e7b4"}.mdi-hardware-keyboard-arrow-left:before{content:"\e7b5"}.mdi-hardware-keyboard-arrow-right:before{content:"\e7b6"}.mdi-hardware-keyboard-arrow-up:before{content:"\e7b7"}.mdi-hardware-keyboard-backspace:before{content:"\e7b8"}.mdi-hardware-keyboard-capslock:before{content:"\e7b9"}.mdi-hardware-keyboard-control:before{content:"\e7ba"}.mdi-hardware-keyboard-hide:before{content:"\e7bb"}.mdi-hardware-keyboard-return:before{content:"\e7bc"}.mdi-hardware-keyboard-tab:before{content:"\e7bd"}.mdi-hardware-keyboard-voice:before{content:"\e7be"}.mdi-hardware-laptop:before{content:"\e7bf"}.mdi-hardware-laptop-chromebook:before{content:"\e7c0"}.mdi-hardware-laptop-mac:before{content:"\e7c1"}.mdi-hardware-laptop-windows:before{content:"\e7c2"}.mdi-hardware-memory:before{content:"\e7c3"}.mdi-hardware-mouse:before{content:"\e7c4"}.mdi-hardware-phone-android:before{content:"\e7c5"}.mdi-hardware-phone-iphone:before{content:"\e7c6"}.mdi-hardware-phonelink:before{content:"\e7c7"}.mdi-hardware-phonelink-off:before{content:"\e7c8"}.mdi-hardware-security:before{content:"\e7c9"}.mdi-hardware-sim-card:before{content:"\e7ca"}.mdi-hardware-smartphone:before{content:"\e7cb"}.mdi-hardware-speaker:before{content:"\e7cc"}.mdi-hardware-tablet:before{content:"\e7cd"}.mdi-hardware-tablet-android:before{content:"\e7ce"}.mdi-hardware-tablet-mac:before{content:"\e7cf"}.mdi-hardware-tv:before{content:"\e7d0"}.mdi-hardware-watch:before{content:"\e7d1"}.mdi-image-add-to-photos:before{content:"\e7d2"}.mdi-image-adjust:before{content:"\e7d3"}.mdi-image-assistant-photo:before{content:"\e7d4"}.mdi-image-audiotrack:before{content:"\e7d5"}.mdi-image-blur-circular:before{content:"\e7d6"}.mdi-image-blur-linear:before{content:"\e7d7"}.mdi-image-blur-off:before{content:"\e7d8"}.mdi-image-blur-on:before{content:"\e7d9"}.mdi-image-brightness-1:before{content:"\e7da"}.mdi-image-brightness-2:before{content:"\e7db"}.mdi-image-brightness-3:before{content:"\e7dc"}.mdi-image-brightness-4:before{content:"\e7dd"}.mdi-image-brightness-5:before{content:"\e7de"}.mdi-image-brightness-6:before{content:"\e7df"}.mdi-image-brightness-7:before{content:"\e7e0"}.mdi-image-brush:before{content:"\e7e1"}.mdi-image-camera:before{content:"\e7e2"}.mdi-image-camera-alt:before{content:"\e7e3"}.mdi-image-camera-front:before{content:"\e7e4"}.mdi-image-camera-rear:before{content:"\e7e5"}.mdi-image-camera-roll:before{content:"\e7e6"}.mdi-image-center-focus-strong:before{content:"\e7e7"}.mdi-image-center-focus-weak:before{content:"\e7e8"}.mdi-image-collections:before{content:"\e7e9"}.mdi-image-colorize:before{content:"\e7ea"}.mdi-image-color-lens:before{content:"\e7eb"}.mdi-image-compare:before{content:"\e7ec"}.mdi-image-control-point:before{content:"\e7ed"}.mdi-image-control-point-duplicate:before{content:"\e7ee"}.mdi-image-crop:before{content:"\e7ef"}.mdi-image-crop-3-2:before{content:"\e7f0"}.mdi-image-crop-5-4:before{content:"\e7f1"}.mdi-image-crop-7-5:before{content:"\e7f2"}.mdi-image-crop-16-9:before{content:"\e7f3"}.mdi-image-crop-din:before{content:"\e7f4"}.mdi-image-crop-free:before{content:"\e7f5"}.mdi-image-crop-landscape:before{content:"\e7f6"}.mdi-image-crop-original:before{content:"\e7f7"}.mdi-image-crop-portrait:before{content:"\e7f8"}.mdi-image-crop-square:before{content:"\e7f9"}.mdi-image-dehaze:before{content:"\e7fa"}.mdi-image-details:before{content:"\e7fb"}.mdi-image-edit:before{content:"\e7fc"}.mdi-image-exposure:before{content:"\e7fd"}.mdi-image-exposure-minus-1:before{content:"\e7fe"}.mdi-image-exposure-minus-2:before{content:"\e7ff"}.mdi-image-exposure-plus-1:before{content:"\e800"}.mdi-image-exposure-plus-2:before{content:"\e801"}.mdi-image-exposure-zero:before{content:"\e802"}.mdi-image-filter:before{content:"\e803"}.mdi-image-filter-1:before{content:"\e804"}.mdi-image-filter-2:before{content:"\e805"}.mdi-image-filter-3:before{content:"\e806"}.mdi-image-filter-4:before{content:"\e807"}.mdi-image-filter-5:before{content:"\e808"}.mdi-image-filter-6:before{content:"\e809"}.mdi-image-filter-7:before{content:"\e80a"}.mdi-image-filter-8:before{content:"\e80b"}.mdi-image-filter-9:before{content:"\e80c"}.mdi-image-filter-9-plus:before{content:"\e80d"}.mdi-image-filter-b-and-w:before{content:"\e80e"}.mdi-image-filter-center-focus:before{content:"\e80f"}.mdi-image-filter-drama:before{content:"\e810"}.mdi-image-filter-frames:before{content:"\e811"}.mdi-image-filter-hdr:before{content:"\e812"}.mdi-image-filter-none:before{content:"\e813"}.mdi-image-filter-tilt-shift:before{content:"\e814"}.mdi-image-filter-vintage:before{content:"\e815"}.mdi-image-flare:before{content:"\e816"}.mdi-image-flash-auto:before{content:"\e817"}.mdi-image-flash-off:before{content:"\e818"}.mdi-image-flash-on:before{content:"\e819"}.mdi-image-flip:before{content:"\e81a"}.mdi-image-gradient:before{content:"\e81b"}.mdi-image-grain:before{content:"\e81c"}.mdi-image-grid-off:before{content:"\e81d"}.mdi-image-grid-on:before{content:"\e81e"}.mdi-image-hdr-off:before{content:"\e81f"}.mdi-image-hdr-on:before{content:"\e820"}.mdi-image-hdr-strong:before{content:"\e821"}.mdi-image-hdr-weak:before{content:"\e822"}.mdi-image-healing:before{content:"\e823"}.mdi-image-image:before{content:"\e824"}.mdi-image-image-aspect-ratio:before{content:"\e825"}.mdi-image-iso:before{content:"\e826"}.mdi-image-landscape:before{content:"\e827"}.mdi-image-leak-add:before{content:"\e828"}.mdi-image-leak-remove:before{content:"\e829"}.mdi-image-lens:before{content:"\e82a"}.mdi-image-looks:before{content:"\e82b"}.mdi-image-looks-3:before{content:"\e82c"}.mdi-image-looks-4:before{content:"\e82d"}.mdi-image-looks-5:before{content:"\e82e"}.mdi-image-looks-6:before{content:"\e82f"}.mdi-image-looks-one:before{content:"\e830"}.mdi-image-looks-two:before{content:"\e831"}.mdi-image-loupe:before{content:"\e832"}.mdi-image-movie-creation:before{content:"\e833"}.mdi-image-nature:before{content:"\e834"}.mdi-image-nature-people:before{content:"\e835"}.mdi-image-navigate-:before{content:"\e836"}.mdi-image-navigate-next:before{content:"\e837"}.mdi-image-palette:before{content:"\e838"}.mdi-image-panorama:before{content:"\e839"}.mdi-image-panorama-fisheye:before{content:"\e83a"}.mdi-image-panorama-horizontal:before{content:"\e83b"}.mdi-image-panorama-vertical:before{content:"\e83c"}.mdi-image-panorama-wide-angle:before{content:"\e83d"}.mdi-image-photo:before{content:"\e83e"}.mdi-image-photo-album:before{content:"\e83f"}.mdi-image-photo-camera:before{content:"\e840"}.mdi-image-photo-library:before{content:"\e841"}.mdi-image-portrait:before{content:"\e842"}.mdi-image-remove-red-eye:before{content:"\e843"}.mdi-image-rotate-left:before{content:"\e844"}.mdi-image-rotate-right:before{content:"\e845"}.mdi-image-slideshow:before{content:"\e846"}.mdi-image-straighten:before{content:"\e847"}.mdi-image-style:before{content:"\e848"}.mdi-image-switch-camera:before{content:"\e849"}.mdi-image-switch-video:before{content:"\e84a"}.mdi-image-tag-faces:before{content:"\e84b"}.mdi-image-texture:before{content:"\e84c"}.mdi-image-timelapse:before{content:"\e84d"}.mdi-image-timer:before{content:"\e84e"}.mdi-image-timer-3:before{content:"\e84f"}.mdi-image-timer-10:before{content:"\e850"}.mdi-image-timer-auto:before{content:"\e851"}.mdi-image-timer-off:before{content:"\e852"}.mdi-image-tonality:before{content:"\e853"}.mdi-image-transform:before{content:"\e854"}.mdi-image-tune:before{content:"\e855"}.mdi-image-wb-auto:before{content:"\e856"}.mdi-image-wb-cloudy:before{content:"\e857"}.mdi-image-wb-incandescent:before{content:"\e858"}.mdi-image-wb-iridescent:before{content:"\e859"}.mdi-image-wb-sunny:before{content:"\e85a"}.mdi-maps-beenhere:before{content:"\e85b"}.mdi-maps-directions:before{content:"\e85c"}.mdi-maps-directions-bike:before{content:"\e85d"}.mdi-maps-directions-bus:before{content:"\e85e"}.mdi-maps-directions-car:before{content:"\e85f"}.mdi-maps-directions-ferry:before{content:"\e860"}.mdi-maps-directions-subway:before{content:"\e861"}.mdi-maps-directions-train:before{content:"\e862"}.mdi-maps-directions-transit:before{content:"\e863"}.mdi-maps-directions-walk:before{content:"\e864"}.mdi-maps-flight:before{content:"\e865"}.mdi-maps-hotel:before{content:"\e866"}.mdi-maps-layers:before{content:"\e867"}.mdi-maps-layers-clear:before{content:"\e868"}.mdi-maps-local-airport:before{content:"\e869"}.mdi-maps-local-atm:before{content:"\e86a"}.mdi-maps-local-attraction:before{content:"\e86b"}.mdi-maps-local-bar:before{content:"\e86c"}.mdi-maps-local-cafe:before{content:"\e86d"}.mdi-maps-local-car-wash:before{content:"\e86e"}.mdi-maps-local-convenience-store:before{content:"\e86f"}.mdi-maps-local-drink:before{content:"\e870"}.mdi-maps-local-florist:before{content:"\e871"}.mdi-maps-local-gas-station:before{content:"\e872"}.mdi-maps-local-grocery-store:before{content:"\e873"}.mdi-maps-local-hospital:before{content:"\e874"}.mdi-maps-local-hotel:before{content:"\e875"}.mdi-maps-local-laundry-service:before{content:"\e876"}.mdi-maps-local-library:before{content:"\e877"}.mdi-maps-local-mall:before{content:"\e878"}.mdi-maps-local-movies:before{content:"\e879"}.mdi-maps-local-offer:before{content:"\e87a"}.mdi-maps-local-parking:before{content:"\e87b"}.mdi-maps-local-pharmacy:before{content:"\e87c"}.mdi-maps-local-phone:before{content:"\e87d"}.mdi-maps-local-pizza:before{content:"\e87e"}.mdi-maps-local-play:before{content:"\e87f"}.mdi-maps-local-post-office:before{content:"\e880"}.mdi-maps-local-print-shop:before{content:"\e881"}.mdi-maps-local-restaurant:before{content:"\e882"}.mdi-maps-local-see:before{content:"\e883"}.mdi-maps-local-shipping:before{content:"\e884"}.mdi-maps-local-taxi:before{content:"\e885"}.mdi-maps-location-history:before{content:"\e886"}.mdi-maps-map:before{content:"\e887"}.mdi-maps-my-location:before{content:"\e888"}.mdi-maps-navigation:before{content:"\e889"}.mdi-maps-pin-drop:before{content:"\e88a"}.mdi-maps-place:before{content:"\e88b"}.mdi-maps-rate-review:before{content:"\e88c"}.mdi-maps-restaurant-menu:before{content:"\e88d"}.mdi-maps-satellite:before{content:"\e88e"}.mdi-maps-store-mall-directory:before{content:"\e88f"}.mdi-maps-terrain:before{content:"\e890"}.mdi-maps-traffic:before{content:"\e891"}.mdi-navigation-apps:before{content:"\e892"}.mdi-navigation-arrow-back:before{content:"\e893"}.mdi-navigation-arrow-drop-down:before{content:"\e894"}.mdi-navigation-arrow-drop-down-circle:before{content:"\e895"}.mdi-navigation-arrow-drop-up:before{content:"\e896"}.mdi-navigation-arrow-forward:before{content:"\e897"}.mdi-navigation-cancel:before{content:"\e898"}.mdi-navigation-check:before{content:"\e899"}.mdi-navigation-chevron-left:before{content:"\e89a"}.mdi-navigation-chevron-right:before{content:"\e89b"}.mdi-navigation-close:before{content:"\e89c"}.mdi-navigation-expand-less:before{content:"\e89d"}.mdi-navigation-expand-more:before{content:"\e89e"}.mdi-navigation-fullscreen:before{content:"\e89f"}.mdi-navigation-fullscreen-exit:before{content:"\e8a0"}.mdi-navigation-menu:before{content:"\e8a1"}.mdi-navigation-more-horiz:before{content:"\e8a2"}.mdi-navigation-more-vert:before{content:"\e8a3"}.mdi-navigation-refresh:before{content:"\e8a4"}.mdi-navigation-unfold-less:before{content:"\e8a5"}.mdi-navigation-unfold-more:before{content:"\e8a6"}.mdi-notification-adb:before{content:"\e8a7"}.mdi-notification-bluetooth-audio:before{content:"\e8a8"}.mdi-notification-disc-full:before{content:"\e8a9"}.mdi-notification-dnd-forwardslash:before{content:"\e8aa"}.mdi-notification-do-not-disturb:before{content:"\e8ab"}.mdi-notification-drive-eta:before{content:"\e8ac"}.mdi-notification-event-available:before{content:"\e8ad"}.mdi-notification-event-busy:before{content:"\e8ae"}.mdi-notification-event-note:before{content:"\e8af"}.mdi-notification-folder-special:before{content:"\e8b0"}.mdi-notification-mms:before{content:"\e8b1"}.mdi-notification-more:before{content:"\e8b2"}.mdi-notification-network-locked:before{content:"\e8b3"}.mdi-notification-phone-bluetooth-speaker:before{content:"\e8b4"}.mdi-notification-phone-forwarded:before{content:"\e8b5"}.mdi-notification-phone-in-talk:before{content:"\e8b6"}.mdi-notification-phone-locked:before{content:"\e8b7"}.mdi-notification-phone-missed:before{content:"\e8b8"}.mdi-notification-phone-paused:before{content:"\e8b9"}.mdi-notification-play-download:before{content:"\e8ba"}.mdi-notification-play-install:before{content:"\e8bb"}.mdi-notification-sd-card:before{content:"\e8bc"}.mdi-notification-sim-card-alert:before{content:"\e8bd"}.mdi-notification-sms:before{content:"\e8be"}.mdi-notification-sms-failed:before{content:"\e8bf"}.mdi-notification-sync:before{content:"\e8c0"}.mdi-notification-sync-disabled:before{content:"\e8c1"}.mdi-notification-sync-problem:before{content:"\e8c2"}.mdi-notification-system-update:before{content:"\e8c3"}.mdi-notification-tap-and-play:before{content:"\e8c4"}.mdi-notification-time-to-leave:before{content:"\e8c5"}.mdi-notification-vibration:before{content:"\e8c6"}.mdi-notification-voice-chat:before{content:"\e8c7"}.mdi-notification-vpn-lock:before{content:"\e8c8"}.mdi-social-cake:before{content:"\e8c9"}.mdi-social-domain:before{content:"\e8ca"}.mdi-social-group:before{content:"\e8cb"}.mdi-social-group-add:before{content:"\e8cc"}.mdi-social-location-city:before{content:"\e8cd"}.mdi-social-mood:before{content:"\e8ce"}.mdi-social-notifications:before{content:"\e8cf"}.mdi-social-notifications-none:before{content:"\e8d0"}.mdi-social-notifications-off:before{content:"\e8d1"}.mdi-social-notifications-on:before{content:"\e8d2"}.mdi-social-notifications-paused:before{content:"\e8d3"}.mdi-social-pages:before{content:"\e8d4"}.mdi-social-party-mode:before{content:"\e8d5"}.mdi-social-people:before{content:"\e8d6"}.mdi-social-people-outline:before{content:"\e8d7"}.mdi-social-person:before{content:"\e8d8"}.mdi-social-person-add:before{content:"\e8d9"}.mdi-social-person-outline:before{content:"\e8da"}.mdi-social-plus-one:before{content:"\e8db"}.mdi-social-poll:before{content:"\e8dc"}.mdi-social-public:before{content:"\e8dd"}.mdi-social-school:before{content:"\e8de"}.mdi-social-share:before{content:"\e8df"}.mdi-social-whatshot:before{content:"\e8e0"}.mdi-toggle-check-box:before{content:"\e8e1"}.mdi-toggle-check-box-outline-blank:before{content:"\e8e2"}.mdi-toggle-radio-button-off:before{content:"\e8e3"}.mdi-toggle-radio-button-on:before{content:"\e8e4"}[class^="mdi-"],[class*=" mdi-"],.mdi{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.player .control{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}@font-face{font-family:"icomoon";src:url("../fonts/icomoon/fonts/icomoon.eot");src:url("../fonts/icomoon/fonts/icomoon.eot?#iefix") format("embedded-opentype"),url("../fonts/icomoon/fonts/icomoon.woff") format("woff"),url("../fonts/icomoon/fonts/icomoon.ttf") format("truetype");font-weight:normal;font-style:normal}.icomoon-google:before{content:"\e900"}.icomoon-home:before{content:"\e607"}.icomoon-pencil:before{content:"\e608"}.icomoon-image:before{content:"\e609"}.icomoon-music2:before{content:"\e60a"}.icomoon-headphones:before{content:"\e60b"}.icomoon-play:before{content:"\e60c"}.icomoon-film:before{content:"\e60d"}.icomoon-camera:before{content:"\e60e"}.icomoon-pacman:before{content:"\e60f"}.icomoon-tag:before{content:"\e610"}.icomoon-tags:before{content:"\e611"}.icomoon-location:before{content:"\e612"}.icomoon-screen:before{content:"\e613"}.icomoon-mobile:before{content:"\e614"}.icomoon-tv:before{content:"\e615"}.icomoon-bubble:before{content:"\e616"}.icomoon-bubbles:before{content:"\e617"}.icomoon-user:before{content:"\e618"}.icomoon-spinner:before{content:"\e619"}.icomoon-search:before{content:"\e61a"}.icomoon-key:before{content:"\e61b"}.icomoon-settings:before{content:"\e61c"}.icomoon-cog:before{content:"\e61d"}.icomoon-stats:before{content:"\e61e"}.icomoon-switch:before{content:"\e61f"}.icomoon-tree:before{content:"\e620"}.icomoon-cloud:before{content:"\e621"}.icomoon-earth:before{content:"\e622"}.icomoon-link:before{content:"\e623"}.icomoon-attachment:before{content:"\e624"}.icomoon-star:before{content:"\e625"}.icomoon-star2:before{content:"\e626"}.icomoon-heart:before{content:"\e627"}.icomoon-heart2:before{content:"\e628"}.icomoon-smiley:before{content:"\e629"}.icomoon-smiley2:before{content:"\e62a"}.icomoon-info:before{content:"\e62b"}.icomoon-checkmark:before{content:"\e62c"}.icomoon-arrow-right:before{content:"\e62d"}.icomoon-arrow-left:before{content:"\e62e"}.icomoon-arrow-right2:before{content:"\e62f"}.icomoon-arrow-left2:before{content:"\e630"}.icomoon-share:before{content:"\e631"}.icomoon-googleplus:before{content:"\e632"}.icomoon-facebook:before{content:"\e633"}.icomoon-twitter:before{content:"\e634"}.icomoon-feed:before{content:"\e635"}.icomoon-feed2:before{content:"\e636"}.icomoon-youtube:before{content:"\e637"}.icomoon-picasa:before{content:"\e638"}.icomoon-github:before{content:"\e639"}.icomoon-github2:before{content:"\e63a"}.icomoon-github3:before{content:"\e63b"}.icomoon-tux:before{content:"\e63c"}.icomoon-apple:before{content:"\e63d"}.icomoon-android:before{content:"\e63e"}.icomoon-windows8:before{content:"\e63f"}.icomoon-paypal:before{content:"\e640"}.icomoon-file-zip:before{content:"\e641"}.icomoon-file-css:before{content:"\e642"}.icomoon-imdb:before{content:"\e901"}.icomoon-flatscreen:before{content:"\e600"}.icomoon-clapperboard:before{content:"\e601"}.icomoon-kodi-symbol:before{content:"\e602"}.icomoon-kodi-text:before{content:"\e603"}.icomoon-linux:before{content:"\e604"}.icomoon-music:before{content:"\e605"}.icomoon-pi:before{content:"\e606"}.icomoon-network:before{content:"\e643"}.icomoon-rss:before{content:"\e644"}.icomoon-statistics:before{content:"\e645"}.icomoon-pie:before{content:"\e646"}.icomoon-minus:before{content:"\e647"}.icomoon-plus:before{content:"\e648"}.icomoon-info2:before{content:"\e649"}.icomoon-question:before{content:"\e64a"}.icomoon-help:before{content:"\e64b"}.icomoon-warning:before{content:"\e64c"}.icomoon-list:before{content:"\e64d"}.icomoon-flow-tree:before{content:"\e64e"}.icomoon-arrow-left3:before{content:"\e64f"}.icomoon-arrow-right3:before{content:"\e650"}.icomoon-arrow-left4:before{content:"\e651"}.icomoon-arrow-right4:before{content:"\e652"}.icomoon-arrow-left5:before{content:"\e653"}.icomoon-uniE654:before{content:"\e654"}[class^="icomoon-"],[class*=" icomoon-"],.icomoon{display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#logo{display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.table-hover>tbody>tr:hover,.songs-table tr.song.menu-open,.songs-table tr.song:hover{background-color:rgba(255,255,255,0.3)}.table-hover>tbody>tr:hover .crop,.songs-table tr.song.menu-open .crop,.songs-table tr.song:hover .crop{position:relative;white-space:nowrap;overflow:hidden}.table-hover>tbody>tr:hover .crop:after,.songs-table tr.song.menu-open .crop:after,.songs-table tr.song:hover .crop:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E7E7E7', endColorstr='#FFE7E7E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3ZTdlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlN2U3ZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(231,231,231,0)),color-stop(100%, #e7e7e7));background-image:-moz-linear-gradient(left, rgba(231,231,231,0) 0%,#e7e7e7 100%);background-image:-webkit-linear-gradient(left, rgba(231,231,231,0) 0%,#e7e7e7 100%);background-image:linear-gradient(to right, rgba(231,231,231,0) 0%,#e7e7e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.shadow-z-1,.card,.snackbar,.landing-page .region-content h3,.landing-page h3.set-header,.landing-set .set__header,.card,.snackbar{box-shadow:0 1px 3px rgba(0,0,0,0.04),0 1px 2px rgba(0,0,0,0.05)}.shadow-z-2-hover,.btn:hover:not(.btn-link),.btn:hover:not(.btn-link){box-shadow:0 3px 6px rgba(0,0,0,0.07),0 2px 4px rgba(0,0,0,0.13)}.table-striped>tbody>tr:nth-child(odd){background-color:rgba(255,255,255,0.5)}.table-striped>tbody>tr>td{border:0}.table>tbody>tr>td{border-top:none}.options-list{padding-bottom:0.5em}.options-list>li{border-bottom:1px solid #ddd}.options-list>li:last-child{border:0}.options-list>li>span,.options-list>li>a{display:block;padding:0.5em 1em;cursor:pointer}.options-list>li>span:hover,.options-list>li>a:hover{background:#12b2e7;color:#fff}.options-list>li>span:hover small,.options-list>li>a:hover small{display:inline}.options-list small{font-size:70%;opacity:0.7;display:none}@media (min-width: 57em){.modal.style-options .modal-dialog{width:300px}}.modal.style-options .modal-footer{display:none}.page-padding,.settings-form .form-content-region,.section-lab .page,.api-method--execute{padding:1em}@media (min-width: 57em){.page-padding,.settings-form .form-content-region,.section-lab .page,.api-method--execute{padding:2em;padding-left:3em}} +.page,.page-secondary,.api-method--execute,.help--page .region-content-wrapper .region-content,.settings-form{max-width:58em;margin-left:0;background:#fff}.page-secondary,.api-method--execute{background:rgba(255,255,255,0.5)}.page-wrapper,.help--page .region-content-wrapper{padding:0;margin-bottom:4em}.page-wrapper .region-content,.help--page .region-content-wrapper .region-content{padding:0}.addon-list .region-first,.browser-page .region-first,.category-list .region-first,.filter-pane,.help--page .region-first,.landing-page .region-first,.local-playlist-list .region-first,.pvr-page .region-first,.epg-page .region-first,.search-page-layout .region-first,.settings-page .region-first{padding:1em 1.5em}.sidebar-section h3,.browser-page .region-first h3,.filters-container h3,.local-playlist-list .region-first h3,.region-first .nav-sub h3{font-size:15px;text-transform:uppercase;margin:1em 0;color:#888;font-weight:bold}.sidebar-section,.browser-page .region-first .source-set,.filters-container .nav-list,.filters-container .selection-list,.filters-container .active-list,.region-first .nav-sub{margin-bottom:2em}.sidebar-section ul,.filters-container .nav-list,.filters-container .selection-list,.local-playlist-list .region-first .lists,.region-first .nav-sub .items{padding-left:1em}.sidebar-section ul li,.filters-container .nav-list li,.filters-container .selection-list li,.local-playlist-list .region-first .lists li,.region-first .nav-sub .items li{padding-bottom:0.5em;position:relative;white-space:nowrap;overflow:hidden;cursor:pointer}.sidebar-section ul li:after,.filters-container .nav-list li:after,.filters-container .selection-list li:after,.local-playlist-list .region-first .lists li:after,.region-first .nav-sub .items li:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F2F2F2', endColorstr='#FFF2F2F2');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YyZjJmMiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMmYyZjIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(242,242,242,0)),color-stop(100%, #f2f2f2));background-image:-moz-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:-webkit-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:linear-gradient(to right, rgba(242,242,242,0) 0%,#f2f2f2 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.sidebar-section ul li:hover,.filters-container .nav-list li:hover,.filters-container .selection-list li:hover,.local-playlist-list .region-first .lists li:hover,.region-first .nav-sub .items li:hover{color:#12b2e7}.sidebar-section ul li a,.filters-container .nav-list li a,.filters-container .selection-list li a,.local-playlist-list .region-first .lists li a,.region-first .nav-sub .items li a{color:#2b2f30}.sidebar-section ul li a.active,.filters-container .nav-list li a.active,.filters-container .selection-list li a.active,.local-playlist-list .region-first .lists li a.active,.region-first .nav-sub .items li a.active{color:#12b2e7;font-weight:bold}.active-player-local .sidebar-section ul li a.active,.sidebar-section .active-player-local ul li a.active,.active-player-local .filters-container .nav-list li a.active,.filters-container .active-player-local .nav-list li a.active,.active-player-local .filters-container .selection-list li a.active,.filters-container .active-player-local .selection-list li a.active,.active-player-local .local-playlist-list .region-first .lists li a.active,.local-playlist-list .region-first .active-player-local .lists li a.active,.active-player-local .region-first .nav-sub .items li a.active,.region-first .nav-sub .active-player-local .items li a.active{color:#db2464}.browser-page .region-first .sources{padding-left:1em;padding-left:0.5em}.browser-page .region-first .sources li{padding-bottom:0.5em;position:relative;white-space:nowrap;overflow:hidden;cursor:pointer}.browser-page .region-first .sources li:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F2F2F2', endColorstr='#FFF2F2F2');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YyZjJmMiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMmYyZjIiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(242,242,242,0)),color-stop(100%, #f2f2f2));background-image:-moz-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:-webkit-linear-gradient(left, rgba(242,242,242,0) 0%,#f2f2f2 100%);background-image:linear-gradient(to right, rgba(242,242,242,0) 0%,#f2f2f2 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.browser-page .region-first .sources li:hover{color:#12b2e7}.browser-page .region-first .sources li a{color:#2b2f30}.browser-page .region-first .sources li a.active{color:#12b2e7;font-weight:bold}.active-player-local .browser-page .region-first .sources li a.active,.browser-page .region-first .active-player-local .sources li a.active{color:#db2464}.browser-page .region-first .sources li>div{display:inline-block;padding-left:0.5em}.browser-page .region-first .sources li:before{display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none;opacity:0.3;content:"";font-size:0.9em}@font-face{font-family:"opensans-light";src:url("../fonts/opensans/opensans-light-webfont.eot");src:url("../fonts/opensans/opensans-light-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/opensans/opensans-light-webfont.woff") format("woff"),url("../fonts/opensans/opensans-light-webfont.ttf") format("truetype");font-weight:"normal";font-style:normal}@font-face{font-family:"opensans";src:url("../fonts/opensans/opensans-regular-webfont.eot");src:url("../fonts/opensans/opensans-regular-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/opensans/opensans-regular-webfont.woff") format("woff"),url("../fonts/opensans/opensans-regular-webfont.ttf") format("truetype");font-weight:"normal";font-style:normal}html,body{font-family:"opensans",Helvetica,Arial,sans-serif}body{zoom:0.75}@media (min-width: 25em){body{zoom:0.85}}@media (min-width: 37em){body{zoom:0.95}}@media (min-width: 45em){body{zoom:1}} a{-webkit-transition:all 0.3s linear;-o-transition:all 0.3s linear;transition:all 0.3s linear}a:focus,a:hover{text-decoration:none;outline:none}h1,h2,h3,h4{font-family:"opensans-light",Helvetica,Arial,sans-serif}.inline-links{margin-top:1.5em}.inline-links>li{display:inline-block;margin-right:0.5em}.addon-list .nav-sub li{text-transform:capitalize}.addon-list .card .play{display:none !important}.addon-list .card .subtitle{text-transform:capitalize}.album--with-songs{position:relative;margin-bottom:20px}@media (min-width: 57em){.album--with-songs .region-album-side{position:absolute}}@media (min-width: 57em) and (min-width: 45em){.album--with-songs .region-album-side{width:190px}}@media (min-width: 57em) and (min-width: 75em){.album--with-songs .region-album-side{width:280px}}@media (min-width: 57em){.album--with-songs .region-album-content{max-width:1100px;padding:0 20px 0 0}}@media (min-width: 57em) and (min-width: 45em){.artist-show .album--with-songs .region-album-content{margin-left:190px}}@media (min-width: 57em) and (min-width: 75em){.artist-show .album--with-songs .region-album-content{margin-left:280px}}@media (min-width: 57em) and (min-width: 45em){.album--with-songs .region-album-content{min-height:190px}}@media (min-width: 57em) and (min-width: 75em){.album--with-songs .region-album-content{min-height:280px}}@media (min-width: 57em){.album--with-songs .card-minimal{padding:0 22px 0 0px}} .dropdown-menu{padding:0.5em 0;background:#1b1c1d;color:#999;border-radius:0}.dropdown-menu li{padding:0.25em 1em}.dropdown-menu li:hover{background:rgba(255,255,255,0.1);color:#fff;cursor:pointer}.dropdown-menu li:hover.divider{cursor:none;background:none}.dropdown-menu li.divider{padding:0;margin:0.25em 0}.dropdown-menu li.dropdown-submenu{position:relative;overflow:visible}.dropdown-menu li.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-4px;white-space:nowrap}.dropdown-menu li.dropdown-submenu:hover>.dropdown-menu{display:block}.browser-page .region-first .sources li.type-source:before{content:"\e73e"}.browser-page .region-first .sources li.type-addon:before{content:"\e6b1"}.browser-page .region-first .sources li.type-playlist:before{content:"\e610"}.browser-page .region-content{padding:0}.browser-page .actions{top:1px;right:10px;position:absolute}.browser-page .actions .sort-toggle,.browser-page .actions .context-toggle{display:table;width:30px;text-align:center;cursor:pointer;font-size:1.5em;opacity:0.6}.browser-page .actions .sort-toggle:before,.browser-page .actions .context-toggle:before{content:"\e71a";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.browser-page .actions .sort-toggle:before,.browser-page .actions .context-toggle:before{display:table-cell;vertical-align:middle;height:39px}.browser-page .actions .sort-toggle:hover,.browser-page .actions .context-toggle:hover{opacity:1}.browser-page .actions .context-toggle:before{content:"\e8a3"}.browser-page .actions>li{display:inline-block}.browser-page .actions .dropdown-menu{text-transform:capitalize}.browser-page .sort-wrapper li i:after{content:"\e89e";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.browser-page .sort-wrapper li.order-descending i:after{content:"\e89d";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.browser-page .sort-wrapper li.active{color:#fff}.folder-layout .loading-bar,.folder-layout .path{height:3em;padding-right:5em;background:rgba(0,0,0,0.05)}.loading .folder-layout .loading-bar,.loading .folder-layout .path{display:none}.folder-layout .loading-bar ul,.folder-layout .path ul{display:table}.folder-layout .loading-bar ul li,.folder-layout .path ul li{display:table-cell;vertical-align:middle;height:3em;padding:0 1em;cursor:pointer;border-right:1px dotted rgba(0,0,0,0.05);max-width:300px;overflow:hidden;white-space:nowrap}.folder-layout .loading-bar ul li:last-child,.folder-layout .path ul li:last-child{border:none;font-weight:bold}.folder-layout .loading-bar ul li:last-child:hover,.folder-layout .path ul li:last-child:hover{background:none}.folder-layout .loading-bar ul li:hover,.folder-layout .path ul li:hover{background:rgba(0,0,0,0.05)}.folder-layout .loading-bar{display:none}.loading .folder-layout .loading-bar{display:block}.folder-layout .loading-bar .inner{display:table}.folder-layout .loading-bar .inner span{display:table-cell;vertical-align:middle;height:3em;padding:0 1em}.folder-layout .loading-bar .loader-small-inline{margin:0.7em 0 0 0.7em}.folder-layout .folder-container .folders-pane,.folder-layout .folder-container .files{padding:1em}.folder-layout .folder-container .folders-pane{background:#f9f9f9}@media (min-width: 75em){.folder-layout .folder-container .folders-pane{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:41.6666666667%;float:left}.folder-layout .folder-container .files{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:58.3333333333%;float:right}} -.folder-layout .folder,.folder-layout .file,.folder-layout .back-button,.browser-file-list .folder,.browser-file-list .file,.browser-file-list .back-button,.browser-folder-list .folder,.browser-folder-list .file,.browser-folder-list .back-button{height:42px;position:relative;border-bottom:1px solid #eee}.folder-layout .folder .thumb,.folder-layout .file .thumb,.folder-layout .back-button .thumb,.browser-file-list .folder .thumb,.browser-file-list .file .thumb,.browser-file-list .back-button .thumb,.browser-folder-list .folder .thumb,.browser-folder-list .file .thumb,.browser-folder-list .back-button .thumb{width:40px;height:40px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.folder-layout .folder .thumb,.folder-layout .file .thumb,.folder-layout .back-button .thumb,.browser-file-list .folder .thumb,.browser-file-list .file .thumb,.browser-file-list .back-button .thumb,.browser-folder-list .folder .thumb,.browser-folder-list .file .thumb,.browser-folder-list .back-button .thumb{top:1px;bottom:1px;left:0;position:absolute;z-index:20}.folder-layout .folder .thumb:hover .play,.folder-layout .file .thumb:hover .play,.folder-layout .back-button .thumb:hover .play,.browser-file-list .folder .thumb:hover .play,.browser-file-list .file .thumb:hover .play,.browser-file-list .back-button .thumb:hover .play,.browser-folder-list .folder .thumb:hover .play,.browser-folder-list .file .thumb:hover .play,.browser-folder-list .back-button .thumb:hover .play{display:table}.folder-layout .folder .title,.folder-layout .file .title,.folder-layout .back-button .title,.browser-file-list .folder .title,.browser-file-list .file .title,.browser-file-list .back-button .title,.browser-folder-list .folder .title,.browser-folder-list .file .title,.browser-folder-list .back-button .title{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:0 7px;padding-left:50px;cursor:pointer;line-height:40px}.folder-layout .folder .play,.folder-layout .file .play,.folder-layout .back-button .play,.browser-file-list .folder .play,.browser-file-list .file .play,.browser-file-list .back-button .play,.browser-folder-list .folder .play,.browser-folder-list .file .play,.browser-folder-list .back-button .play{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;display:table;width:40px;text-align:center;cursor:pointer;display:none;color:#fff;font-size:150%}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{display:table-cell;vertical-align:middle;height:40px}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{padding-right:5px}.folder-layout .file .title,.browser-file-list .file .title,.browser-folder-list .file .title{position:relative;white-space:nowrap;overflow:hidden;margin-right:3em}.folder-layout .file .title:after,.browser-file-list .file .title:after,.browser-folder-list .file .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E0DFDF', endColorstr='#FFE0DFDF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2UwZGZkZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlMGRmZGYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(224,223,223,0)),color-stop(100%, #e0dfdf));background-image:-moz-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:-webkit-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:linear-gradient(to right, rgba(224,223,223,0) 0%,#e0dfdf 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.folder-layout .folder,.browser-file-list .folder,.browser-folder-list .folder{position:relative;white-space:nowrap;overflow:hidden}.folder-layout .folder:after,.browser-file-list .folder:after,.browser-folder-list .folder:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F9F9F9', endColorstr='#FFF9F9F9');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmOWY5ZjkiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(249,249,249,0)),color-stop(100%, #f9f9f9));background-image:-moz-linear-gradient(left, rgba(249,249,249,0) 0%,#f9f9f9 100%);background-image:-webkit-linear-gradient(left, rgba(249,249,249,0) 0%,#f9f9f9 100%);background-image:linear-gradient(to right, rgba(249,249,249,0) 0%,#f9f9f9 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.folder-layout .file .menu i,.folder-layout .folder .menu i,.browser-file-list .file .menu i,.browser-file-list .folder .menu i,.browser-folder-list .file .menu i,.browser-folder-list .folder .menu i{font-size:150%}.folder-layout .file .menu i:before,.folder-layout .folder .menu i:before,.browser-file-list .file .menu i:before,.browser-file-list .folder .menu i:before,.browser-folder-list .file .menu i:before,.browser-folder-list .folder .menu i:before{content:"\e8a2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .file .menu .dropdown-menu,.folder-layout .folder .menu .dropdown-menu,.browser-file-list .file .menu .dropdown-menu,.browser-file-list .folder .menu .dropdown-menu,.browser-folder-list .file .menu .dropdown-menu,.browser-folder-list .folder .menu .dropdown-menu{top:0}.folder-layout .file .actions,.folder-layout .folder .actions,.browser-file-list .file .actions,.browser-file-list .folder .actions,.browser-folder-list .file .actions,.browser-folder-list .folder .actions{top:0;right:0px;bottom:0;position:absolute;display:none;width:30px;display:block;z-index:50}.folder-layout .file .actions>li,.folder-layout .folder .actions>li,.browser-file-list .file .actions>li,.browser-file-list .folder .actions>li,.browser-folder-list .file .actions>li,.browser-folder-list .folder .actions>li{width:30px;text-align:center;float:left}.folder-layout .file .actions>li i:before,.folder-layout .file .actions>li:before,.folder-layout .folder .actions>li i:before,.folder-layout .folder .actions>li:before,.browser-file-list .file .actions>li i:before,.browser-file-list .file .actions>li:before,.browser-file-list .folder .actions>li i:before,.browser-file-list .folder .actions>li:before,.browser-folder-list .file .actions>li i:before,.browser-folder-list .file .actions>li:before,.browser-folder-list .folder .actions>li i:before,.browser-folder-list .folder .actions>li:before{display:table-cell;vertical-align:middle;width:30px;height:40px;color:#999;cursor:pointer}.folder-layout .file .actions>li>i,.folder-layout .folder .actions>li>i,.browser-file-list .file .actions>li>i,.browser-file-list .folder .actions>li>i,.browser-folder-list .file .actions>li>i,.browser-folder-list .folder .actions>li>i{opacity:0.4}.folder-layout .back-button i,.browser-file-list .back-button i,.browser-folder-list .back-button i{display:table;width:39px;text-align:center;cursor:pointer}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{content:"\e89a";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{display:table-cell;vertical-align:middle;height:39px}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{background:#DBDBDB;font-size:150%;color:#B5B5B5;width:40px}.card-detail{position:relative}.card-detail .entity-progress{display:none}.card-detail .meta{display:none}.card-detail .card-album,.card-detail .card-artist{width:158px}.card-detail .card-album .artwork,.card-detail .card-album .artwork .thumb,.card-detail .card-artist .artwork,.card-detail .card-artist .artwork .thumb{width:158px;height:158px}@media (min-width: 75em){.card-detail .card-album,.card-detail .card-artist{width:238px}.card-detail .card-album .artwork,.card-detail .card-album .artwork .thumb,.card-detail .card-artist .artwork,.card-detail .card-artist .artwork .thumb{width:238px;height:238px}}.card-detail .card-movie,.card-detail .card-tvshow,.card-detail .card-season{width:158px}.card-detail .card-movie .artwork,.card-detail .card-movie .artwork .thumb,.card-detail .card-tvshow .artwork,.card-detail .card-tvshow .artwork .thumb,.card-detail .card-season .artwork,.card-detail .card-season .artwork .thumb{width:158px;height:236px}@media (min-width: 75em){.card-detail .card-movie,.card-detail .card-tvshow,.card-detail .card-season{width:238px}.card-detail .card-movie .artwork,.card-detail .card-movie .artwork .thumb,.card-detail .card-tvshow .artwork,.card-detail .card-tvshow .artwork .thumb,.card-detail .card-season .artwork,.card-detail .card-season .artwork .thumb{width:238px;height:357px}}.card-detail .card-episode{width:158px}.card-detail .card-episode .artwork,.card-detail .card-episode .artwork .thumb{width:158px;height:99px}@media (min-width: 75em){.card-detail .card-episode{width:238px}.card-detail .card-episode .artwork,.card-detail .card-episode .artwork .thumb{width:238px;height:150px}}.card-detail .actions{top:10px;right:10px;position:absolute;z-index:50}.card-detail .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:200%;color:rgba(255,255,255,0.8);display:none;text-shadow:1px 1px 5px rgba(0,0,0,0.3)}.card-detail .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-detail .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-detail .thumbs{display:none !important}.card-detail.thumbs-up .thumbs{color:rgba(255,255,255,0.6);opacity:1;display:table}.card-detail:hover .thumbs{display:table}.card-detail:hover.thumbs-up .thumbs{color:#12b2e7}.card-minimal{color:#888;width:199px;height:auto;margin:5px;background:#fff;position:relative;overflow:hidden;width:47px;height:auto;width:100%;margin:2em 0 0.5em;padding:0;overflow:visible}.card-minimal a{color:#888}.card-minimal .title a{color:#2b2f30}.card-minimal .subtitle{font-size:85%;margin-top:5px}.card-minimal .dropdown i,.card-minimal .actions li,.card-minimal .play{color:rgba(255,255,255,0.8)}.card-minimal .dropdown i:hover,.card-minimal .actions li:hover,.card-minimal .play:hover{color:#fff}.card-minimal .record{color:rgba(255,255,255,0.8)}.card-minimal .record:hover{color:#bf0a07}.card-minimal.ph{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-minimal .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:199px;height:199px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-minimal .artwork img{display:block;vertical-align:middle;width:199px;margin-top:0}.card-minimal .artwork .thumb{width:199px;height:199px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-minimal .artwork a{display:block}.card-minimal .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:auto;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-minimal .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-minimal .entity-progress .current-progress{height:2px;background:#12b2e7}.card-minimal .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-minimal .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-minimal .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-minimal .watched{display:none}.card-minimal.is-watched .watched{color:#12b2e7}.card-minimal.is-watched .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-minimal .meta{position:relative;padding:8px 10px;width:199px}.card-minimal .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-minimal .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-minimal .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-minimal .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-minimal .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-minimal .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-minimal .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .dropdown{top:5px;right:0;position:absolute}.card-minimal .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-minimal .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-minimal .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-minimal .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-minimal .actions .thumbs{display:none}.card-minimal .actions li{float:left;margin-left:3px}.card-minimal .actions li:before{display:table-cell !important}.card-minimal:hover .artwork .thumb:after{opacity:1}.card-minimal:hover .actions,.card-minimal:hover .dropdown i,.card-minimal:hover .play{display:table}.card-minimal:hover .record{display:table}.card-minimal.selected{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-minimal.selected{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-minimal.selected:before{border-color:#db2464}.card-minimal.selected:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-minimal.selected .current-progress{display:none}.card-minimal .dropdown-menu{left:auto;right:0px;top:-7px}.card-minimal.thumbs-up .actions .thumbs{color:#12b2e7}.card-minimal .artwork,.card-minimal .artwork .thumb{width:47px;height:47px}@media (min-width: 75em){.card-minimal{width:70px}.card-minimal .artwork,.card-minimal .artwork .thumb{width:70px;height:70px}}.card-minimal .artwork{float:left}.card-minimal .dropdown i,.card-minimal ul.actions>li{color:#ddd}.card-minimal .dropdown i:hover,.card-minimal ul.actions>li:hover{color:#b0b0b0}.card-minimal .meta{padding:4px 0 4px 60px}.card-minimal .meta .title:after,.card-minimal .meta .subtitle:after{display:none}@media (min-width: 57em){.card-minimal{width:238px;margin:0;width:158px;background:none}.card-minimal .artwork,.card-minimal .artwork .thumb{width:158px;height:158px}}@media (min-width: 57em) and (min-width: 75em){.card-minimal{width:238px}.card-minimal .artwork,.card-minimal .artwork .thumb{width:238px;height:238px}}@media (min-width: 57em){.card-minimal .artwork{float:none}.card-minimal .meta{padding:0.5em 0}} +.folder-layout .folder,.folder-layout .file,.folder-layout .back-button,.browser-file-list .folder,.browser-file-list .file,.browser-file-list .back-button,.browser-folder-list .folder,.browser-folder-list .file,.browser-folder-list .back-button{height:42px;position:relative;border-bottom:1px solid #eee}.folder-layout .folder .thumb,.folder-layout .file .thumb,.folder-layout .back-button .thumb,.browser-file-list .folder .thumb,.browser-file-list .file .thumb,.browser-file-list .back-button .thumb,.browser-folder-list .folder .thumb,.browser-folder-list .file .thumb,.browser-folder-list .back-button .thumb{width:40px;height:40px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.folder-layout .folder .thumb,.folder-layout .file .thumb,.folder-layout .back-button .thumb,.browser-file-list .folder .thumb,.browser-file-list .file .thumb,.browser-file-list .back-button .thumb,.browser-folder-list .folder .thumb,.browser-folder-list .file .thumb,.browser-folder-list .back-button .thumb{top:1px;bottom:1px;left:0;position:absolute;z-index:20}.folder-layout .folder .thumb:hover .play,.folder-layout .file .thumb:hover .play,.folder-layout .back-button .thumb:hover .play,.browser-file-list .folder .thumb:hover .play,.browser-file-list .file .thumb:hover .play,.browser-file-list .back-button .thumb:hover .play,.browser-folder-list .folder .thumb:hover .play,.browser-folder-list .file .thumb:hover .play,.browser-folder-list .back-button .thumb:hover .play{display:table}.folder-layout .folder .title,.folder-layout .file .title,.folder-layout .back-button .title,.browser-file-list .folder .title,.browser-file-list .file .title,.browser-file-list .back-button .title,.browser-folder-list .folder .title,.browser-folder-list .file .title,.browser-folder-list .back-button .title{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:0 7px;padding-left:50px;cursor:pointer;line-height:40px}.folder-layout .folder .play,.folder-layout .file .play,.folder-layout .back-button .play,.browser-file-list .folder .play,.browser-file-list .file .play,.browser-file-list .back-button .play,.browser-folder-list .folder .play,.browser-folder-list .file .play,.browser-folder-list .back-button .play{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;display:table;width:40px;text-align:center;cursor:pointer;display:none;color:#fff;font-size:150%}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{display:table-cell;vertical-align:middle;height:40px}.folder-layout .folder .play:before,.folder-layout .file .play:before,.folder-layout .back-button .play:before,.browser-file-list .folder .play:before,.browser-file-list .file .play:before,.browser-file-list .back-button .play:before,.browser-folder-list .folder .play:before,.browser-folder-list .file .play:before,.browser-folder-list .back-button .play:before{padding-right:5px}.folder-layout .file .title,.browser-file-list .file .title,.browser-folder-list .file .title{position:relative;white-space:nowrap;overflow:hidden;margin-right:3em}.folder-layout .file .title:after,.browser-file-list .file .title:after,.browser-folder-list .file .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E0DFDF', endColorstr='#FFE0DFDF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2UwZGZkZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlMGRmZGYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(224,223,223,0)),color-stop(100%, #e0dfdf));background-image:-moz-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:-webkit-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:linear-gradient(to right, rgba(224,223,223,0) 0%,#e0dfdf 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.folder-layout .folder,.browser-file-list .folder,.browser-folder-list .folder{position:relative;white-space:nowrap;overflow:hidden}.folder-layout .folder:after,.browser-file-list .folder:after,.browser-folder-list .folder:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F9F9F9', endColorstr='#FFF9F9F9');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmOWY5ZjkiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(249,249,249,0)),color-stop(100%, #f9f9f9));background-image:-moz-linear-gradient(left, rgba(249,249,249,0) 0%,#f9f9f9 100%);background-image:-webkit-linear-gradient(left, rgba(249,249,249,0) 0%,#f9f9f9 100%);background-image:linear-gradient(to right, rgba(249,249,249,0) 0%,#f9f9f9 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.folder-layout .file .menu i,.folder-layout .folder .menu i,.browser-file-list .file .menu i,.browser-file-list .folder .menu i,.browser-folder-list .file .menu i,.browser-folder-list .folder .menu i{font-size:150%}.folder-layout .file .menu i:before,.folder-layout .folder .menu i:before,.browser-file-list .file .menu i:before,.browser-file-list .folder .menu i:before,.browser-folder-list .file .menu i:before,.browser-folder-list .folder .menu i:before{content:"\e8a2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .file .menu .dropdown-menu,.folder-layout .folder .menu .dropdown-menu,.browser-file-list .file .menu .dropdown-menu,.browser-file-list .folder .menu .dropdown-menu,.browser-folder-list .file .menu .dropdown-menu,.browser-folder-list .folder .menu .dropdown-menu{top:0}.folder-layout .file .actions,.folder-layout .folder .actions,.browser-file-list .file .actions,.browser-file-list .folder .actions,.browser-folder-list .file .actions,.browser-folder-list .folder .actions{top:0;right:0px;bottom:0;position:absolute;display:none;width:30px;display:block;z-index:50}.folder-layout .file .actions>li,.folder-layout .folder .actions>li,.browser-file-list .file .actions>li,.browser-file-list .folder .actions>li,.browser-folder-list .file .actions>li,.browser-folder-list .folder .actions>li{width:30px;text-align:center;float:left}.folder-layout .file .actions>li i:before,.folder-layout .file .actions>li:before,.folder-layout .folder .actions>li i:before,.folder-layout .folder .actions>li:before,.browser-file-list .file .actions>li i:before,.browser-file-list .file .actions>li:before,.browser-file-list .folder .actions>li i:before,.browser-file-list .folder .actions>li:before,.browser-folder-list .file .actions>li i:before,.browser-folder-list .file .actions>li:before,.browser-folder-list .folder .actions>li i:before,.browser-folder-list .folder .actions>li:before{display:table-cell;vertical-align:middle;width:30px;height:40px;color:#999;cursor:pointer}.folder-layout .file .actions>li>i,.folder-layout .folder .actions>li>i,.browser-file-list .file .actions>li>i,.browser-file-list .folder .actions>li>i,.browser-folder-list .file .actions>li>i,.browser-folder-list .folder .actions>li>i{opacity:0.4}.folder-layout .back-button i,.browser-file-list .back-button i,.browser-folder-list .back-button i{display:table;width:39px;text-align:center;cursor:pointer}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{content:"\e89a";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{display:table-cell;vertical-align:middle;height:39px}.folder-layout .back-button i:before,.browser-file-list .back-button i:before,.browser-folder-list .back-button i:before{background:#DBDBDB;font-size:150%;color:#B5B5B5;width:40px}.card-detail{position:relative}.card-detail .entity-progress{display:none}.card-detail .meta{display:none}.card-detail .card-album,.card-detail .card-artist{width:158px}.card-detail .card-album .artwork,.card-detail .card-album .artwork .thumb,.card-detail .card-artist .artwork,.card-detail .card-artist .artwork .thumb{width:158px;height:158px}@media (min-width: 75em){.card-detail .card-album,.card-detail .card-artist{width:238px}.card-detail .card-album .artwork,.card-detail .card-album .artwork .thumb,.card-detail .card-artist .artwork,.card-detail .card-artist .artwork .thumb{width:238px;height:238px}}.card-detail .card-movie,.card-detail .card-tvshow,.card-detail .card-season{width:158px}.card-detail .card-movie .artwork,.card-detail .card-movie .artwork .thumb,.card-detail .card-tvshow .artwork,.card-detail .card-tvshow .artwork .thumb,.card-detail .card-season .artwork,.card-detail .card-season .artwork .thumb{width:158px;height:236px}@media (min-width: 75em){.card-detail .card-movie,.card-detail .card-tvshow,.card-detail .card-season{width:238px}.card-detail .card-movie .artwork,.card-detail .card-movie .artwork .thumb,.card-detail .card-tvshow .artwork,.card-detail .card-tvshow .artwork .thumb,.card-detail .card-season .artwork,.card-detail .card-season .artwork .thumb{width:238px;height:357px}}.card-detail .card-musicvideo,.card-detail .card-episode{width:158px}.card-detail .card-musicvideo .artwork,.card-detail .card-musicvideo .artwork .thumb,.card-detail .card-episode .artwork,.card-detail .card-episode .artwork .thumb{width:158px;height:99px}@media (min-width: 75em){.card-detail .card-musicvideo,.card-detail .card-episode{width:238px}.card-detail .card-musicvideo .artwork,.card-detail .card-musicvideo .artwork .thumb,.card-detail .card-episode .artwork,.card-detail .card-episode .artwork .thumb{width:238px;height:150px}}.card-detail .actions{top:10px;right:10px;position:absolute;z-index:50}.card-detail .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:200%;color:rgba(255,255,255,0.8);display:none;text-shadow:1px 1px 5px rgba(0,0,0,0.3)}.card-detail .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-detail .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-detail .thumbs{display:none !important}.card-detail.thumbs-up .thumbs{color:rgba(255,255,255,0.6);opacity:1;display:table}.card-detail:hover .thumbs{display:table}.card-detail:hover.thumbs-up .thumbs{color:#12b2e7}.card-minimal{color:#888;width:199px;height:auto;margin:5px;background:#fff;position:relative;overflow:hidden;width:47px;height:auto;width:100%;margin:2em 0 0.5em;padding:0;overflow:visible}.card-minimal a{color:#888}.card-minimal .title a{color:#2b2f30}.card-minimal .subtitle{font-size:85%;margin-top:5px}.card-minimal .dropdown i,.card-minimal .actions li,.card-minimal .play{color:rgba(255,255,255,0.8)}.card-minimal .dropdown i:hover,.card-minimal .actions li:hover,.card-minimal .play:hover{color:#fff}.card-minimal .record{color:rgba(255,255,255,0.8)}.card-minimal .record:hover{color:#bf0a07}.card-minimal.ph{opacity:0.1;-webkit-box-shadow:none;box-shadow:none}.card-minimal .artwork{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:199px;height:199px;position:relative;background:#ccc 50% 50% no-repeat;background-size:cover}.card-minimal .artwork img{display:block;vertical-align:middle;width:199px;margin-top:0}.card-minimal .artwork .thumb{width:199px;height:199px;background-position:50% 0;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.card-minimal .artwork a{display:block}.card-minimal .artwork .thumb:after{content:"";top:0;right:0;left:0;position:absolute;height:auto;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;opacity:0;-webkit-transition:0.1s all linear;-o-transition:0.1s all linear;transition:0.1s all linear}.card-minimal .entity-progress{right:0;bottom:0;left:0;position:absolute;top:auto;z-index:20}.card-minimal .entity-progress .current-progress{height:2px;background:#12b2e7}.card-minimal .watched-tick{color:#12b2e7;right:10px;bottom:3px;position:absolute;font-size:125%;display:none}.card-minimal .watched-tick:before{content:"\e899";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .watched{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-minimal .watched:before{content:"\e8e2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .watched:before{display:table-cell;vertical-align:middle;height:1.5em}.thumbs-page .card-minimal .watched{display:none}.card-minimal.is-watched .watched{color:#12b2e7}.card-minimal.is-watched .watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .thumb{display:block;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.card-minimal .meta{position:relative;padding:8px 10px;width:199px}.card-minimal .meta .title{position:relative;white-space:nowrap;overflow:hidden}.card-minimal .meta .title:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-minimal .meta .subtitle{position:relative;white-space:nowrap;overflow:hidden}.card-minimal .meta .subtitle:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card-minimal .play{display:table;width:1.5em;text-align:center;cursor:pointer;bottom:0;left:0;position:absolute;font-size:220%;display:none;z-index:20}.card-minimal .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .play:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .record{display:table;width:1.5em;text-align:center;cursor:pointer;right:10px;bottom:7px;position:absolute;font-size:150%;display:none;z-index:20}.card-minimal .record:before{content:"\e7da";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .record:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .dropdown{top:5px;right:0;position:absolute}.card-minimal .dropdown i{display:table;width:1.5em;text-align:center;cursor:pointer;z-index:20;font-size:180%;display:none}.card-minimal .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.card-minimal .actions{top:10px;right:35px;position:absolute;display:table;display:none}.card-minimal .actions .thumbs{display:table;width:1.5em;text-align:center;cursor:pointer;font-size:135%}.card-minimal .actions .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.card-minimal .actions .thumbs:before{display:table-cell;vertical-align:middle;height:1.5em}.disable-thumbs .card-minimal .actions .thumbs{display:none}.card-minimal .actions li{float:left;margin-left:3px}.card-minimal .actions li:before{display:table-cell !important}.card-minimal:hover .artwork .thumb:after{opacity:1}.card-minimal:hover .actions,.card-minimal:hover .dropdown i,.card-minimal:hover .play{display:table}.card-minimal:hover .record{display:table}.card-minimal.selected{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .card-minimal.selected{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .card-minimal.selected:before{border-color:#db2464}.card-minimal.selected:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.card-minimal.selected .current-progress{display:none}.card-minimal .dropdown-menu{left:auto;right:0px;top:-7px}.card-minimal.thumbs-up .actions .thumbs{color:#12b2e7}.card-minimal .artwork,.card-minimal .artwork .thumb{width:47px;height:47px}@media (min-width: 75em){.card-minimal{width:70px}.card-minimal .artwork,.card-minimal .artwork .thumb{width:70px;height:70px}}.card-minimal .artwork{float:left}.card-minimal .dropdown i,.card-minimal ul.actions>li{color:#ddd}.card-minimal .dropdown i:hover,.card-minimal ul.actions>li:hover{color:#b0b0b0}.card-minimal .meta{padding:4px 0 4px 60px}.card-minimal .meta .title:after,.card-minimal .meta .subtitle:after{display:none}@media (min-width: 57em){.card-minimal{width:238px;margin:0;width:158px;background:none}.card-minimal .artwork,.card-minimal .artwork .thumb{width:158px;height:158px}}@media (min-width: 57em) and (min-width: 75em){.card-minimal{width:238px}.card-minimal .artwork,.card-minimal .artwork .thumb{width:238px;height:238px}}@media (min-width: 57em){.card-minimal .artwork{float:none}.card-minimal .meta{padding:0.5em 0}} .card.category{height:50px;width:185px}.card.category a{padding:1em 0.5em;display:block;position:relative;white-space:nowrap;overflow:hidden}.card.category a:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.card.category:hover{background:#e5e5e5}.card.category:hover a{position:relative;white-space:nowrap;overflow:hidden}.card.category:hover a:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E5E5E5', endColorstr='#FFE5E5E5');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U1ZTVlNSIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlNWU1ZTUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(229,229,229,0)),color-stop(100%, #e5e5e5));background-image:-moz-linear-gradient(left, rgba(229,229,229,0) 0%,#e5e5e5 100%);background-image:-webkit-linear-gradient(left, rgba(229,229,229,0) 0%,#e5e5e5 100%);background-image:linear-gradient(to right, rgba(229,229,229,0) 0%,#e5e5e5 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}@media (min-width: 45em){.edit-form .form-tabs,.edit-form.with-tabs .form-groups{height:420px;overflow-y:auto}} .edit-form .form-item{*zoom:1;margin-bottom:1em}.edit-form .form-item:after{content:"";display:table;clear:both}.edit-form label{color:#666}.edit-form .form-control{padding:7px;background:#fafafa;height:auto !important;border-bottom-color:#ddd}.edit-form .form-control:focus{border-bottom-color:#12b2e7;background:#f0fafe}.edit-form .form-control[type="date"]{padding-bottom:5px}.edit-form .form-groups{padding:1em}.edit-form.with-tabs .group-title{display:none}@media (min-width: 45em){.edit-form.with-tabs .form-tabs{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:28.5714285714%;float:left;-webkit-box-shadow:inset 1px 1px 8px 0 rgba(43,47,48,0.1);box-shadow:inset 1px 1px 8px 0 rgba(43,47,48,0.1);padding:1em 0 1em 0.5em;margin-bottom:0}.edit-form.with-tabs .form-tabs li{float:none}.edit-form.with-tabs .form-tabs li.active{-webkit-box-shadow:1px 1px 8px 0 rgba(43,47,48,0.1);box-shadow:1px 1px 8px 0 rgba(43,47,48,0.1)}.edit-form.with-tabs .form-groups{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:71.4285714286%;float:right;padding-bottom:0}}.edit-form textarea{min-height:115px}.edit-form .form-edit-file textarea{padding:0.5em;border:none}#modal-window.style-edit-form .modal-body{padding:0}#modal-window.style-edit-form form footer{margin-top:0}#modal-window.style-edit-form form footer .inline-list{padding:0 2em}#modal-window.style-edit-form .modal-title span{color:rgba(255,255,255,0.5)}#modal-window.style-edit-form .modal-title span:after{content:": "}@media (min-width: 45em){#modal-window.style-edit-form .modal-dialog{width:700px}} -.form-imageselect__tabs{margin:-1em -1em 1em;background:#e5e5e5;padding-left:1em}.form-imageselect__panes .pane{display:none}.form-imageselect__panes .pane.active{display:block}.form-imageselect__thumbs li{float:left;margin:0 0.5em 0.5em 0;cursor:pointer;width:106px;overflow:hidden}.form-imageselect__thumbs li.selected{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .form-imageselect__thumbs li.selected{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .form-imageselect__thumbs li.selected:before{border-color:#db2464}.form-imageselect__thumbs li.selected:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.form-imageselect__thumbs li.selected .current-progress{display:none}.form-edit-fanart .form-imageselect__thumbs li{width:222px}.form-imageselect__thumbs img{height:160px;width:auto}.form-edit-fanart .form-imageselect__thumbs img{height:125px}.form-imageselect__loader{display:none;margin:1em 0;border-radius:3px;padding:0.5em;color:#999}.form-imageselect__loader .loader-small-inline{margin-right:0.5em;float:left}.form-imageselect__loader span{display:inline-block;line-height:20px;height:20px}.images-loading .form-imageselect__loader{display:block}.empty-result{text-align:center}.empty-result .empty-actions{margin-top:1em;font-size:120%}.youtube-list .thumb{width:120px;float:left;margin-right:1em}.youtube-list li{margin-bottom:0.5em}.youtube-list h3{font-size:18px;padding-top:0.25em;margin-bottom:1em}.youtube-list .flat-btn{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#bac1c8;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;margin-right:0.5em;display:inline-block;padding:0.3em 1em}.youtube-list .flat-btn .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.youtube-list .flat-btn .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00BAC1C8', endColorstr='#FFBAC1C8');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2JhYzFjOCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiYWMxYzgiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(186,193,200,0)),color-stop(100%, #bac1c8));background-image:-moz-linear-gradient(left, rgba(186,193,200,0) 0%,#bac1c8 100%);background-image:-webkit-linear-gradient(left, rgba(186,193,200,0) 0%,#bac1c8 100%);background-image:linear-gradient(to right, rgba(186,193,200,0) 0%,#bac1c8 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.youtube-list .flat-btn:hover{color:#fff}.with-filters .layout-container>.region-first{overflow:hidden}.filters-loading .with-filters .region-content-wrapper .region-content{opacity:0.3}.filters-container .nav-list a,.filters-container .nav-list .option,.filters-container .selection-list a,.filters-container .selection-list .option{color:#2b2f30;cursor:pointer}.filters-container .nav-list a.active,.filters-container .nav-list .option.active,.filters-container .selection-list a.active,.filters-container .selection-list .option.active{color:#12b2e7;font-weight:bold}.active-player-local .filters-container .nav-list a.active,.active-player-local .filters-container .nav-list .option.active,.active-player-local .filters-container .selection-list a.active,.active-player-local .filters-container .selection-list .option.active{color:#db2464}.filters-container .selection-list a,.filters-container .selection-list .option{text-transform:capitalize}.filters-container .sortable.active{position:relative}.filters-container .sortable.active.order-asc:after{content:"\e89e";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .sortable.active.order-desc:after{content:"\e89d";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .sortable.active:after{font-size:130%;padding-left:0.25em;position:absolute;margin-top:1px}.filters-container .filter-btn{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em;display:block}.filters-container .filter-btn .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.filters-container .filter-btn .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.filters-container .filter-btn:hover{color:#fff}.filters-container .filter-btn:before{content:"\e898";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filter-btn:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.filters-container .filter-btn:hover:before{color:#fff}.filters-container .filter-btn.filterable-add{display:inline-block;background-color:#a8a7a6}.filters-container .filter-btn.filterable-add:hover{background-color:#12b2e7}.active-player-local .filters-container .filter-btn.filterable-add:hover{background-color:#db2464}.filters-container .filter-btn.filterable-add:before{content:"\e6fd";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filters-page h3,.filters-container .filters-options h3{cursor:pointer;padding-left:1em;position:relative}.filters-container .filters-page h3:before,.filters-container .filters-options h3:before{content:"\e89a";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filters-page h3:before,.filters-container .filters-options h3:before{font-size:140%;position:absolute;left:-12px;top:-3px}.filters-container .filters-page h3:hover:before,.filters-container .filters-options h3:hover:before{color:#12b2e7}.active-player-local .filters-container .filters-page h3:hover:before,.active-player-local .filters-container .filters-options h3:hover:before{color:#db2464}.filters-container .open-filters{position:relative}.filters-container .open-filters i{top:-3px;right:3px;position:absolute;cursor:pointer;font-size:150%;display:none}.filters-container .open-filters i:before{content:"\e6fb";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .open-filters:hover i{color:#2b2f30}.filters-container .deselect-all{margin:0 0 0.5em 1em;cursor:pointer}.filters-active-bar{-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.15);box-shadow:0 3px 6px -4px rgba(0,0,0,0.15);position:fixed;margin-left:0;left:0;top:50px;right:0;background:#fff;padding:0.75em;text-align:center;z-index:20;display:none}@media (min-width: 57em){.filters-active-bar{margin-left:50px}}@media (min-width: 57em){.filters-active-bar{left:190px}}@media (min-width: 75em){.filters-active-bar{left:250px}}.shell-playlist-closed .filters-active-bar{right:0}@media (min-width: 57em){.filters-active-bar{right:310px}.shell-playlist-closed .filters-active-bar{right:50px}}@media (min-width: 75em){.filters-active-bar{right:400px}.shell-playlist-closed .filters-active-bar{right:50px}}.shell-playlist-closed .filters-active-bar{right:0}@media (min-width: 57em){.shell-playlist-closed .filters-active-bar{right:50px}}@media (min-width: 75em){.shell-playlist-closed .filters-active-bar{right:50px}}.filters-active-bar .remove{top:0;right:0;bottom:0;position:absolute;display:table;width:2em;text-align:center;cursor:pointer;font-size:150%;opacity:0.5}.filters-active-bar .remove:before{content:"\e702";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-active-bar .remove:before{display:table-cell;vertical-align:middle;height:2em}.filters-active-bar .remove:hover{opacity:1}.filters-active-bar .filters-active-all{display:block;margin:0 2em;position:relative;white-space:nowrap;overflow:hidden;text-transform:capitalize}.filters-active-bar .filters-active-all:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.layout-container.filters-active .filters-active-bar{display:block}.layout-container.filters-active .region-content{padding-top:3.5em}.layout-container.filters-active .filters-container .open-filters i{display:block}.is-loading{opacity:0.5}.filter-pane{top:0;right:0;bottom:0;left:0;position:absolute;-webkit-transition:0.2s all ease-out;-o-transition:0.2s all ease-out;transition:0.2s all ease-out;overflow-y:auto}.filter-pane.filters-current{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}.show-filters .filter-pane.filters-current{-moz-transform:translate(-240px, 0);-ms-transform:translate(-240px, 0);-webkit-transform:translate(-240px, 0);transform:translate(-240px, 0)}.show-options .filter-pane.filters-current{-moz-transform:translate(-480px, 0);-ms-transform:translate(-480px, 0);-webkit-transform:translate(-480px, 0);transform:translate(-480px, 0)}.filter-pane.filters-page{-moz-transform:translate(240px, 0);-ms-transform:translate(240px, 0);-webkit-transform:translate(240px, 0);transform:translate(240px, 0)}.show-filters .filter-pane.filters-page{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}.show-options .filter-pane.filters-page{-moz-transform:translate(-240px, 0);-ms-transform:translate(-240px, 0);-webkit-transform:translate(-240px, 0);transform:translate(-240px, 0)}.filter-pane.filters-options{-moz-transform:translate(480px, 0);-ms-transform:translate(480px, 0);-webkit-transform:translate(480px, 0);transform:translate(480px, 0)}.show-filters .filter-pane.filters-options{-moz-transform:translate(240px, 0);-ms-transform:translate(240px, 0);-webkit-transform:translate(240px, 0);transform:translate(240px, 0)}.show-options .filter-pane.filters-options{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}form .form-control-wrapper .form-control:focus,form .form-control-wrapper .form-control{padding:0.5em 0.25em;height:auto;margin-bottom:0.5em}.help-block{margin-top:8px;font-size:90%;color:#C0C0C0}.form-type-hidden{display:none}form .inline-list li{display:inline-block;margin-right:2em;float:left}form .inline-list .response{padding-top:18px}.form-type-hide{display:none}.form-item-half-width{width:50%;float:left;padding-right:0.5em}.active-player-kodi #header{background:#1e2122}.active-player-kodi #logo{color:#12b2e7;background:#1e2122}.active-player-local #header{background:#313233}.active-player-local #logo{color:#db2464;background:#313233}#header{color:rgba(255,255,255,0.6);position:fixed;top:0;left:0;right:0;height:50px;z-index:51;right:0}.shell-playlist-closed #header{right:0}@media (min-width: 57em){#header{right:310px}.shell-playlist-closed #header{right:50px}}@media (min-width: 75em){#header{right:400px}.shell-playlist-closed #header{right:50px}}.shell-playlist-closed #header{right:0}@media (min-width: 57em){.shell-playlist-closed #header{right:50px}}@media (min-width: 75em){.shell-playlist-closed #header{right:50px}}#header .search-toggle{position:absolute}#header .search-toggle i{display:table;width:50px;text-align:center;cursor:pointer}#header .search-toggle i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#header .search-toggle i:before{display:table-cell;vertical-align:middle;height:50px}#selected-region{display:none;position:absolute;top:0;height:50px;right:100%}@media (min-width: 57em){#selected-region{right:200px}}#selected-region .menu-toggle{font-size:150%;display:table;width:50px;text-align:center;cursor:pointer;float:right}#selected-region .menu-toggle:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#selected-region .menu-toggle:before{display:table-cell;vertical-align:middle;height:50px}#selected-region .dropdown-menu{margin:0}#selected-region .selected-text{display:inline-block;height:50px;line-height:50px}#selected-region.media-video .selected-watched,#selected-region.media-video .selected-unwatched{display:block}#selected-region.media-video .selected-localadd{display:none}#selected-region.media-audio .selected-watched,#selected-region.media-audio .selected-unwatched{display:none}#selected-region.media-audio .selected-localadd{display:block}#page-title{margin:0;line-height:50px;font-size:1.3em}#page-title .context a,#page-title .title{padding:0 0 0 0.5em}#search-region{top:50px;right:0;left:0;position:absolute;display:none}body.section-search #search-region{display:block}@media (min-width: 57em){#search-region{top:0;left:auto}} +.form-imageselect__tabs{margin:-1em -1em 1em;background:#e5e5e5;padding-left:1em}.form-imageselect__panes .pane{display:none}.form-imageselect__panes .pane.active{display:block}.form-imageselect__thumbs li{float:left;margin:0 0.5em 0.5em 0;cursor:pointer;overflow:hidden;background:#a8a7a6 50% 50% no-repeat;background-size:cover}.form-imageselect__thumbs li.selected{outline:2px solid #12b2e7;box-shadow:0 0 10px 1px rgba(18,178,231,0.5);position:relative}.active-player-local .form-imageselect__thumbs li.selected{outline:2px solid #db2464;box-shadow:0 0 10px 1px rgba(219,36,100,0.5)}.active-player-local .form-imageselect__thumbs li.selected:before{border-color:#db2464}.form-imageselect__thumbs li.selected:before{right:-10px;bottom:-10px;position:absolute;transform:rotate(-45deg);content:'';width:0;height:0;border:10px solid transparent;border-top-color:#12b2e7}.form-imageselect__thumbs li.selected .current-progress{display:none}.form-imageselect__thumbs li,.form-item-poster-size .form-imageselect__thumbs li{width:106px;height:160px}.form-item-fanart-size .form-imageselect__thumbs li,.form-edit-fanart .form-imageselect__thumbs li{width:222px;height:125px}.form-imageselect__loader{display:none;margin:1em 0;border-radius:3px;padding:0.5em;color:#999}.form-imageselect__loader .loader-small-inline{margin-right:0.5em;float:left}.form-imageselect__loader span{display:inline-block;line-height:20px;height:20px}.images-loading .form-imageselect__loader{display:block}.empty-result{text-align:center}.empty-result .empty-actions{margin-top:1em;font-size:120%}.youtube-list .thumb{width:120px;float:left;margin-right:1em}.youtube-list li{margin-bottom:0.5em}.youtube-list h3{font-size:18px;padding-top:0.25em;margin-bottom:1em}.youtube-list .flat-btn{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#bac1c8;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;margin-right:0.5em;display:inline-block;padding:0.3em 1em}.youtube-list .flat-btn .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.youtube-list .flat-btn .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00BAC1C8', endColorstr='#FFBAC1C8');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2JhYzFjOCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiYWMxYzgiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(186,193,200,0)),color-stop(100%, #bac1c8));background-image:-moz-linear-gradient(left, rgba(186,193,200,0) 0%,#bac1c8 100%);background-image:-webkit-linear-gradient(left, rgba(186,193,200,0) 0%,#bac1c8 100%);background-image:linear-gradient(to right, rgba(186,193,200,0) 0%,#bac1c8 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.youtube-list .flat-btn:hover{color:#fff}.with-filters .layout-container>.region-first{overflow:hidden}.filters-loading .with-filters .region-content-wrapper .region-content{opacity:0.3}.filters-container .nav-list a,.filters-container .nav-list .option,.filters-container .selection-list a,.filters-container .selection-list .option{color:#2b2f30;cursor:pointer}.filters-container .nav-list a.active,.filters-container .nav-list .option.active,.filters-container .selection-list a.active,.filters-container .selection-list .option.active{color:#12b2e7;font-weight:bold}.active-player-local .filters-container .nav-list a.active,.active-player-local .filters-container .nav-list .option.active,.active-player-local .filters-container .selection-list a.active,.active-player-local .filters-container .selection-list .option.active{color:#db2464}.filters-container .selection-list a,.filters-container .selection-list .option{text-transform:capitalize}.filters-container .sortable.active{position:relative}.filters-container .sortable.active.order-asc:after{content:"\e89e";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .sortable.active.order-desc:after{content:"\e89d";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .sortable.active:after{font-size:130%;padding-left:0.25em;position:absolute;margin-top:1px}.filters-container .filter-btn{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em;display:block}.filters-container .filter-btn .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.filters-container .filter-btn .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.filters-container .filter-btn:hover{color:#fff}.filters-container .filter-btn:before{content:"\e898";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filter-btn:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.filters-container .filter-btn:hover:before{color:#fff}.filters-container .filter-btn.filterable-add{display:inline-block;background-color:#a8a7a6}.filters-container .filter-btn.filterable-add:hover{background-color:#12b2e7}.active-player-local .filters-container .filter-btn.filterable-add:hover{background-color:#db2464}.filters-container .filter-btn.filterable-add:before{content:"\e6fd";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filters-page h3,.filters-container .filters-options h3{cursor:pointer;padding-left:1em;position:relative}.filters-container .filters-page h3:before,.filters-container .filters-options h3:before{content:"\e89a";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .filters-page h3:before,.filters-container .filters-options h3:before{font-size:140%;position:absolute;left:-12px;top:-3px}.filters-container .filters-page h3:hover:before,.filters-container .filters-options h3:hover:before{color:#12b2e7}.active-player-local .filters-container .filters-page h3:hover:before,.active-player-local .filters-container .filters-options h3:hover:before{color:#db2464}.filters-container .open-filters{position:relative}.filters-container .open-filters i{top:-3px;right:3px;position:absolute;cursor:pointer;font-size:150%;display:none}.filters-container .open-filters i:before{content:"\e6fb";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-container .open-filters:hover i{color:#2b2f30}.filters-container .deselect-all{margin:0 0 0.5em 1em;cursor:pointer}.filters-active-bar{-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.15);box-shadow:0 3px 6px -4px rgba(0,0,0,0.15);position:fixed;margin-left:0;left:0;top:50px;right:0;background:#fff;padding:0.75em;text-align:center;z-index:20;display:none}@media (min-width: 57em){.filters-active-bar{margin-left:50px}}@media (min-width: 57em){.filters-active-bar{left:190px}}@media (min-width: 75em){.filters-active-bar{left:250px}}.shell-playlist-closed .filters-active-bar{right:0}@media (min-width: 57em){.filters-active-bar{right:310px}.shell-playlist-closed .filters-active-bar{right:50px}}@media (min-width: 75em){.filters-active-bar{right:400px}.shell-playlist-closed .filters-active-bar{right:50px}}.shell-playlist-closed .filters-active-bar{right:0}@media (min-width: 57em){.shell-playlist-closed .filters-active-bar{right:50px}}@media (min-width: 75em){.shell-playlist-closed .filters-active-bar{right:50px}}.filters-active-bar .remove{top:0;right:0;bottom:0;position:absolute;display:table;width:2em;text-align:center;cursor:pointer;font-size:150%;opacity:0.5}.filters-active-bar .remove:before{content:"\e702";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.filters-active-bar .remove:before{display:table-cell;vertical-align:middle;height:2em}.filters-active-bar .remove:hover{opacity:1}.filters-active-bar .filters-active-all{display:block;margin:0 2em;position:relative;white-space:nowrap;overflow:hidden;text-transform:capitalize}.filters-active-bar .filters-active-all:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.layout-container.filters-active .filters-active-bar{display:block}.layout-container.filters-active .region-content{padding-top:3.5em}.layout-container.filters-active .filters-container .open-filters i{display:block}.is-loading{opacity:0.5}.filter-pane{top:0;right:0;bottom:0;left:0;position:absolute;-webkit-transition:0.2s all ease-out;-o-transition:0.2s all ease-out;transition:0.2s all ease-out;overflow-y:auto}.filter-pane.filters-current{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}.show-filters .filter-pane.filters-current{-moz-transform:translate(-240px, 0);-ms-transform:translate(-240px, 0);-webkit-transform:translate(-240px, 0);transform:translate(-240px, 0)}.show-options .filter-pane.filters-current{-moz-transform:translate(-480px, 0);-ms-transform:translate(-480px, 0);-webkit-transform:translate(-480px, 0);transform:translate(-480px, 0)}.filter-pane.filters-page{-moz-transform:translate(240px, 0);-ms-transform:translate(240px, 0);-webkit-transform:translate(240px, 0);transform:translate(240px, 0)}.show-filters .filter-pane.filters-page{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}.show-options .filter-pane.filters-page{-moz-transform:translate(-240px, 0);-ms-transform:translate(-240px, 0);-webkit-transform:translate(-240px, 0);transform:translate(-240px, 0)}.filter-pane.filters-options{-moz-transform:translate(480px, 0);-ms-transform:translate(480px, 0);-webkit-transform:translate(480px, 0);transform:translate(480px, 0)}.show-filters .filter-pane.filters-options{-moz-transform:translate(240px, 0);-ms-transform:translate(240px, 0);-webkit-transform:translate(240px, 0);transform:translate(240px, 0)}.show-options .filter-pane.filters-options{-moz-transform:translate(0, 0);-ms-transform:translate(0, 0);-webkit-transform:translate(0, 0);transform:translate(0, 0)}form .form-control-wrapper .form-control:focus,form .form-control-wrapper .form-control{padding:0.5em 0.25em;height:auto;margin-bottom:0.5em}.help-block{margin-top:8px;font-size:90%;color:#C0C0C0}.form-type-hidden{display:none}form .inline-list li{display:inline-block;margin-right:2em;float:left}form .inline-list .response{padding-top:18px}.form-type-hide{display:none}.form-item-half-width{width:50%;float:left;padding-right:0.5em}.active-player-kodi #header{background:#1e2122}.active-player-kodi #logo{color:#12b2e7;background:#1e2122}.active-player-local #header{background:#313233}.active-player-local #logo{color:#db2464;background:#313233}#header{color:rgba(255,255,255,0.6);position:fixed;top:0;left:0;right:0;height:50px;z-index:51;right:0}.shell-playlist-closed #header{right:0}@media (min-width: 57em){#header{right:310px}.shell-playlist-closed #header{right:50px}}@media (min-width: 75em){#header{right:400px}.shell-playlist-closed #header{right:50px}}.shell-playlist-closed #header{right:0}@media (min-width: 57em){.shell-playlist-closed #header{right:50px}}@media (min-width: 75em){.shell-playlist-closed #header{right:50px}}#header .search-toggle{position:absolute}#header .search-toggle i{display:table;width:50px;text-align:center;cursor:pointer}#header .search-toggle i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#header .search-toggle i:before{display:table-cell;vertical-align:middle;height:50px}#selected-region{display:none;position:absolute;top:0;height:50px;right:100%}@media (min-width: 57em){#selected-region{right:200px}}#selected-region .menu-toggle{font-size:150%;display:table;width:50px;text-align:center;cursor:pointer;float:right}#selected-region .menu-toggle:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#selected-region .menu-toggle:before{display:table-cell;vertical-align:middle;height:50px}#selected-region .dropdown-menu{margin:0}#selected-region .selected-text{display:inline-block;height:50px;line-height:50px}#selected-region.media-video .selected-watched,#selected-region.media-video .selected-unwatched{display:block}#selected-region.media-video .selected-localadd{display:none}#selected-region.media-audio .selected-watched,#selected-region.media-audio .selected-unwatched{display:none}#selected-region.media-audio .selected-localadd{display:block}#page-title{margin:0;line-height:50px;font-size:1.3em}#page-title .context a,#page-title .title{padding:0 0 0 0.5em}#search-region{top:50px;right:0;left:0;position:absolute;display:none}body.section-search #search-region{display:block}@media (min-width: 57em){#search-region{top:0;left:auto}} .mobile-menu{top:0;right:0;position:absolute}.mobile-menu li{display:inline-block;margin:0;width:50px;height:50px}.mobile-menu i{display:table;width:50px;text-align:center;cursor:pointer;color:rgba(255,255,255,0.6);font-size:120%}.mobile-menu i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.mobile-menu i:before{display:table-cell;vertical-align:middle;height:50px}@media (min-width: 57em){.mobile-menu{display:none}} .mobile-menu--link__remote i:before{content:"\e66f"}.section-remote .mobile-menu--link__remote i:before{color:#fff}.mobile-menu--link__search i:before{content:"\e65f"}.section-search .mobile-menu--link__search i:before{color:#fff}.mobile-menu--link__playlist i:before{content:"\e783"}.section-playlist .mobile-menu--link__playlist i:before{color:#fff}.help--page .region-content-wrapper .region-content{padding:1em}@media (min-width: 57em){.help--page .region-content-wrapper .region-content{padding:2em;padding-left:3em}}.help--page .help--overview--report ul{margin:0;padding:0}.help--page .help--overview--report ul li{margin:0;padding:0;list-style:none}.help--page .help--overview--report ul li:nth-child(even){background:#f5f5f5}.help--page .help--overview--report ul li.warning{background:#ffeacc}.help--page .help--overview--report ul strong,.help--page .help--overview--report ul span{padding:0.5em;display:block;width:50%;float:left}@media (min-width: 57em){.help--page .help--overview--report ul span{width:70%}.help--page .help--overview--report ul strong{width:30%}} .landing-page .landing-section{padding-bottom:10px}.landing-page .region-content{padding:0}.landing-page .region-content h3 a,.landing-page h3.set-header a{font-size:75%;line-height:1.4;float:right;color:#999}.landing-page .region-content h3 a:hover,.landing-page h3.set-header a:hover{color:#12b2e7}.landing-page .landing-sections{position:relative;z-index:10}.landing-loading .landing-page .landing-content{min-height:3000px}#landing-hero{display:none;background-color:#323537;background-attachment:fixed;background-repeat:no-repeat;background-size:cover;background-position:50% 50%;height:600px;position:relative;z-index:1}@media (min-width: 57em){#landing-hero{display:block}} .active-player-kodi .details-header{background:#323537}.active-player-kodi .details-header .gradient{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzMyMzUzNyIvPjxzdG9wIG9mZnNldD0iMzAlIiBzdG9wLWNvbG9yPSIjMzIzNTM3IiBzdG9wLW9wYWNpdHk9IjAuOSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzMyMzUzNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, #323537),color-stop(30%, rgba(50,53,55,0.9)),color-stop(100%, rgba(50,53,55,0)));background-image:-moz-linear-gradient(left, #323537 0%,rgba(50,53,55,0.9) 30%,rgba(50,53,55,0) 100%);background-image:-webkit-linear-gradient(left, #323537 0%,rgba(50,53,55,0.9) 30%,rgba(50,53,55,0) 100%);background-image:linear-gradient(to right, #323537 0%,rgba(50,53,55,0.9) 30%,rgba(50,53,55,0) 100%)}.active-player-local .details-header{background:#222425}.active-player-local .details-header .gradient{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzIyMjQyNSIvPjxzdG9wIG9mZnNldD0iMzAlIiBzdG9wLWNvbG9yPSIjMjIyNDI1IiBzdG9wLW9wYWNpdHk9IjAuOSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzIyMjQyNSIgc3RvcC1vcGFjaXR5PSIwLjAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, #222425),color-stop(30%, rgba(34,36,37,0.9)),color-stop(100%, rgba(34,36,37,0)));background-image:-moz-linear-gradient(left, #222425 0%,rgba(34,36,37,0.9) 30%,rgba(34,36,37,0) 100%);background-image:-webkit-linear-gradient(left, #222425 0%,rgba(34,36,37,0.9) 30%,rgba(34,36,37,0) 100%);background-image:linear-gradient(to right, #222425 0%,rgba(34,36,37,0.9) 30%,rgba(34,36,37,0) 100%)}.details-header{*zoom:1;position:relative;min-height:283px;padding-bottom:2em}.details-header:after{content:"";display:table;clear:both}.details-header a{color:rgba(255,255,255,0.6)}.details-header a:hover{color:rgba(255,255,255,0.9)}.details-header .region-details-side{padding:0.5em 0 0.5em 0.5em;display:none}@media (min-width: 45em){.details-header .region-details-side{width:190px}}@media (min-width: 75em){.details-header .region-details-side{width:280px}}@media (min-width: 45em){.details-header .region-details-side{display:block;padding:1.5em;position:absolute}}.details-header .region-details-meta-wrapper{padding:0.5em 2em;color:rgba(255,255,255,0.9);position:relative;z-index:20}@media (min-width: 45em){.details-header .region-details-meta-wrapper{margin-left:190px}}@media (min-width: 75em){.details-header .region-details-meta-wrapper{margin-left:280px}}@media (min-width: 45em){.details-header .region-details-meta-wrapper{padding:0.5em 1em 0 0.5em}}@media (min-width: 75em){.details-header .region-details-meta-wrapper{padding-top:1em}}@media (min-width: 90em){.details-header .region-details-meta-wrapper{margin-right:300px;color:rgba(255,255,255,0.9)}.shell-playlist-closed .details-header .region-details-meta-wrapper{margin-right:500px}}.details-header .region-details-title{color:rgba(255,255,255,0.95);margin-bottom:0.5em}.details-header .region-details-title .sub{font-weight:normal;font-size:14px;color:rgba(255,255,255,0.4)}@media (min-width: 45em){.details-header .region-details-title{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:75%;float:left}}.details-header .region-details-rating{width:73px;font-size:170%;color:rgba(255,255,255,0.7);white-space:nowrap;margin-top:0.8em;padding-right:2em;position:relative;text-align:right}.details-header .region-details-rating i{font-size:150%;top:-5px;right:0;position:absolute}.details-header .region-details-rating i:before{content:"\e631";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}@media (min-width: 45em){.details-header .region-details-rating{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:25%;float:right}}.details-header .region-details-subtext{color:rgba(255,255,255,0.6);*zoom:1}.details-header .region-details-subtext:after{content:"";display:table;clear:both}.details-header .region-details-fanart{background-size:cover;background-position:50% 50%;width:100%;top:0;right:0;bottom:0;left:0;position:absolute;z-index:10;opacity:0.3}@media (min-width: 57em){.details-header .region-details-fanart{width:600px;margin-left:50px}}@media (min-width: 75em){.details-header .region-details-fanart{left:auto}}.details-header .region-details-fanart .gradient{content:"";top:0;bottom:0;left:0;position:absolute;width:60%}@media (min-width: 90em){.details-header .region-details-fanart{opacity:0.8}}.details-header .tagline,.details-header .description{margin-bottom:0.5em;max-height:22px;overflow:hidden;cursor:pointer;color:rgba(255,255,255,0.6)}.details-header .tagline.expanded,.details-header .description.expanded{max-height:none}@media (min-width: 75em){.details-header .tagline,.details-header .description{padding-right:10%}}.details-header .tagline{max-height:none;cursor:default;color:rgba(255,255,255,0.8)}.details-header .meta{margin:1em 0}.details-header .meta span{color:rgba(255,255,255,0.6)}.details-header .meta label{text-transform:capitalize}.details-header .runtime{font-size:120%;margin-bottom:0.6em;float:left}.details-header .genres{float:right}.details-header .streams span{color:rgba(255,255,255,0.6);text-transform:uppercase}.details-header .card-detail .artwork{position:relative;z-index:20}.details-header .card-detail .play{top:0;right:0;bottom:0;left:0;position:absolute;background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;z-index:20;cursor:pointer;opacity:0}.details-header .card-detail .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.details-header .card-detail .play:before{font-size:400%;color:rgba(255,255,255,0.8);top:0;right:0;bottom:0;left:0;position:absolute;margin:auto;width:55px;height:55px}.details-header .card-detail:hover .play{opacity:1}.details-header label{font-weight:normal}.details-header .dropdown>span{cursor:pointer}.tvshow-show .details-header,.season-details .details-header,.movie-show .details-header{min-height:315px}@media (min-width: 75em){.tvshow-show .details-header,.season-details .details-header,.movie-show .details-header{min-height:405px}}.section-movie .details-header .region-details-meta-below,.section-tvshow .details-header .region-details-meta-below{height:auto;overflow:initial}.layout-container.with-sidebar-first>.region-first{background:#f2f2f2;position:fixed;bottom:70px;top:50px;left:0;width:0;width:250px;left:-100%;-webkit-box-shadow:1px 0 3px 0 rgba(134,134,134,0.3);box-shadow:1px 0 3px 0 rgba(134,134,134,0.3);-webkit-transition:all 0.3s linear;-o-transition:all 0.3s linear;transition:all 0.3s linear;overflow-y:auto;z-index:25}@media (min-width: 57em){.layout-container.with-sidebar-first>.region-first{bottom:70px}}@media (min-width: 57em){.layout-container.with-sidebar-first>.region-first{left:50px}}@media (min-width: 57em){.layout-container.with-sidebar-first>.region-first{width:190px}}@media (min-width: 75em){.layout-container.with-sidebar-first>.region-first{width:250px}}@media (min-width: 57em){.layout-container.with-sidebar-first>.region-first{display:block;-webkit-box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);left:50px}}.region-first-open .layout-container.with-sidebar-first>.region-first{left:0}@media (min-width: 57em){.region-first-open .layout-container.with-sidebar-first>.region-first{left:50px}}.layout-container.with-sidebar-first>.region-content-wrapper{margin-left:0;margin-left:0}@media (min-width: 57em){.layout-container.with-sidebar-first>.region-content-wrapper{margin-left:190px}}@media (min-width: 75em){.layout-container.with-sidebar-first>.region-content-wrapper{margin-left:250px}}.layout-container.with-header>.region-content-wrapper{position:relative}.layout-container.with-header>.region-content-wrapper>.region-content,.layout-container.with-header>.region-content{background:#f5f5f5;padding-top:2em;min-height:500px}.region-first-toggle{top:0;left:50px;position:fixed;display:table;width:50px;text-align:center;cursor:pointer;color:rgba(255,255,255,0.6);z-index:100;font-size:150%;opacity:0.5}.region-first-toggle:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.region-first-toggle:before{display:table-cell;vertical-align:middle;height:50px}@media (min-width: 57em){.region-first-toggle{display:none}}.region-first-open .region-first-toggle{color:#fff}.region-first-open .region-first-toggle:before{content:"\e89a"}.content-container.with-sidebar .content-container-first{float:left;padding-right:2em;display:none}@media (min-width: 45em){.content-container.with-sidebar .content-container-first{width:190px}}@media (min-width: 75em){.content-container.with-sidebar .content-container-first{width:280px}}@media (min-width: 45em){.content-container.with-sidebar .content-container-content-wrapper{margin-left:190px}}@media (min-width: 75em){.content-container.with-sidebar .content-container-content-wrapper{margin-left:280px}} -.section-content{border-bottom:1px solid #ddd;max-width:1100px;margin-bottom:2em;padding-bottom:2em}.section-content h2{margin-bottom:1em}.section-content.section-full-width{max-width:none}.content-sections>.section-content:last-child{border:none}#loading-page{top:0;right:0;bottom:150px;left:0;position:fixed;left:0;right:0}@media (min-width: 57em){#loading-page{left:50px}}.shell-playlist-closed #loading-page{right:0}@media (min-width: 57em){#loading-page{right:310px}.shell-playlist-closed #loading-page{right:50px}}@media (min-width: 75em){#loading-page{right:400px}.shell-playlist-closed #loading-page{right:50px}}#loading-page.init{left:0 !important;right:0 !important}.shell-playlist-closed #loading-page{right:0}@media (min-width: 57em){.shell-playlist-closed #loading-page{right:50px}}@media (min-width: 75em){.shell-playlist-closed #loading-page{right:50px}}#loading-page h2{text-align:center;margin-top:18rem;font-size:1.5em;color:#a8a7a6}@media (min-width: 57em){#loading-page h2{margin-top:33rem}}.loader-inline #loading-page{position:relative;bottom:0;left:0 !important;right:0 !important}.loader-inline #loading-page h2{margin-top:10rem}@media (min-width: 57em){.loader-inline #loading-page h2{margin-top:12rem}} -.loader{position:absolute;margin:5rem auto 3rem auto;overflow:hidden}.loader>div{position:absolute;top:0;left:0;height:100%;width:100%}.orbit{height:20rem;width:20rem;top:0;left:0;bottom:0;right:0;margin:auto;overflow:visible;background-color:#ddd;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%}.orbit>div{top:2.5rem;left:2.5rem;font-size:1rem;height:15rem;width:15rem;-webkit-transform-origin:center center;-moz-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}.orbit>div::before{position:absolute;left:calc(50% - .5em);display:block;content:'';height:1em;width:1em;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%;-moz-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.orbit>div:nth-child(1)::before{background-color:#a8a7a6}.orbit>div:nth-child(2)::before{background-color:#a8a7a6}.orbit>div:nth-child(3)::before{background-color:#a8a7a6}.orbit>div:nth-child(4)::before{background-color:#a8a7a6}@-moz-keyframes loading-orbit{0%{-moz-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-orbit{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-orbit{0%{-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-orbit-before{0%{height:1em;width:1em;-moz-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-moz-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-moz-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}@-webkit-keyframes loading-orbit-before{0%{height:1em;width:1em;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-webkit-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}@keyframes loading-orbit-before{0%{height:1em;width:1em;-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-moz-transform:translate3d(1rem, 15rem, 0);-ms-transform:translate3d(1rem, 15rem, 0);-webkit-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}.loader.orbit>div{-webkit-animation:loading-orbit 6s infinite linear;-o-animation:loading-orbit 6s infinite linear;animation:loading-orbit 6s infinite linear}.loader.orbit>div::before{-webkit-animation:loading-orbit-before 2s infinite ease-in-out;-o-animation:loading-orbit-before 2s infinite ease-in-out;animation:loading-orbit-before 2s infinite ease-in-out}.loader.orbit>div:nth-child(1){-webkit-animation-delay:0s;animation-delay:0s}.loader.orbit>div:nth-child(2){-webkit-animation-delay:-0.75s;animation-delay:-0.75s}.loader.orbit>div:nth-child(3){-webkit-animation-delay:-1.5s;animation-delay:-1.5s}.loader.orbit>div:nth-child(4){-webkit-animation-delay:-2.25s;animation-delay:-2.25s}.loader.orbit>div:nth-child(1)::before{-webkit-animation-delay:0s;animation-delay:0s}.loader.orbit>div:nth-child(2)::before{-webkit-animation-delay:-0.5s;animation-delay:-0.5s}.loader.orbit>div:nth-child(3)::before{-webkit-animation-delay:-1s;animation-delay:-1s}.loader.orbit>div:nth-child(4)::before{-webkit-animation-delay:-1.5s;animation-delay:-1.5s}.spinner-double-section-far,.spinner-double-section{top:20em;right:0;bottom:0;left:0;position:absolute;margin:auto;width:80px;height:80px;border-radius:50%;border:4px solid rgba(170,170,170,0.2);-webkit-animation:spinner 3s linear infinite;-o-animation:spinner 3s linear infinite;animation:spinner 3s linear infinite}.loader-inline .spinner-double-section-far,.loader-inline .spinner-double-section{top:5em}@-moz-keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-webkit-keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner-double-section-far,.spinner-double-section{position:relative}.spinner-double-section-far:before,.spinner-double-section-far:after,.spinner-double-section:before,.spinner-double-section:after{content:'';position:absolute;top:-20px;left:-20px;display:block;width:80px;height:80px;border-radius:50%;border:4px solid transparent;border-top-color:#12b2e7}.spinner-double-section-far:after,.spinner-double-section:after{border-top-color:transparent;border-bottom-color:#12b2e7}.spinner-double-section-far{top:11em}.spinner-double-section-far:before,.spinner-double-section-far:after{top:-12px;left:-12px;width:96px;height:96px}@media (min-width: 57em){.spinner-double-section-far{top:20em}} -@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.loader-small-inline{border-radius:50%;width:20px;height:20px;border:0.25rem solid rgba(0,0,0,0.1);border-top-color:#12b2e7;animation:spin 1s infinite linear;display:inline-block}.local-playlist-list .region-first .new-list{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#a8a7a6;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em;margin:2em 0}.local-playlist-list .region-first .new-list .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.local-playlist-list .region-first .new-list .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00A8A7A6', endColorstr='#FFA8A7A6');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2E4YTdhNiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNhOGE3YTYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(168,167,166,0)),color-stop(100%, #a8a7a6));background-image:-moz-linear-gradient(left, rgba(168,167,166,0) 0%,#a8a7a6 100%);background-image:-webkit-linear-gradient(left, rgba(168,167,166,0) 0%,#a8a7a6 100%);background-image:linear-gradient(to right, rgba(168,167,166,0) 0%,#a8a7a6 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.local-playlist-list .region-first .new-list:hover{color:#fff}.local-playlist-list .region-first .new-list:before{content:"\e6fd";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.local-playlist-list .region-first .new-list:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.local-playlist-list .region-first .new-list:hover:before{color:#fff}.local-playlist-list .region-content{padding:0}.modal .playlist-selection-list .lists li:after{display:none}.local-playlist .local-playlist-header{position:relative;background:#fff;padding:1em}.local-playlist .local-playlist-header h2{margin:0;font-size:18px;color:#888}.local-playlist .local-playlist-header .dropdown{position:absolute;right:1em;top:0.5em}.local-playlist .local-playlist-header .dropdown i{color:#888;display:table;width:1.5em;text-align:center;cursor:pointer;font-size:150%}.local-playlist .local-playlist-header .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.local-playlist .local-playlist-header .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.local-playlist .local-playlist-header .dropdown ul{left:auto;right:0}.local-playlist .item-container{margin:1em}.local-playlist .empty-content{color:#888;text-align:center;font-size:150%;margin:2em}#nav-bar{background:rgba(255,255,255,0.9);width:50px;padding:0;top:0;left:0;position:fixed;margin:0;padding:0;-webkit-transition:all 0.3s linear;-o-transition:all 0.3s linear;transition:all 0.3s linear;z-index:50;-webkit-box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);display:none}#nav-bar #nav-header{height:50px;background:#1e2122 url('../images/logo.png?1423030648') 0 0 no-repeat}.section-home #nav-bar{display:block}@media (min-width: 57em){#nav-bar{display:block}}#nav-bar nav{padding:1em 0}#nav-bar nav ul{margin:0;padding:0}#nav-bar nav ul li{margin:0;padding:0;list-style:none}#nav-bar nav ul a{display:block;padding:0.5em 0;color:#2b2f30;top:0;bottom:0;left:0;position:absolute;white-space:nowrap;-webkit-transition:none;-o-transition:none;transition:none}#nav-bar nav ul a span{display:none;padding-right:1em;font-weight:bold;padding-top:2px}#nav-bar nav ul a i{font-size:130%;width:50px;text-align:center}#nav-bar nav ul a i:before{top:10px;left:16px;position:absolute}#nav-bar nav ul ul{display:none}#nav-bar nav ul li{position:relative;height:38px}#nav-bar nav ul li:hover{white-space:nowrap}#nav-bar nav ul li:hover a{background:#12b2e7;color:#fff}#nav-bar nav ul li:hover a span{display:inline-block}.active-player-local #nav-bar nav ul li:hover a{background:#db2464}#player-wrapper{right:0;bottom:0;left:0;position:fixed;height:70px;background:#18191a;z-index:501}@media (min-width: 57em){#player-wrapper{height:70px}} +.section-content{max-width:1150px;margin-bottom:2em;padding-bottom:2em}.section-content h2{margin-bottom:1em}.section-content.section-full-width{max-width:none}.content-sections>.section-content:last-child{border:none}#loading-page{top:0;right:0;bottom:150px;left:0;position:fixed;left:0;right:0}@media (min-width: 57em){#loading-page{left:50px}}.shell-playlist-closed #loading-page{right:0}@media (min-width: 57em){#loading-page{right:310px}.shell-playlist-closed #loading-page{right:50px}}@media (min-width: 75em){#loading-page{right:400px}.shell-playlist-closed #loading-page{right:50px}}#loading-page.init{left:0 !important;right:0 !important}.shell-playlist-closed #loading-page{right:0}@media (min-width: 57em){.shell-playlist-closed #loading-page{right:50px}}@media (min-width: 75em){.shell-playlist-closed #loading-page{right:50px}}#loading-page h2{text-align:center;margin-top:18rem;font-size:1.5em;color:#a8a7a6}@media (min-width: 57em){#loading-page h2{margin-top:33rem}}.loader-inline #loading-page{position:relative;bottom:0;left:0 !important;right:0 !important}.loader-inline #loading-page h2{margin-top:10rem}@media (min-width: 57em){.loader-inline #loading-page h2{margin-top:12rem}}.search-page #loading-page{position:static;width:100%}.loader{position:absolute;margin:5rem auto 3rem auto;overflow:hidden}.loader>div{position:absolute;top:0;left:0;height:100%;width:100%}.orbit{height:20rem;width:20rem;top:0;left:0;bottom:0;right:0;margin:auto;overflow:visible;background-color:#ddd;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%}.orbit>div{top:2.5rem;left:2.5rem;font-size:1rem;height:15rem;width:15rem;-webkit-transform-origin:center center;-moz-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}.orbit>div::before{position:absolute;left:calc(50% - .5em);display:block;content:'';height:1em;width:1em;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%;-moz-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.orbit>div:nth-child(1)::before{background-color:#a8a7a6}.orbit>div:nth-child(2)::before{background-color:#a8a7a6}.orbit>div:nth-child(3)::before{background-color:#a8a7a6}.orbit>div:nth-child(4)::before{background-color:#a8a7a6}@-moz-keyframes loading-orbit{0%{-moz-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-orbit{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-orbit{0%{-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-orbit-before{0%{height:1em;width:1em;-moz-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-moz-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-moz-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}@-webkit-keyframes loading-orbit-before{0%{height:1em;width:1em;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-webkit-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}@keyframes loading-orbit-before{0%{height:1em;width:1em;-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:5}5%{height:1.25em;width:1.25em}25%{height:2em;width:2em;z-index:10;background-color:#12b2e7}50%{-moz-transform:translate3d(1rem, 15rem, 0);-ms-transform:translate3d(1rem, 15rem, 0);-webkit-transform:translate3d(1rem, 15rem, 0);transform:translate3d(1rem, 15rem, 0);z-index:0;height:1em;width:1em}100%{-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);z-index:0;height:1em;width:1em}}.loader.orbit>div{-webkit-animation:loading-orbit 6s infinite linear;-o-animation:loading-orbit 6s infinite linear;animation:loading-orbit 6s infinite linear}.loader.orbit>div::before{-webkit-animation:loading-orbit-before 2s infinite ease-in-out;-o-animation:loading-orbit-before 2s infinite ease-in-out;animation:loading-orbit-before 2s infinite ease-in-out}.loader.orbit>div:nth-child(1){-webkit-animation-delay:0s;animation-delay:0s}.loader.orbit>div:nth-child(2){-webkit-animation-delay:-0.75s;animation-delay:-0.75s}.loader.orbit>div:nth-child(3){-webkit-animation-delay:-1.5s;animation-delay:-1.5s}.loader.orbit>div:nth-child(4){-webkit-animation-delay:-2.25s;animation-delay:-2.25s}.loader.orbit>div:nth-child(1)::before{-webkit-animation-delay:0s;animation-delay:0s}.loader.orbit>div:nth-child(2)::before{-webkit-animation-delay:-0.5s;animation-delay:-0.5s}.loader.orbit>div:nth-child(3)::before{-webkit-animation-delay:-1s;animation-delay:-1s}.loader.orbit>div:nth-child(4)::before{-webkit-animation-delay:-1.5s;animation-delay:-1.5s}.spinner-double-section-far,.spinner-double-section{top:20em;right:0;bottom:0;left:0;position:absolute;margin:auto;width:80px;height:80px;border-radius:50%;border:4px solid rgba(170,170,170,0.2);-webkit-animation:spinner 3s linear infinite;-o-animation:spinner 3s linear infinite;animation:spinner 3s linear infinite}.loader-inline .spinner-double-section-far,.loader-inline .spinner-double-section{top:5em}@-moz-keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-webkit-keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner-double-section-far,.spinner-double-section{position:relative}.spinner-double-section-far:before,.spinner-double-section-far:after,.spinner-double-section:before,.spinner-double-section:after{content:'';position:absolute;top:-20px;left:-20px;display:block;width:80px;height:80px;border-radius:50%;border:4px solid transparent;border-top-color:#12b2e7}.spinner-double-section-far:after,.spinner-double-section:after{border-top-color:transparent;border-bottom-color:#12b2e7}.spinner-double-section-far{top:11em}.spinner-double-section-far:before,.spinner-double-section-far:after{top:-12px;left:-12px;width:96px;height:96px}@media (min-width: 57em){.spinner-double-section-far{top:20em}} +@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.loader-small-inline{border-radius:50%;width:20px;height:20px;border:0.25rem solid rgba(0,0,0,0.1);border-top-color:#12b2e7;animation:spin 1s infinite linear;display:inline-block}.local-playlist-list .region-first .new-list{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#a8a7a6;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em;margin:2em 0}.local-playlist-list .region-first .new-list .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.local-playlist-list .region-first .new-list .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00A8A7A6', endColorstr='#FFA8A7A6');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2E4YTdhNiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNhOGE3YTYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(168,167,166,0)),color-stop(100%, #a8a7a6));background-image:-moz-linear-gradient(left, rgba(168,167,166,0) 0%,#a8a7a6 100%);background-image:-webkit-linear-gradient(left, rgba(168,167,166,0) 0%,#a8a7a6 100%);background-image:linear-gradient(to right, rgba(168,167,166,0) 0%,#a8a7a6 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.local-playlist-list .region-first .new-list:hover{color:#fff}.local-playlist-list .region-first .new-list:before{content:"\e6fd";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.local-playlist-list .region-first .new-list:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.local-playlist-list .region-first .new-list:hover:before{color:#fff}.local-playlist-list .region-content{padding:0}.modal .playlist-selection-list h3{display:none}.modal .playlist-selection-list .lists li:after{display:none}.local-playlist .local-playlist-header{position:relative;background:#fff;padding:1em}.local-playlist .local-playlist-header h2{margin:0;font-size:18px;color:#888}.local-playlist .local-playlist-header .dropdown{position:absolute;right:1em;top:0.5em}.local-playlist .local-playlist-header .dropdown i{color:#888;display:table;width:1.5em;text-align:center;cursor:pointer;font-size:150%}.local-playlist .local-playlist-header .dropdown i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.local-playlist .local-playlist-header .dropdown i:before{display:table-cell;vertical-align:middle;height:1.5em}.local-playlist .local-playlist-header .dropdown ul{left:auto;right:0}.local-playlist .item-container{margin:1em}.local-playlist .empty-content{color:#888;text-align:center;font-size:150%;margin:2em}#modal-window .close,#modal-window .close:hover,#modal-window .close:focus{color:#fff}#modal-window .modal-dialog{-webkit-box-shadow:0 2px 11px 2px rgba(0,0,0,0.32);box-shadow:0 2px 11px 2px rgba(0,0,0,0.32)}@media (min-width: 45em){#modal-window .modal-dialog{min-width:500px}}#modal-window .modal-header{background:#2F3334;color:#fff}#modal-window .modal-header,#modal-window .modal-body{padding:15px 20px}#modal-window .modal-footer{background:rgba(0,0,0,0.05);padding:5px 20px}#modal-window.style-confirm .modal-body{padding:30px 20px}@media (min-width: 57em){#modal-window.style-video .modal-dialog{width:800px}}#modal-window.style-video .modal-body{padding:0;position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden}#modal-window.style-video .modal-body iframe{position:absolute;top:0;left:0;width:100%;height:100%}#modal-window.style-video .modal-footer{display:none}#modal-window.style-edit-form .modal-footer,#modal-window.style-form .modal-footer{display:none}#modal-window.style-edit-form footer,#modal-window.style-form footer{margin:15px -20px -15px;padding:5px 20px;background:rgba(0,0,0,0.05);*zoom:1}#modal-window.style-edit-form footer:after,#modal-window.style-form footer:after{content:"";display:table;clear:both}#modal-window.style-edit-form footer .inline-list li,#modal-window.style-form footer .inline-list li{margin:0 0 0 2em;float:right}#nav-bar{background:rgba(255,255,255,0.9);width:50px;padding:0;top:0;left:0;position:fixed;margin:0;padding:0;-webkit-transition:all 0.3s linear;-o-transition:all 0.3s linear;transition:all 0.3s linear;z-index:50;-webkit-box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);box-shadow:1px 0 3px 0 rgba(134,134,134,0.05);display:none}#nav-bar #nav-header{height:50px;background:#1e2122 url('../images/logo.png?1423030648') 0 0 no-repeat}.section-home #nav-bar{display:block}@media (min-width: 57em){#nav-bar{display:block}}#nav-bar nav{padding:1em 0}#nav-bar nav ul{margin:0;padding:0}#nav-bar nav ul li{margin:0;padding:0;list-style:none}#nav-bar nav ul a{display:block;padding:0.5em 0;color:#2b2f30;top:0;bottom:0;left:0;position:absolute;white-space:nowrap;-webkit-transition:none;-o-transition:none;transition:none}#nav-bar nav ul a span{display:none;padding-right:1em;font-weight:bold;padding-top:2px}#nav-bar nav ul a i{font-size:130%;width:50px;text-align:center}#nav-bar nav ul a i:before{top:10px;left:16px;position:absolute}#nav-bar nav ul ul{display:none}#nav-bar nav ul li{position:relative;height:38px}#nav-bar nav ul li:hover{white-space:nowrap}#nav-bar nav ul li:hover a{background:#12b2e7;color:#fff}#nav-bar nav ul li:hover a span{display:inline-block}.active-player-local #nav-bar nav ul li:hover a{background:#db2464}#player-wrapper{right:0;bottom:0;left:0;position:fixed;height:70px;background:#18191a;z-index:501}@media (min-width: 57em){#player-wrapper{height:70px}} #player-local{display:none}.active-player-local #player-local{display:block}#player-kodi{display:block}.active-player-local #player-kodi{display:none}#player-kodi .playing-thumb:hover .remote-toggle{display:table}.player .controls-primary,.player .controls-secondary{background:rgba(255,255,255,0.05);height:70px}@media (min-width: 57em){.player .controls-primary,.player .controls-secondary{height:70px}}.player .controls-primary .control,.player .controls-secondary .control{cursor:pointer;height:70px;display:table;font-size:40px;color:rgba(255,255,255,0.5)}@media (min-width: 57em){.player .controls-primary .control,.player .controls-secondary .control{height:70px}}.player .controls-primary .control:hover,.player .controls-secondary .control:hover{color:#fff}.player .control{text-align:center}.player .control:before{display:table-cell;vertical-align:middle}.player .controls-primary{display:none;width:100%}@media (min-width: 57em){.player .controls-primary{width:300px}}.player .controls-primary .control{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:33.33%;float:left}@media (min-width: 57em){.player .controls-primary{float:left;display:block}}.player .controls-secondary{display:none;width:100%}@media (min-width: 57em){.player .controls-secondary{width:300px}}.player .controls-secondary .control{margin-top:-9px;font-size:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:25%;float:left}@media (min-width: 57em){.player .controls-secondary{float:right;display:block}}.player .now-playing{height:70px;position:relative;font-size:12px;font-weight:bold;color:#bac1c8}@media (min-width: 57em){.player .now-playing{height:70px}}.player .now-playing a{color:#bac1c8}@media (min-width: 57em){.player .now-playing{margin-right:300px;margin-left:300px}}.player .thumb{width:70px;height:70px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.player .playing-thumb{top:0;bottom:0;left:0;position:absolute;width:70px;height:70px;z-index:10;overflow:hidden;background-color:rgba(255,255,255,0.2);background-size:cover;background-position:50% 50%}@media (min-width: 57em){.player .playing-thumb{width:70px}}@media (min-width: 57em){.player .playing-thumb{height:70px}}.player .remote-toggle{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;display:table;width:100px;text-align:center;cursor:pointer;display:none;color:#fff;font-size:200%;text-align:center;height:70px;width:70px;font-size:300%;opacity:0.8}.player .remote-toggle:before{content:"\e66f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.player .remote-toggle:before{display:table-cell;vertical-align:middle;height:100px}.player .remote-toggle:before{padding-right:5px}@media (min-width: 57em){.player .remote-toggle{height:70px}}@media (min-width: 57em){.player .remote-toggle{width:70px}}.player .remote-toggle:before{display:table-cell;vertical-align:middle;height:70px;width:70px;padding:0}@media (min-width: 57em){.player .remote-toggle:before{height:70px}}@media (min-width: 57em){.player .remote-toggle:before{width:70px}}.player .playing-info{margin-left:70px}@media (min-width: 57em){.player .playing-info{margin-left:70px}}.player .playing-time{right:0;bottom:0;position:absolute;top:20px;margin:7px 10px 0 0;text-align:right}.player .playing-meta{margin:7px 0 0 10px}.player .playing-title a,.player .playing-time-current{color:#fff;font-size:14px}.player .slider-bar{height:20px;background:rgba(255,255,255,0.1);border-top:4px solid rgba(255,255,255,0);margin:0;cursor:pointer}.player .slider-bar .noUi-base,.player .slider-bar .noUi-handle,.player .slider-bar .noUi-origin{height:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;top:0;border:none}.player .slider-bar .noUi-origin{background:#1f1f20;top:-4px}.player .slider-bar .noUi-handle{background:none;width:7px;left:-5px}.player .slider-bar:hover .noUi-handle{background:#6B6B6B}.player .volume{background:#36393a}.control-prev:before{content:"\e6a8"}.control-play:before{content:"\e6b9";font-size:150%}.control-next:before{content:"\e6a7"}.control-mute:before{content:"\e6d2"}.control-repeat:before{content:"\e6c2"}.control-shuffle:before{content:"\e6c5"}.control-menu:before{content:"\e8a3"}.player-menu-wrapper{right:0;position:fixed;width:100%;bottom:70px;z-index:50}@media (min-width: 57em){.player-menu-wrapper{width:300px}}@media (min-width: 57em){.player-menu-wrapper{bottom:70px}}.player-menu-wrapper ul{background:#fff;-webkit-box-shadow:-1px -1px 8px rgba(0,0,0,0.1);box-shadow:-1px -1px 8px rgba(0,0,0,0.1);height:0;-webkit-transition:height 0.5s ease-in;-o-transition:height 0.5s ease-in;transition:height 0.5s ease-in}.player-menu-wrapper ul li{padding:7px 13px;cursor:pointer}.player-menu-wrapper ul li:hover{background:rgba(0,0,0,0.1)}.player-menu-wrapper.opened ul{height:auto}#player-kodi{background:#18191a}.kodi-playing #player-kodi .control-play:before{content:"\e6b6"}.kodi-playing #player-kodi .playing-progress{border-top-color:#12b2e7}.kodi-paused #player-kodi .control-play:before{content:"\e6b9"}.kodi-mute-on #player-kodi .control-mute:hover{color:#12b2e7}.kodi-mute-on #player-kodi .control-mute:before{content:"\e6d0"}.kodi-repeat-one #player-kodi .control-repeat{color:#fff}.kodi-repeat-one #player-kodi .control-repeat:before{content:"\e6c3"}.kodi-repeat-one #player-kodi .control-repeat:hover{color:#12b2e7}.kodi-repeat-all #player-kodi .control-repeat{color:#fff}.kodi-repeat-all #player-kodi .control-repeat:hover{color:#12b2e7}.kodi-shuffled-on #player-kodi .control-shuffle{color:#fff}.kodi-shuffled-on #player-kodi .control-shuffle:hover{color:#12b2e7}#player-kodi .slider-bar{background:#2a2b2c}#player-kodi .slider-bar .noUi-origin{background:#151617}#player-local{background:#313233}.local-playing #player-local .control-play:before{content:"\e6b6"}.local-playing #player-local .playing-progress{border-top-color:#db2464}.local-paused #player-local .control-play:before{content:"\e6b9"}.local-mute-on #player-local .control-mute:hover{color:#db2464}.local-mute-on #player-local .control-mute:before{content:"\e6d0"}.local-repeat-one #player-local .control-repeat{color:#fff}.local-repeat-one #player-local .control-repeat:before{content:"\e6c3"}.local-repeat-one #player-local .control-repeat:hover{color:#db2464}.local-repeat-all #player-local .control-repeat{color:#fff}.local-repeat-all #player-local .control-repeat:hover{color:#db2464}.local-shuffled-on #player-local .control-shuffle{color:#fff}.local-shuffled-on #player-local .control-shuffle:hover{color:#db2464}#player-local .slider-bar{background:#414243}#player-local .slider-bar .noUi-origin{background:#2c2d2d}.playlist-items li{border-bottom:1px solid rgba(255,255,255,0.1);height:34px;position:relative;color:#999}.playlist-items li a{color:#999}.playlist-items li.sortable-ghost,.playlist-items li.row-playing,.playlist-items li.row-paused,.playlist-items li:hover{height:51px;background-color:#0b0c0c}.playlist-items li.sortable-ghost .thumb,.playlist-items li.row-playing .thumb,.playlist-items li.row-paused .thumb,.playlist-items li:hover .thumb{width:50px;height:50px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.playlist-items li.sortable-ghost .subtitle,.playlist-items li.sortable-ghost .thumb,.playlist-items li.row-playing .subtitle,.playlist-items li.row-playing .thumb,.playlist-items li.row-paused .subtitle,.playlist-items li.row-paused .thumb,.playlist-items li:hover .subtitle,.playlist-items li:hover .thumb{display:block}.playlist-items li.sortable-ghost .title a,.playlist-items li.row-playing .title a,.playlist-items li.row-paused .title a,.playlist-items li:hover .title a{color:rgba(255,255,255,0.95)}.playlist-items li.row-playing,.playlist-items li.row-paused{height:80px;background-image:url('../images/row-playing-white.gif?1423213071');background-repeat:no-repeat;background-position:2px 1px}.playlist-items li.row-playing .remove,.playlist-items li.row-paused .remove{display:none !important}.playlist-items li.row-playing .thumb,.playlist-items li.row-paused .thumb{width:80px;height:80px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.playlist-items li.row-playing .thumb,.playlist-items li.row-paused .thumb{top:0;right:0;bottom:0;position:absolute;margin:0}.playlist-items li.row-playing .thumb .play,.playlist-items li.row-paused .thumb .play{display:none !important}.playlist-items li.row-playing .thumb .thumbs,.playlist-items li.row-paused .thumb .thumbs{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;display:table;width:50px;text-align:center;cursor:pointer;display:none;color:#fff;font-size:200%;width:80px}.playlist-items li.row-playing .thumb .thumbs:before,.playlist-items li.row-paused .thumb .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.playlist-items li.row-playing .thumb .thumbs:before,.playlist-items li.row-paused .thumb .thumbs:before{display:table-cell;vertical-align:middle;height:50px}.playlist-items li.row-playing .thumb .thumbs:before,.playlist-items li.row-paused .thumb .thumbs:before{padding-right:5px}.playlist-items li.row-playing .thumb .thumbs:before,.playlist-items li.row-paused .thumb .thumbs:before{width:80px;height:80px}.playlist-items li.row-playing .thumb:hover .thumbs,.playlist-items li.row-paused .thumb:hover .thumbs{display:block}.playlist-items li.row-playing .meta,.playlist-items li.row-paused .meta{margin-right:90px;margin-left:27px}.playlist-items li.row-playing .meta .title,.playlist-items li.row-paused .meta .title{margin-top:5px;font-size:110%}.playlist-items li.row-paused{background-image:url('../images/row-pause-white.png?1423213243')}.playlist-items li.sortable-ghost{height:50px;background:rgba(255,255,255,0.3);opacity:0.5}.playlist-items li.thumbs-up .thumbs{color:#12b2e7 !important}.active-player-local .playlist-items li.thumbs-up .thumbs{color:#db2464 !important}.playlist-items .thumb{background:transparent;overflow:hidden;letter-spacing:-0.31em;width:50px;height:50px;float:left;margin-right:10px;display:none;position:relative}.playlist-items .thumb img{display:block;vertical-align:middle;width:50px;margin-top:50%}.playlist-items .thumb .thumb{width:50px;height:50px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.playlist-items .thumb:hover .play{display:table}.playlist-items .play{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;display:table;width:50px;text-align:center;cursor:pointer;display:none;color:#fff;font-size:200%}.playlist-items .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.playlist-items .play:before{display:table-cell;vertical-align:middle;height:50px}.playlist-items .play:before{padding-right:5px}.playlist-items .meta{margin:0 30px 0 0px;padding:9px 10px 5px 15px}.playlist-items .title,.playlist-items .subtitle{display:block;overflow:hidden;white-space:nowrap}.playlist-items .title,.playlist-items .title a{color:#bdc1c2}.playlist-items .subtitle{display:none;font-size:95%;margin-top:2px}.playlist-items .remove{top:0;right:0;bottom:0;position:absolute;display:table;width:34px;text-align:center;cursor:pointer;display:none}.playlist-items .remove:before{content:"\e89c";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.playlist-items .remove:before{display:table-cell;vertical-align:middle;height:50px}.playlist-items .remove:hover{font-size:120%;color:darkred}.playlist-items li:hover .remove{display:table}.playlists-wrapper{padding:1em;font-size:85%;overflow-y:auto;right:0;bottom:0;left:0;position:absolute;top:50px;z-index:500}.media-toggle{*zoom:1;background:rgba(255,255,255,0.1);margin-bottom:0.5em}.media-toggle:after{content:"";display:table;clear:both}.media-toggle li{float:left;padding:5px 15px;color:#999;cursor:pointer}.playlist-bar.media-audio .media-toggle li.audio{color:#fff;background:rgba(255,255,255,0.1)}.playlist-bar.media-video .media-toggle li.video{color:#fff;background:rgba(255,255,255,0.1)}.playlist-header{background:#313233;height:50px}.playlist-header .player-toggle{display:table}.playlist-header .player-toggle li{height:50px;display:table-cell;vertical-align:middle;padding:0 2em 0 2em;color:rgba(255,255,255,0.8);cursor:pointer}.playlist-header .player-toggle li:before{margin-right:0.5em;font-size:90%}.playlist-header .player-toggle li.kodi:before{content:"\e602";display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.playlist-header .player-toggle li.local:before{content:"\e7b0";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.active-player-kodi .playlist-header .player-toggle li.kodi{color:#12b2e7;background:#1b1c1d}.active-player-local .playlist-header .player-toggle li.local{color:#db2464;background:#1b1c1d}.playlist-header .playlist-menu{top:0;right:0;position:absolute}.playlist-header .playlist-menu .menu-toggle{display:table;width:50px;text-align:center;cursor:pointer;color:rgba(255,255,255,0.5);font-size:150%}.playlist-header .playlist-menu .menu-toggle:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.playlist-header .playlist-menu .menu-toggle:before{display:table-cell;vertical-align:middle;height:50px}.playlist-header .playlist-menu .menu-toggle:hover{color:#fff}@media (min-width: 57em){.playlist-header .playlist-menu{right:50px}}.playlist-header .playlist-menu .dropdown-menu{background:#fff;padding:0;top:50px;margin-top:-5px}.playlist-header .playlist-menu .dropdown-menu li{padding:0;font-size:12px}.playlist-header .playlist-menu .dropdown-menu li.dropdown-header{background:rgba(0,0,0,0.1);color:rgba(0,0,0,0.6)}.playlist-header .playlist-menu .dropdown-menu li.dropdown-header,.playlist-header .playlist-menu .dropdown-menu li a{padding:0.6em 1em}.playlist-header .playlist-menu .dropdown-menu li a{color:rgba(0,0,0,0.5)}.playlist-header .playlist-menu .dropdown-menu li .party-mode i{display:none}.kodi-partymode-on .playlist-header .playlist-menu .dropdown-menu li .party-mode i{display:inline-block}.active-player-kodi .kodi-playlists{display:block}.active-player-kodi .local-playlists{display:none}.active-player-local .kodi-playlists{display:none}.active-player-local .local-playlists{display:block}.playlist-page__empty{text-align:right;margin-right:1em}.playlist-page__empty h3{margin-bottom:1em}.pvr-card{background:#fff;padding:1em;margin-bottom:0.5em;position:relative}.pvr-card.aired{background-color:#f0f0f0}.pvr-card.airing{background:#f4fcff}.pvr-card .title{margin-bottom:0.5em}.pvr-card .entity-progress{top:auto;bottom:0}.pvr-card .entity-progress .current-progress{height:4px;background:#12b2e7}.pvr-card .plot,.pvr-card .title span{color:#888;font-size:90%}.pvr-card .plot{margin-top:0.5em}.pvr-card .actions{top:0.5em;right:0.5em;position:absolute}.pvr-card .actions li{display:table;width:1.5em;text-align:center;cursor:pointer;color:rgba(0,0,0,0.3);float:left;font-size:140%}.pvr-card .actions li:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.pvr-card .actions li:before{display:table-cell;vertical-align:middle;height:1.5em}.pvr-card .actions li:hover{color:rgba(0,0,0,0.6)}.pvr-card .actions li.play{font-size:190%;margin-top:-5px}.pvr-card .actions li.record:before{content:"\e7da"}.pvr-card .actions li.toggle-timer:before{content:"\e65e"}.pvr-card.has-timer .actions li.toggle-timer,.pvr-card.has-timer .actions li.record{color:#bf0a07}#remote{display:none;position:fixed;top:0;right:0;left:0;bottom:70px;top:50px;right:0;background-color:#18191a;z-index:500;background-size:cover}.section-remote #remote{display:block}@media (min-width: 57em){#remote{bottom:70px}}.shell-playlist-closed #remote{right:0}@media (min-width: 57em){#remote{right:310px}.shell-playlist-closed #remote{right:50px}}@media (min-width: 75em){#remote{right:400px}.shell-playlist-closed #remote{right:50px}} #remote-background{top:0;right:0;bottom:360px;left:0;position:absolute;background-color:#2b2f30;background-position:50% 50%;background-size:cover}@media (min-width: 57em){#remote-background{bottom:0;z-index:1;background-color:#f5f5f5}} .kodi-remote{position:absolute;bottom:180px;left:0;right:0;font-size:1.7em;color:#6F7374;overflow:hidden;z-index:500;width:auto}@media (min-width: 57em){.kodi-remote{bottom:0}}@media (min-width: 57em){.kodi-remote{width:371px}}.kodi-remote .ibut{background:#222324}.kodi-remote .ibut:hover{color:#ccc;cursor:pointer}.kodi-remote .main-controls{background:#18191a;*zoom:1}.kodi-remote .main-controls:after{content:"";display:table;clear:both}.kodi-remote .direction{background:#222324;height:155px;margin-top:-12px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:75%;float:left;position:relative;z-index:10}.kodi-remote .direction .pad{margin:5px auto;width:240px;position:relative;text-align:center}.kodi-remote .direction .pad .ibut{height:145px;position:absolute;top:0;left:80px;width:80px;font-size:125%}.kodi-remote .direction .pad .ibut.up,.kodi-remote .direction .pad .ibut.down,.kodi-remote .direction .pad .ibut.ok{height:48.3333333333px;line-height:48.3333333333px}.kodi-remote .direction .pad .ibut.down{top:96.6666666667px}.kodi-remote .direction .pad .ibut.ok{top:48.3333333333px;font-size:12px}.kodi-remote .direction .pad .ibut.left{bottom:0;left:0;line-height:145px;padding-left:20px}.kodi-remote .direction .pad .ibut.right{bottom:0;right:0;left:auto;line-height:145px;padding-right:20px}.kodi-remote .buttons{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:25%;float:right;padding:6px 8px 4px;margin-top:-20px}.kodi-remote .buttons .ibut{display:block;padding:11px 0;text-align:center;margin:1px 0 9px 0}.kodi-remote .alt-controls .row,.kodi-remote .secondary-controls{clear:both;background:#18191a;height:70px}.kodi-remote .alt-controls .row .ibut,.kodi-remote .secondary-controls .ibut{background:#222324;width:33%;padding:0;line-height:70px;font-size:1.5em;text-align:center;float:left;margin-bottom:12px}@media (min-width: 57em){.kodi-remote .alt-controls .row .ibut,.kodi-remote .secondary-controls .ibut{line-height:70px}}.kodi-remote .secondary-controls{height:auto}.kodi-remote .alt-controls .row{margin:8px 0}.kodi-remote .playing-area{height:150px;position:relative;font-size:15px;color:#838b8d}.kodi-remote .playing-area .not-playing,.kodi-remote .playing-area .playing{padding:10px 20px 35px;text-align:right}.kodi-remote .playing-area .playing{background:#3b3f40 0 0 no-repeat;background-size:cover;display:none}.kodi-remote .playing-area:after{content:"";position:absolute;left:0;bottom:0;right:0;height:24px;z-index:5}.section-remote .player .now-playing .remote-toggle,.section-remote .player .now-playing .thumb{height:75px;width:75px}.section-remote .player .controls-secondary,.section-remote .player .controls-secondary .control,.section-remote .player .controls-primary,.section-remote .player .controls-primary .control,.section-remote .player .now-playing,.section-remote .player .now-playing .thumb{height:75px}.section-remote #player-wrapper{height:250px}.section-remote .player .controls-secondary,.section-remote .player .controls-primary{display:block;margin-bottom:12px}.section-remote .player .now-playing{margin:10px 0 0 0}.section-remote .player .playing-info{margin-left:75px}@media (min-width: 57em){.section-remote #player-wrapper{height:70px}.section-remote .player .now-playing,.section-remote .player .controls-secondary,.section-remote .player .controls-primary{margin:0}.section-remote .player .now-playing,.section-remote .player .now-playing .control,.section-remote .player .controls-secondary,.section-remote .player .controls-secondary .control,.section-remote .player .controls-primary,.section-remote .player .controls-primary .control{height:70px}.section-remote .player .now-playing,.section-remote .player .now-playing .thumb,.section-remote .player .controls-secondary,.section-remote .player .controls-secondary .thumb,.section-remote .player .controls-primary,.section-remote .player .controls-primary .thumb{height:70px}.section-remote .player .now-playing .thumb,.section-remote .player .controls-secondary .thumb,.section-remote .player .controls-primary .thumb{width:70px}.section-remote .player .now-playing .playing-info,.section-remote .player .controls-secondary .playing-info,.section-remote .player .controls-primary .playing-info{margin-left:70px}.section-remote .player .now-playing{margin-left:300px;margin-right:300px}} -#search-region{background:rgba(255,255,255,0.9);height:50px;margin-left:0}@media (min-width: 57em){#search-region{display:block}}#search-region:after{content:"";height:3px;background:#12b2e7;opacity:0.3;bottom:0;left:0;position:absolute;width:0%}#search-region.pre-search:after{display:block;width:100%;-webkit-transition:2s all linear;-o-transition:2s all linear;transition:2s all linear}#search{background:none;border:none;height:50px;width:100%;outline:none;padding:0 0.5em 0 50px;color:rgba(0,0,0,0.4)}@media (min-width: 57em){#search{width:200px}} -#do-search{width:50px;height:50px;display:table;top:0;left:0;position:absolute}#do-search:before{content:"\e65f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#do-search:before{font-size:150%;display:table-cell;vertical-align:middle;text-align:center;color:rgba(0,0,0,0.6)}.search-page{top:50px;position:relative}@media (min-width: 57em){.search-page{top:0}}@media (min-width: 57em){.search-page__empty{text-align:right}}.search-page h2.set-header{padding-left:5px}.search-page .browser-folder-list{background:rgba(255,255,255,0.7)}.search-page-layout .search-media-links a{text-transform:capitalize}.search-page-layout .region-content{padding:0}.set-page{padding:0.5em 1.5em 1em}.set-page .entity-set .set-header{margin:1em 0 0.5em;text-transform:capitalize;font-size:22px}.set-page .entity-set .more a{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.set-page .entity-set .more a .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.set-page .entity-set .more a .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.set-page .entity-set .more a:hover{color:#fff}.set-page .entity-set .more a:before{content:"\e6d7";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.set-page .entity-set .more a:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.set-page .entity-set .more a:hover:before{color:#fff}.set-page .entity-set-song .set-results{padding:5px}.set-page .entity-set-loading #loading-page{left:0;right:0;position:relative}.set-page .entity-set-loading .spinner-double-section-far,.set-page .entity-set-loading h2{top:5em}.set-page .entity-set-loading h2{margin-top:5em !important}.settings-page .region-content{padding:0;padding-bottom:70px}@media (min-width: 57em){.settings-page .region-content{padding-bottom:70px}} -.settings-form .form-group{padding-bottom:1.5em;margin-bottom:0;*zoom:1}.settings-form .form-group:after{content:"";display:table;clear:both}@media (min-width: 45em){.settings-form .form-group .control-label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:42.8571428571%;float:left;padding:5px 2em 0.5em 0}.settings-form .form-group .element{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:57.1428571429%;float:right}}.settings-form .group-title{margin-top:0.5em;margin-bottom:1em;padding-bottom:0.5em;color:#12b2e7;display:inline-block}.settings-form .group-title i{color:rgba(136,136,136,0.7)}@media (min-width: 57em){.settings-form .form-items{margin:0 4em 0 2em}}.settings-form footer{color:rgba(255,255,255,0.7);border-top:1px solid #C8C8C8;background:#2B2E2F;padding:1em}@media (min-width: 57em){.settings-form footer{padding:1em 2em}}.settings-form .togglebutton{margin-top:4px}.settings-form .togglebutton label .toggle:after{top:-3px}.settings-form-draggable .form-groups .draggable-row{position:relative;border-bottom:1px solid rgba(221,221,221,0.6);padding:1em 0.5em;cursor:move}.settings-form-draggable .form-groups .draggable-row:nth-child(even){background:rgba(229,229,229,0.2)}.settings-form-draggable .form-groups .draggable-row .form-group{padding-bottom:0.5em}.settings-form-draggable .form-groups .draggable-row .control-label{cursor:move;position:relative;display:block}.settings-form-draggable .form-groups .draggable-row .control-label i{margin-left:0.5em;font-weight:normal;font-size:1.3em;position:absolute;right:0.5em;top:0.5em;opacity:0.9}.settings-form-draggable .form-groups .draggable-row .remove-item{top:0;right:0;position:absolute;padding:0 0.5em 0.25em;color:#921212;display:none;font-size:1.5em;cursor:pointer;opacity:0.5}.settings-form-draggable .form-groups .draggable-row .remove-item:hover{opacity:0.9}.settings-form-draggable .form-groups .draggable-row:hover .remove-item{display:block}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{border:#ddd}::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.2);cursor:pointer}::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,0.4)}body,body.model-open{overflow-y:scroll}#logo{top:0;left:0;position:fixed;height:50px;width:50px;display:table;z-index:100;-webkit-perspective:1000;overflow:hidden;text-align:center;color:#12b2e7;font-size:2em}#logo:before{content:"\e602";display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.loading #logo{-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-animation:pulsate 2s linear;-o-animation:pulsate 2s linear;animation:pulsate 2s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-font-smoothing:subpixel-antialiased}#logo:before{display:table-cell;vertical-align:middle}#page-title .title{padding-left:50px;display:none}@media (min-width: 57em){#page-title .title{display:inline-block}} +#modal-window.style-system .modal-dialog{width:300px;min-width:300px}#search-region{background:rgba(255,255,255,0.9);height:50px;margin-left:0}@media (min-width: 57em){#search-region{display:block}}#search-region:after{content:"";height:3px;background:#12b2e7;opacity:0.3;bottom:0;left:0;position:absolute;width:0%}#search-region.pre-search:after{display:block;width:100%;-webkit-transition:2s all linear;-o-transition:2s all linear;transition:2s all linear}#search{background:none;border:none;height:50px;width:100%;outline:none;padding:0 0.5em 0 50px;color:rgba(0,0,0,0.4)}@media (min-width: 57em){#search{width:200px}} +#do-search{width:50px;height:50px;display:table;top:0;left:0;position:absolute}#do-search:before{content:"\e65f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#do-search:before{font-size:150%;display:table-cell;vertical-align:middle;text-align:center;color:rgba(0,0,0,0.6)}.search-page{top:50px;position:relative}@media (min-width: 57em){.search-page{top:0}}@media (min-width: 57em){.search-page__empty{text-align:right}}.search-page h2.set-header{padding-left:5px}.search-page .browser-folder-list{background:rgba(255,255,255,0.7)}.search-page-layout .search-media-links a{text-transform:capitalize}.search-page-layout .region-content{padding:0}.set-page{padding:0.5em 1.5em 1em}.set-page .entity-set .set-header{margin:1em 0 0.5em;text-transform:capitalize;font-size:22px}.set-page .entity-set .more a{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.set-page .entity-set .more a .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.set-page .entity-set .more a .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.set-page .entity-set .more a:hover{color:#fff}.set-page .entity-set .more a:before{content:"\e6d7";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.set-page .entity-set .more a:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.set-page .entity-set .more a:hover:before{color:#fff}.set-page .entity-set-song .set-results{padding:5px}.set-page .entity-set-loading #loading-page{left:0;right:0;position:relative}.set-page .entity-set-loading .spinner-double-section-far,.set-page .entity-set-loading h2{top:5em}.set-page .entity-set-loading h2{margin-top:5em !important}.landing-set .set__actions{top:0.75em;right:1em;position:absolute;z-index:20}.landing-set .set__actions i{display:table;width:1.5em;text-align:center;cursor:pointer}.landing-set .set__actions i:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.landing-set .set__actions i:before{display:table-cell;vertical-align:middle;height:1.5em}.landing-set .set__more{margin-top:-2em}.landing-set .set__more a{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.landing-set .set__more a .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.landing-set .set__more a .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.landing-set .set__more a:hover{color:#fff}.landing-set .set__more a:before{content:"\e6d7";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.landing-set .set__more a:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.landing-set .set__more a:hover:before{color:#fff}.section-content .set h2{margin-bottom:0.25em}.settings-page .region-content{padding:0;padding-bottom:70px}@media (min-width: 57em){.settings-page .region-content{padding-bottom:70px}} +.settings-form .form-group{padding-bottom:1.5em;margin-bottom:0;*zoom:1}.settings-form .form-group:after{content:"";display:table;clear:both}@media (min-width: 45em){.settings-form .form-group .control-label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:42.8571428571%;float:left;padding:5px 2em 0.5em 0}.settings-form .form-group .element{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:57.1428571429%;float:right}}.settings-form .group-title{margin-top:0.5em;margin-bottom:1em;padding-bottom:0.5em;color:#12b2e7;display:inline-block}.settings-form .group-title i{color:rgba(136,136,136,0.7)}@media (min-width: 57em){.settings-form .form-items{margin:0 4em 0 2em}}.settings-form footer{color:rgba(255,255,255,0.7);border-top:1px solid #C8C8C8;background:#2B2E2F;padding:1em}@media (min-width: 57em){.settings-form footer{padding:1em 2em}}.settings-form .togglebutton{margin-top:4px}.settings-form .togglebutton label .toggle:after{top:-3px}.settings-form-draggable .form-groups .draggable-row{position:relative;border-bottom:1px solid rgba(221,221,221,0.6);padding:1em 2em 0.5em 0.5em}@media (min-width: 57em){.settings-form-draggable .form-groups .draggable-row{cursor:move;padding-right:1em}}.settings-form-draggable .form-groups .draggable-row:nth-child(even){background:rgba(229,229,229,0.2)}.settings-form-draggable .form-groups .draggable-row .form-group{padding-bottom:0.5em}.settings-form-draggable .form-groups .draggable-row .control-label{cursor:move;position:relative;display:block}.settings-form-draggable .form-groups .draggable-row .control-label i{margin-left:0.5em;font-weight:normal;font-size:1.3em;position:absolute;right:0.5em;top:0.5em;opacity:0.9}.settings-form-draggable .form-groups .draggable-row .remove-item{top:0;right:0;position:absolute;padding:0.5em 0.5em 0.25em;color:#921212;font-size:1.5em;cursor:pointer;opacity:0.5}@media (min-width: 57em){.settings-form-draggable .form-groups .draggable-row .remove-item{display:none}}.settings-form-draggable .form-groups .draggable-row .remove-item:hover{opacity:0.9}.settings-form-draggable .form-groups .draggable-row:hover .remove-item{display:block}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{border:#ddd}::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.2);cursor:pointer}::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,0.4)}body,body.model-open{overflow-y:scroll}#logo{top:0;left:0;position:fixed;height:50px;width:50px;display:table;z-index:100;-webkit-perspective:1000;overflow:hidden;text-align:center;color:#12b2e7;font-size:2em}#logo:before{content:"\e602";display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.loading #logo{-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-animation:pulsate 2s linear;-o-animation:pulsate 2s linear;animation:pulsate 2s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-font-smoothing:subpixel-antialiased}#logo:before{display:table-cell;vertical-align:middle}#page-title .title{padding-left:50px;display:none}@media (min-width: 57em){#page-title .title{display:inline-block}} #fanart,#fanart-overlay{top:50px;bottom:0;position:fixed;bottom:70px;right:0;left:0}@media (min-width: 57em){#fanart,#fanart-overlay{bottom:70px}}.shell-playlist-closed #fanart,.shell-playlist-closed #fanart-overlay{right:0}@media (min-width: 57em){#fanart,#fanart-overlay{right:310px}.shell-playlist-closed #fanart,.shell-playlist-closed #fanart-overlay{right:50px}}@media (min-width: 75em){#fanart,#fanart-overlay{right:400px}.shell-playlist-closed #fanart,.shell-playlist-closed #fanart-overlay{right:50px}}@media (min-width: 57em){#fanart,#fanart-overlay{left:50px}} #fanart{background-color:#e0dfdf;background-size:cover;background-position:50% 50%;z-index:-10}#fanart-overlay{z-index:-9;background-color:rgba(224,223,223,0.7)}.section-home #fanart-overlay{display:none}#main{*zoom:1;margin:50px 0 50px 0;margin-right:0;padding-bottom:70px}#main:after{content:"";display:table;clear:both}.shell-playlist-closed #main{margin-right:0}@media (min-width: 57em){#main{margin-right:310px}.shell-playlist-closed #main{margin-right:50px}}@media (min-width: 75em){#main{margin-right:400px}.shell-playlist-closed #main{margin-right:50px}}@media (min-width: 57em){#main{padding-bottom:70px}}@media (min-width: 57em){#main{margin-left:50px;margin-bottom:0}}.shell-playlist-closed #main{margin-right:0}@media (min-width: 57em){.shell-playlist-closed #main{margin-right:50px}}@media (min-width: 75em){.shell-playlist-closed #main{margin-right:50px}} -#sidebar-two{top:0;right:0;bottom:0;left:0;position:fixed;background:#1b1c1d;z-index:50;top:50px;display:none;width:0;width:auto;bottom:70px}body.page-playlist #sidebar-two{display:block}@media (min-width: 57em){#sidebar-two{left:auto;top:0;display:block}}.shell-playlist-closed #sidebar-two{width:0}@media (min-width: 57em){#sidebar-two{width:310px}.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 75em){#sidebar-two{width:400px}.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 57em){#sidebar-two{bottom:70px}}#sidebar-two #playlist-summary{display:none}#sidebar-two .playlist-toggle-open{top:0;right:0;position:absolute;width:50px;height:50px;display:table;width:50px;text-align:center;cursor:pointer;display:table;cursor:pointer;display:none;text-align:center}#sidebar-two .playlist-toggle-open:before{content:"\e7b6";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#sidebar-two .playlist-toggle-open:before{display:table-cell;vertical-align:middle;height:50px}#sidebar-two .playlist-toggle-open:before{-webkit-transition:all 0.4s linear;-o-transition:all 0.4s linear;transition:all 0.4s linear;display:table-cell;vertical-align:middle;text-align:center;font-size:150%;color:rgba(255,255,255,0.5)}@media (min-width: 57em){#sidebar-two .playlist-toggle-open{display:table}}.shell-playlist-closed #sidebar-two{width:0}.shell-playlist-closed #sidebar-two .playlist-toggle-open:before{-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}@media (min-width: 57em){.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 75em){.shell-playlist-closed #sidebar-two{width:50px}}.shell-playlist-closed #sidebar-two #playlist-bar{display:none}.shell-playlist-closed #sidebar-two #playlist-summary{display:block}#offscreen{display:none}#modal-window .close,#modal-window .close:hover,#modal-window .close:focus{color:#fff}#modal-window .modal-dialog{-webkit-box-shadow:0 2px 11px 2px rgba(0,0,0,0.32);box-shadow:0 2px 11px 2px rgba(0,0,0,0.32)}@media (min-width: 45em){#modal-window .modal-dialog{min-width:500px}}#modal-window .modal-header{background:#2F3334;color:#fff}#modal-window .modal-header,#modal-window .modal-body{padding:15px 20px}@media (min-width: 57em){#modal-window.style-video .modal-dialog{width:800px}}#modal-window.style-video .modal-body{padding:0;position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden}#modal-window.style-video .modal-body iframe{position:absolute;top:0;left:0;width:100%;height:100%}#modal-window.style-video .modal-footer{display:none}#modal-window.style-edit-form .modal-footer,#modal-window.style-form .modal-footer{display:none}#modal-window.style-edit-form footer,#modal-window.style-form footer{margin:15px -20px -15px;padding:5px 20px;background:rgba(0,0,0,0.05);*zoom:1}#modal-window.style-edit-form footer:after,#modal-window.style-form footer:after{content:"";display:table;clear:both}#modal-window.style-edit-form footer .inline-list li,#modal-window.style-form footer .inline-list li{margin:0 0 0 2em;float:right}#snackbar-container{position:fixed;z-index:50;right:0;bottom:70px;margin-bottom:-10px}@media (min-width: 57em){#snackbar-container{bottom:70px}} +#sidebar-two{top:0;right:0;bottom:0;left:0;position:fixed;background:#1b1c1d;z-index:50;top:50px;display:none;width:0;width:auto;bottom:70px}body.page-playlist #sidebar-two{display:block}@media (min-width: 57em){#sidebar-two{left:auto;top:0;display:block}}.shell-playlist-closed #sidebar-two{width:0}@media (min-width: 57em){#sidebar-two{width:310px}.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 75em){#sidebar-two{width:400px}.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 57em){#sidebar-two{bottom:70px}}#sidebar-two #playlist-summary{display:none}#sidebar-two .playlist-toggle-open{top:0;right:0;position:absolute;width:50px;height:50px;display:table;width:50px;text-align:center;cursor:pointer;display:table;cursor:pointer;display:none;text-align:center}#sidebar-two .playlist-toggle-open:before{content:"\e7b6";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}#sidebar-two .playlist-toggle-open:before{display:table-cell;vertical-align:middle;height:50px}#sidebar-two .playlist-toggle-open:before{-webkit-transition:all 0.4s linear;-o-transition:all 0.4s linear;transition:all 0.4s linear;display:table-cell;vertical-align:middle;text-align:center;font-size:150%;color:rgba(255,255,255,0.5)}@media (min-width: 57em){#sidebar-two .playlist-toggle-open{display:table}}.shell-playlist-closed #sidebar-two{width:0}.shell-playlist-closed #sidebar-two .playlist-toggle-open:before{-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}@media (min-width: 57em){.shell-playlist-closed #sidebar-two{width:50px}}@media (min-width: 75em){.shell-playlist-closed #sidebar-two{width:50px}}.shell-playlist-closed #sidebar-two #playlist-bar{display:none}.shell-playlist-closed #sidebar-two #playlist-summary{display:block}#offscreen{display:none}#disconnected{top:0;right:0;bottom:0;left:0;position:fixed;background:rgba(0,0,0,0.7);z-index:9999999;display:none}.lost-connection #disconnected{display:block}#disconnected i{font-size:300%;color:#12b2e7;margin:10px 0 5px}#disconnected h2{margin:0.5em 0;font-size:2em}#disconnected .message{max-width:400px;width:95%;margin:10% auto 0;background:#fff;border-radius:5px;padding:1em;text-align:center}#disconnected .btn{color:#fff}#disconnected .btn:hover{background:#12b2e7}.reconnecting #disconnected .try-connect{display:none}#disconnected .load-connect{display:none}.reconnecting #disconnected .load-connect{display:block}#snackbar-container{position:fixed;z-index:50;right:0;bottom:70px;margin-bottom:-10px}@media (min-width: 57em){#snackbar-container{bottom:70px}} .snackbar{overflow:hidden;clear:both;cursor:pointer;opacity:0;min-width:0;max-width:600px}.shell-playlist-closed .snackbar{min-width:0}@media (min-width: 57em){.snackbar{min-width:310px}.shell-playlist-closed .snackbar{min-width:50px}}@media (min-width: 75em){.snackbar{min-width:400px}.shell-playlist-closed .snackbar{min-width:50px}} .snackbar.snackbar-opened{height:auto;opacity:1}@media (max-width: 767px){#snackbar-container{left:0px !important;right:0px;width:100%}#snackbar-container .snackbar{min-width:100%}#snackbar-container [class="snackbar snackbar-opened"] ~ .snackbar.toast{margin-top:20px}#snackbar-container [class="snackbar snackbar-opened"]{border-radius:0;margin-bottom:0}}.snackbar{background-color:rgba(255,255,255,0.95);color:#2b2f30;font-size:14px;border-radius:0px;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);height:0;-moz-transition:-moz-transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, padding 0 linear 0.2s, height 0 linear 0.2s;-webkit-transition:-webkit-transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, padding 0 linear 0.2s, height 0 linear 0.2s;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, padding 0 linear 0.2s, height 0 linear 0.2s;-moz-transform:translateY(200%);-webkit-transform:translateY(200%);transform:translateY(200%)}.snackbar.snackbar-opened{padding:14px 15px;margin:0 0 10px 0;height:auto;-moz-transition:-moz-transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s;-webkit-transition:-webkit-transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s;transition:transform 0.2s ease-in-out, opacity 0.2s ease-in, height 0 linear 0.2s, height 0 linear 0.2s;-moz-transform:none;-webkit-transform:none;transform:none}.songs-table tr.song{cursor:pointer;font-size:13px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.songs-table tr.song.ph td{height:40px}.songs-table tr.song td{vertical-align:middle;position:relative;border-bottom:1px solid rgba(139,139,139,0.05)}.songs-table tr.song td.song-title{width:60%}.songs-table tr.song td.song-artist{width:40%}.songs-table tr.song .crop{position:relative;white-space:nowrap;overflow:hidden;display:block;height:18px;white-space:normal}.songs-table tr.song .crop:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00E0DFDF', endColorstr='#FFE0DFDF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2UwZGZkZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlMGRmZGYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(224,223,223,0)),color-stop(100%, #e0dfdf));background-image:-moz-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:-webkit-linear-gradient(left, rgba(224,223,223,0) 0%,#e0dfdf 100%);background-image:linear-gradient(to right, rgba(224,223,223,0) 0%,#e0dfdf 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.region-album-songs .songs-table tr.song .crop:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00F5F5F5', endColorstr='#FFF5F5F5');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZjVmNSIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(245,245,245,0)),color-stop(100%, #f5f5f5));background-image:-moz-linear-gradient(left, rgba(245,245,245,0) 0%,#f5f5f5 100%);background-image:-webkit-linear-gradient(left, rgba(245,245,245,0) 0%,#f5f5f5 100%);background-image:linear-gradient(to right, rgba(245,245,245,0) 0%,#f5f5f5 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.songs-table tr.song a{color:rgba(43,47,48,0.7)}.songs-table tr.song a:hover{color:#2b2f30}.songs-table tr.song .play,.songs-table tr.song .play:before,.songs-table tr.song .cell-first{width:40px;height:40px}.songs-table tr.song .play{top:0;left:0;position:absolute;display:table-cell;vertical-align:middle;text-align:center;cursor:pointer;display:none;font-size:200%}.songs-table tr.song .play:before{content:"\e6b9";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.songs-table tr.song .play:before{display:table-cell;vertical-align:middle}.songs-table tr.song .play:hover{color:#2b2f30}.songs-table tr.song .thumb{width:39px;height:39px;background-position:50% 50%;background-color:transparent;display:block;background-size:cover;background-repeat:no-repeat}.songs-table tr.song .thumb{top:0px;bottom:1px;left:0;position:absolute;display:none}.songs-table tr.song .add{font-size:140%}.songs-table tr.song .add:before{content:"\e6fc";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.songs-table tr.song .thumbed-up,.songs-table tr.song .thumbs{font-size:140%}.songs-table tr.song .thumbed-up:before,.songs-table tr.song .thumbs:before{content:"\e684";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.disable-thumbs .songs-table tr.song .thumbed-up,.disable-thumbs .songs-table tr.song .thumbs{display:none}.songs-table tr.song .thumbed-up{top:0px;right:90px;position:absolute;margin-right:-2px;display:none;opacity:0.4}.songs-table tr.song .thumbed-up:before{display:table-cell;vertical-align:middle;width:40px;height:40px}.songs-table tr.song.thumbs-up .thumbed-up{display:table}.songs-table tr.song.thumbs-up .thumbs{color:#12b2e7}.songs-table tr.song .menu i{font-size:150%}.songs-table tr.song .menu i:before{content:"\e8a2";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.songs-table tr.song .menu .dropdown-menu{top:0}.songs-table tr.song .actions{top:0;right:0px;bottom:0;position:absolute;display:none;width:90px}.songs-table tr.song .actions>li{width:30px;text-align:center;float:left}.songs-table tr.song .actions>li i:before,.songs-table tr.song .actions>li:before{display:table-cell;vertical-align:middle;width:30px;height:40px;color:#999;cursor:pointer}.songs-table tr.song.menu-open .crop,.songs-table tr.song:hover .crop{white-space:normal}.songs-table tr.song.menu-open .duration,.songs-table tr.song.menu-open .track,.songs-table tr.song:hover .duration,.songs-table tr.song:hover .track{display:none}.songs-table tr.song.menu-open .play,.songs-table tr.song.menu-open .actions,.songs-table tr.song:hover .play,.songs-table tr.song:hover .actions{display:block}.songs-table tr.song.menu-open .thumbed-up,.songs-table tr.song:hover .thumbed-up{display:none}.songs-table tr.song .song-artist{display:none}@media (min-width: 57em){.songs-table tr.song .song-artist{display:table-cell}}.songs-table tr.song .song-album{display:none}.songs-table tr.song.selected{border-left:1px solid #12b2e7;background:#e2f6fd}.songs-table tr.song.selected .crop:after{display:none}.active-player-local .songs-table tr.song.selected{border-left:1px solid #db2464;background:#fbe9f0}.songs-table tr.song .cell-remove{display:none;padding-top:12px;padding-bottom:0}.songs-table tr.song.sortable-ghost{height:40px;background:#ddd}.songs-table tr.song.sortable-ghost td{opacity:0}.songs-table tr.song.sortable-ghost .play{display:none}.songs-table.verbose .track{margin-left:47px}.songs-table.verbose .play{background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;color:#fff}.songs-table.verbose tr.song .thumb{display:block}.songs-table.verbose tr.song td.song-album{width:30%}@media (min-width: 57em){.songs-table.verbose tr.song td.song-album{display:table-cell}}.songs-table.verbose tr.song td.song-title{width:80%}@media (min-width: 57em){.songs-table.verbose tr.song td.song-title{width:45%}}.songs-table.verbose tr.song td.song-artist{width:25%}.songs-table.verbose tr.song:hover .play{width:39px;height:39px}.songs-table.verbose tr.song:hover .play:hover{color:#fff}.songs-table.verbose tr.song:hover .track{display:block}.local-playlist .songs-table.verbose tr.song:hover .cell-remove{opacity:1;color:darkred}.local-playlist .songs-table.verbose tr.song:hover .cell-remove i:before{content:"\e898"}.songs-table.verbose tr.song.local-row-playing .track,.songs-table.verbose tr.song.local-row-paused .track,.songs-table.verbose tr.song.kodi-row-playing .track,.songs-table.verbose tr.song.kodi-row-paused .track{text-indent:0;background:none}.songs-table.verbose tr.song.local-row-playing .thumb,.songs-table.verbose tr.song.local-row-paused .thumb,.songs-table.verbose tr.song.kodi-row-playing .thumb,.songs-table.verbose tr.song.kodi-row-paused .thumb{background:url('../images/row-pause-blue.png?1423480412') 0 50% no-repeat !important;background-size:initial}.songs-table.verbose tr.song.local-row-playing .play,.songs-table.verbose tr.song.local-row-paused .play,.songs-table.verbose tr.song.kodi-row-playing .play,.songs-table.verbose tr.song.kodi-row-paused .play{display:none}.songs-table.verbose tr.song.kodi-row-playing .thumb{background-image:url('../images/row-playing-blue.gif?1423480525') !important}.songs-table.verbose tr.song.local-row-playing .thumb{background-image:url('../images/row-playing-pink.gif?1424158169') !important}.songs-table.verbose tr.song.local-row-paused .thumb{background-image:url('../images/row-pause-pink.png?1424158216') !important}.local-playlist .songs-table.verbose tr.song .cell-remove{display:block;opacity:0.3}.songs-table.basic .thumb{display:none}.songs-table tr.song.local-row-playing,.songs-table tr.song.local-row-paused,.songs-table tr.song.kodi-row-playing,.songs-table tr.song.kodi-row-paused{background:rgba(255,255,255,0.9) !important}.songs-table tr.song.local-row-playing:hover td .crop:after,.songs-table tr.song.local-row-playing td .crop:after,.songs-table tr.song.local-row-paused:hover td .crop:after,.songs-table tr.song.local-row-paused td .crop:after,.songs-table tr.song.kodi-row-playing:hover td .crop:after,.songs-table tr.song.kodi-row-playing td .crop:after,.songs-table tr.song.kodi-row-paused:hover td .crop:after,.songs-table tr.song.kodi-row-paused td .crop:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.songs-table tr.song.local-row-playing .track,.songs-table tr.song.local-row-paused .track,.songs-table tr.song.kodi-row-playing .track,.songs-table tr.song.kodi-row-paused .track{background:url('../images/row-pause-blue.png?1423480412') 50% 50% no-repeat;text-indent:-99999px}.songs-table tr.song.local-row-paused .track{background:url('../images/row-pause-pink.png?1424158216') 50% 50% no-repeat}.songs-table tr.song.local-row-playing .track,.songs-table tr.song.kodi-row-playing .track{background-image:url('../images/row-playing-blue.gif?1423480525')}.songs-table tr.song.local-row-playing .track{background-image:url('../images/row-playing-pink.gif?1424158169')}.box-loading{max-width:50em;margin-left:auto;margin-right:auto;width:95%;background:#fafafa url('../images/loading-box-bg.jpg?1390099084') 0 bottom repeat-x;-webkit-animation:wave 16s infinite linear;-o-animation:wave 16s infinite linear;animation:wave 16s infinite linear;margin-top:1em;padding:1em;text-align:center;font-size:28px}.box-loading:after{content:" ";display:block;clear:both}.table-row .cell-first{width:40px;min-width:40px;text-align:center;color:rgba(43,47,48,0.5);font-size:95%}.table-row .cell-last{width:80px;min-width:80px;text-align:right;color:rgba(43,47,48,0.5);font-size:95%}.content-tabs li{display:inline-block;padding:1em 2em}.content-tabs li.active{background:rgba(43,47,48,0.05)}.content-tabs li a{color:rgba(102,102,102,0.7)}.content-tabs li a.active{color:#2b2f30}.tab-content{background:rgba(43,47,48,0.05);padding:2em;margin-right:20%;color:#888}.tvshow-show .card-season .thumbs{display:none !important}.streams-short{text-align:center}.streams-short li{display:inline-block;font-size:170%;color:rgba(43,47,48,0.4);padding:0 0.5em}.trailer{position:relative;cursor:pointer}@media (min-width: 45em){.trailer{max-width:238px;float:left;margin-right:2em}}.trailer:hover:after{content:"Watch trailer";background:rgba(0,0,0,0.55);top:0;right:0;bottom:0;left:0;position:absolute;top:0;right:0;bottom:0;left:0;position:absolute;color:#fff;text-align:center;padding-top:30%;font-size:150%}.cast-full{height:141px;white-space:nowrap;overflow-y:auto}.cast-full>li{width:80px;display:inline-block;margin:0 0.6em 0 0;position:relative}.cast-full>li a{color:#2b2f30}.cast-full>li img{-webkit-filter:grayscale(100%);filter:grayscale(100%);opacity:0.8}.cast-full>li .thumb{background:#cbcbcb;overflow:hidden;letter-spacing:-0.31em;width:80px;height:105px}.cast-full>li .thumb img{display:block;vertical-align:middle;width:80px;margin-top:0}.cast-full>li .thumb .thumb{width:80px;height:105px;background-position:50% 0;background-color:#cbcbcb;display:block;background-size:cover;background-repeat:no-repeat}.cast-full>li strong{font-weight:normal}.cast-full>li span{font-size:85%;color:#666}.cast-full>li span,.cast-full>li strong{position:relative;white-space:nowrap;overflow:hidden;display:block}.cast-full>li span:after,.cast-full>li strong:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.cast-full>li .meta{position:absolute;bottom:0;z-index:20;background:#fff;padding:4px;right:0;left:0;display:none}.cast-full>li:hover img{-webkit-filter:grayscale(0%);filter:grayscale(0%);opacity:1}.cast-full>li:hover .actions{display:block}.cast-full>li .actions{bottom:4px;left:4px;position:absolute;display:none}.cast-full>li .actions li{border-radius:3px;float:left;width:15px;height:15px;cursor:pointer;font-size:1.25em;margin-right:5px;opacity:0.7}.cast-full>li .actions li:hover{opacity:1}.cast-full>li .actions li:before{display:block !important}.cast-full>li .actions li.google{color:#4285f4;font-size:1.15em;background:#fff}.cast-full>li .actions li.google:before{content:"\e900";display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.cast-full>li .actions li.imdb{color:#e3b922;background:#000}.cast-full>li .actions li.imdb:before{content:"\e901";display:inline-block;font-family:"icomoon";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.imdblink{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.imdblink .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.imdblink .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.imdblink:hover{color:#fff}.imdblink:before{content:"\e63f";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.imdblink:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.imdblink:hover:before{color:#fff}.btn-flat-play{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:#12b2e7;padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-play .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-play .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#0012B2E7', endColorstr='#FF12B2E7');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzEyYjJlNyIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMmIyZTciLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(18,178,231,0)),color-stop(100%, #12b2e7));background-image:-moz-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:-webkit-linear-gradient(left, rgba(18,178,231,0) 0%,#12b2e7 100%);background-image:linear-gradient(to right, rgba(18,178,231,0) 0%,#12b2e7 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-play:hover{color:#fff}.btn-flat-play:before{content:"\e6ba";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-play:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-play:hover:before{color:#fff}.btn-flat-add{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-add .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-add .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-add:hover{color:#fff}.btn-flat-add:before{content:"\e6fd";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-add:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-add:hover:before{color:#fff}.btn-flat-stream{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-stream .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-stream .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-stream:hover{color:#fff}.btn-flat-stream:before{content:"\e7aa";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-stream:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-stream:hover:before{color:#fff}.btn-flat-download{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-download .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-download .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-download:hover{color:#fff}.btn-flat-download:before{content:"\e6ff";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-download:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-download:hover:before{color:#fff}.btn-flat-more{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-more .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-more .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-more:hover{color:#fff}.btn-flat-more:before{content:"\e8a3";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-more:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-more:hover:before{color:#fff}.btn-flat-watched{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:rgba(255,255,255,0.1);padding:0.5em 1em;position:relative;cursor:pointer;margin:0 0.5em 0.5em 0;color:#fff;text-transform:capitalize;padding-right:2.5em}.btn-flat-watched .text{position:relative;white-space:nowrap;overflow:hidden;display:block}.btn-flat-watched .text:after{content:"";*zoom:1;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#00FFFFFF', endColorstr='#1AFFFFFF');background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');background-size:100%;background-image:-webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(255,255,255,0)),color-stop(100%, #ffffff));background-image:-moz-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%,#ffffff 100%);background-image:linear-gradient(to right, rgba(255,255,255,0) 0%,#ffffff 100%);top:0;right:0;bottom:0;position:absolute;width:1.5em}.btn-flat-watched:hover{color:#fff}.btn-flat-watched:before{content:"\e8e1";display:inline-block;font-family:"Material-Design-Icons";font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;speak:none;font-variant:normal;text-transform:none}.btn-flat-watched:before{top:9px;right:0.5em;position:absolute;color:rgba(255,255,255,0.5);font-size:110%}.btn-flat-watched:hover:before{color:#fff}.btn-flat-watched .action-watched{display:inline}.btn-flat-watched .action-unwatched{display:none}.is-watched .btn-flat-watched .action-watched{display:none}.is-watched .btn-flat-watched .action-unwatched{display:inline}.entity-progress{top:-2px;right:0;left:0;position:absolute;z-index:10}.entity-progress .current-progress{-webkit-transition:width 0.3s linear;-o-transition:width 0.3s linear;transition:width 0.3s linear;height:3px;background:#12b2e7}.season-show .card .show-name,.season-show .card .ep-num{display:none}.landing-page .card .ep-num-full{display:none}.lab--items h3{margin-bottom:2em;font-size:1.3em;margin-top:0}.lab-item{padding:1em;background:rgba(0,0,0,0.05);display:block;margin-bottom:0.5em}.lab-item p{color:#2b2f30}.lab-item:hover{background:rgba(0,0,0,0.1)}.api-browser--methods{padding:1em}.api-browser--method{padding:0.5em 0 0}.api-browser--method h4{font-size:1.05em;margin:0 0 0.25em 0}.api-browser--method p{font-size:90%;opacity:0.5;height:0;overflow:hidden;margin:0 0 0.25em}.api-browser--method .api-method--item{border-bottom:1px solid #ddd;cursor:pointer}.api-browser--method:hover h4{color:#12b2e7;font-weight:700}.api-browser--method:hover p{height:100%}.api-browser--page{padding:0 0.5em;margin-bottom:2em}.api-browser--page .description{font-size:90%;opacity:0.6}.api-method--execute{max-width:58em}.api-method--execute textarea{display:block;width:100%;margin:0.5em 0;padding:0.5em;height:200px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:1px solid #ddd}.api-browser--content{margin:2em 0}.json-syntax-highlight{background:rgba(245,245,245,0.74)}.json-syntax-highlight .string{color:green}.json-syntax-highlight .number{color:darkorange}.json-syntax-highlight .boolean{color:blue}.json-syntax-highlight .null{color:#bd09bd}.json-syntax-highlight .key{color:#bb1313}.icon-browser{max-width:none;background:rgba(255,255,255,0.5)}.icon-browser h3{padding-bottom:0.5em;border-bottom:1px solid #ddd;margin-bottom:0.5em}.icon-browser i{font-size:3.1em;margin-right:0.25em;float:left}.icon-browser li{border-radius:5px;width:210px;padding:0.5em;margin:0.5em;overflow:hidden;float:left;height:65px;position:relative}.icon-browser li span{display:block;font-size:85%}.icon-browser li small{right:0;bottom:0;left:0;position:absolute;padding:4px;background:rgba(153,153,153,0.5);text-align:center;display:none}.icon-browser li:hover{background:#fff}.icon-browser li:hover small{display:block} diff --git a/addons/webinterface.default/videoPlayer.html b/addons/webinterface.default/videoPlayer.html index 53268cc625..2ee7e3e7b3 100644 --- a/addons/webinterface.default/videoPlayer.html +++ b/addons/webinterface.default/videoPlayer.html @@ -2,18 +2,29 @@ <html lang="en"> <head> <meta charset="utf-8"> - <title>Chorus video</title> + <title>Chorus Video Player</title> - <link href="//vjs.zencdn.net/5.11.7/video-js.css" rel="stylesheet"> - <script src="//code.jquery.com/jquery-1.11.0.min.js"></script> + <link href="lib/video-js/video-js.min.css" rel="stylesheet"> + <link href="lib/video-js/plugins/videojs-chromecast/videojs-chromecast.css?01217" rel="stylesheet"> + + <script src="lib/jquery/jquery-1.11.0.min.js"></script> + <script type="text/javascript" src="lib/video-js/plugins/videojs-chromecast/cast_sender.js"></script> <script> + + // Helpers. function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } + function getBaseURL() { + var parts = window.location.href.split('videoPlayer.html'); + return parts[0]; + } + + // Vars. var src = getParameterByName('src'), player = getParameterByName('player'), yt = getParameterByName('yt'), @@ -23,7 +34,7 @@ height = '90%', id = "videoplayer"; - // do we have something to play? + // Do we have something to play? if(src != ''){ // Make the html5 player @@ -35,16 +46,16 @@ "preload": "auto", "autoplay": "autoplay", "data-setup": JSON.stringify({}), - "poster": bg + "poster": getBaseURL() + bg }); $player.append($('<source>', { "type": 'video/mp4', - "src": src + "src": getBaseURL() + src })); $player.attr('width', width).attr('height', height); } - // Make the VLC player + // Make the VLC player. if(player == 'vlc'){ $player = $('<embed>', { "type": "application/x-vlc-plugin", @@ -57,7 +68,7 @@ }); } - // Make the divX player + // Make the divX player. if(player == 'divx'){ $player = $('<object>', { "id": id, @@ -82,24 +93,30 @@ })); } - - // Dom ready actions + // Dom ready actions. $(document).ready(function(){ // update download link - $('#download').attr('href', src); + $('.dl').attr('href', src); + + $('#stream').click(function(e){ + e.preventDefault($(this).attr('href')); + console.log($(this).attr('href')); + window.location = $(this).attr('href'); + }); - // Switch player + // Switch player. $('#switch-player') .val(player) .on('change', function(e){ - var url = 'videoPlayer.html?player=' + $(this).val() + '&src=' + src; + var url = 'videoPlayer.html?player=' + $(this).val() + '&src=' + encodeURIComponent(src) + '&bg=' + encodeURIComponent(bg); window.location = url; }); }); } else if (yt != '') { + // If playing a youtube video. $player = $('<iframe>', { width: width, height: height, @@ -108,8 +125,8 @@ allowfullscreen: 'allowfullscreen' }); $(document).ready(function(){ - $('switch-player').empty(); - $('download').empty(); + $('#switch-player').empty(); + $('#download').empty(); }); } </script> @@ -118,7 +135,11 @@ height: 100%; } body { - margin: 0; background: #000; padding: 0; overflow: hidden; + margin: 0; background: #000; padding: 0; overflow: hidden; color: #333; + } + a { + color: #333; + text-decoration: none; } #player { margin: 0px 10px 0; @@ -126,21 +147,19 @@ margin-top: 1%; } #switch-player, - #download { + #actions { display: block; - color: #333; font: 12px Arial, Helvetica, "Nimbus Sans L", sans-serif; margin: 1px 0 0; padding: 5px 10px 0 0; float: right; - text-decoration: none; } #switch-player { float: left; padding: 5px 0 0 10px; } select:hover, - #download:hover { + .dl:hover { color: #aaa; } #videoplayer { @@ -170,22 +189,37 @@ height: 100%; border: none; } + .vjs-error .vjs-error-display .vjs-modal-dialog-content { + background: rgba(0,0,0,0.5); + height: auto; + font-size: 1.7em; + padding: 2% 15%; + top: auto; + bottom: 5%; + } + .vjs-error .vjs-error-display:before { + display: none; + } </style> </head> <body> -<div class="player-wrapper"> - <div id="player"> - </div> - <div id="player-actions"> - <a href="" id="download" download>Download video</a> - <select id="switch-player"> - <option value="html5">html5</option> - <option value="vlc">VLC Web player</option> - <option value="divx">DivX Webplayer</option> - </select> + <div class="player-wrapper"> + <div id="player"> + </div> + <div id="player-actions"> + <div id="actions"> + <a href="" title="Force download of this video" class="dl" id="download" download>Download</a> - + <a href="" title="Navigate to video so the browser can try and native stream it. Some browsers may still download" class="dl" id="stream">Stream</a> + </div> + <select id="switch-player"> + <option value="html5">html5</option> + <option value="vlc">VLC Web player</option> + <option value="divx">DivX Webplayer</option> + </select> + </div> </div> -</div> -<script> $('#player').prepend($player);</script> -<script src="//vjs.zencdn.net/5.11.7/video.js"></script> + <script> $('#player').prepend($player);</script> + <script src="lib/video-js/video.min.js"></script> + <script src="lib/video-js/plugins/videojs-chromecast/videojs-chromecast.min.js"></script> </body> </html>
\ No newline at end of file diff --git a/cmake/addons/CMakeLists.txt b/cmake/addons/CMakeLists.txt index f1e2fce04a..a6ea149e3f 100644 --- a/cmake/addons/CMakeLists.txt +++ b/cmake/addons/CMakeLists.txt @@ -327,7 +327,12 @@ foreach(addon ${addons}) file(DOWNLOAD "${url}" "${BUILD_DIR}/download/${archive_name}.tar.gz" STATUS dlstatus LOG dllog SHOW_PROGRESS) list(GET dlstatus 0 retcode) if(NOT ${retcode} EQUAL 0) - message(FATAL_ERROR "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}") + file(REMOVE ${BUILD_DIR}/download/${archive_name}.tar.gz) + message(STATUS "ERROR downloading ${url} - status: ${dlstatus} log: ${dllog}") + # add a dummy target for addons to get it in addons failure file + list(APPEND ALL_ADDONS_BUILDING ${id}) + add_custom_target(${id} COMMAND ${CMAKE_COMMAND} -E echo "IGNORED ${id} - download failed" COMMAND exit 1) + continue() endif() endif() diff --git a/cmake/cpack/deb/packages/kodi-image-dev.txt.in b/cmake/cpack/deb/packages/kodi-image-dev.txt.in new file mode 100644 index 0000000000..e9b72f144e --- /dev/null +++ b/cmake/cpack/deb/packages/kodi-image-dev.txt.in @@ -0,0 +1,25 @@ +# kodi-image-dev debian package metadata +# +# Setting PACKAGE_SHLIBDEPS to 'ON' will cause CPack to use dpkg-shlibdeps to +# automatically generate the package dependency list and append its output to +# PACKAGE_DEPENDS list. Only useful for packages that contain binaries. +# +# PACKAGE_ARCHITECTURE should be set to 'all' only if package contains +# architecture agnostic data. CPack will set proper architecture (amd64/i386/etc) +# based on build options. +# +# Remaining settings are (hopefully) self-explanatory. + +PACKAGE_NAME @APP_NAME_LC@-image-dev +PACKAGE_ARCHITECTURE all +PACKAGE_SECTION libdevel +PACKAGE_PRIORITY optional +PACKAGE_SHLIBDEPS +PACKAGE_DEPENDS @APP_NAME_LC@-addon-dev +PACKAGE_RECOMMENDS +PACKAGE_SUGGESTS +PACKAGE_BREAKS +PACKAGE_REPLACES +PACKAGE_PROVIDES xbmc-image-dev +PACKAGE_DESCRIPTION_HEADER @APP_NAME@ Media Center (image add-ons dev package) +PACKAGE_DESCRIPTION_FOOTER This is the development package for @APP_NAME@'s image add-ons. diff --git a/cmake/installdata/common/addons.txt b/cmake/installdata/common/addons.txt index ad951eced6..0c8f296b59 100644 --- a/cmake/installdata/common/addons.txt +++ b/cmake/installdata/common/addons.txt @@ -5,6 +5,7 @@ addons/game.controller.default/* addons/kodi.adsp/* addons/kodi.audiodecoder/* addons/kodi.game/* +addons/kodi.imagedecoder/* addons/kodi.inputstream/* addons/kodi.peripheral/* addons/kodi.resource/* diff --git a/cmake/modules/FindEMBEDDED.cmake b/cmake/modules/FindEMBEDDED.cmake index 5e49716549..8034c4e959 100644 --- a/cmake/modules/FindEMBEDDED.cmake +++ b/cmake/modules/FindEMBEDDED.cmake @@ -13,4 +13,4 @@ if(NOT KODI_DEPENDSBUILD AND NOT TARGET_ARCH_ARM) return() endif() -find_path(EMBEDDED_FOUND NAMES include/linux/imxfb.h include/bcm_host.h PATHS /opt/vc) +find_path(EMBEDDED_FOUND NAMES include/linux/mxcfb.h include/bcm_host.h PATHS /opt/vc) diff --git a/cmake/scripts/ios/ArchSetup.cmake b/cmake/scripts/ios/ArchSetup.cmake index bdd2656c1b..dbb7c4858e 100644 --- a/cmake/scripts/ios/ArchSetup.cmake +++ b/cmake/scripts/ios/ArchSetup.cmake @@ -36,7 +36,7 @@ list(APPEND DEPLIBS "-framework CoreFoundation" "-framework CoreVideo" set(ENABLE_DVDCSS OFF CACHE BOOL "" FORCE) set(ENABLE_OPTICAL OFF CACHE BOOL "" FORCE) -set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "5.1") +set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "6.0") set(CMAKE_XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2") set(CMAKE_XCODE_ATTRIBUTE_INLINES_ARE_PRIVATE_EXTERN OFF) diff --git a/cmake/scripts/linux/Install.cmake b/cmake/scripts/linux/Install.cmake index e2baab09f0..aee45dd55f 100644 --- a/cmake/scripts/linux/Install.cmake +++ b/cmake/scripts/linux/Install.cmake @@ -191,6 +191,12 @@ install(FILES ${CMAKE_SOURCE_DIR}/xbmc/cores/AudioEngine/Utils/AEChannelData.h DESTINATION ${includedir}/${APP_NAME_LC} COMPONENT kodi-audio-dev) +# Install kodi-image-dev +install(FILES ${CMAKE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h + ${CMAKE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h + DESTINATION ${includedir}/${APP_NAME_LC} + COMPONENT kodi-image-dev) + if(ENABLE_EVENTCLIENTS) # Install kodi-eventclients-common BT python files install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/bt/__init__.py diff --git a/cmake/treedata/linux/subdirs.txt b/cmake/treedata/linux/subdirs.txt index 2dc80450d0..b8e84311d6 100644 --- a/cmake/treedata/linux/subdirs.txt +++ b/cmake/treedata/linux/subdirs.txt @@ -10,4 +10,5 @@ xbmc/storage/linux storage/linux xbmc/filesystem/posix filesystem/posix xbmc/utils/posix utils_posix xbmc/windowing/egl windowing/egl +xbmc/windowing/X11 windowing/X11 xbmc/platform/posix posix diff --git a/cmake/treedata/optional/common/X11.txt b/cmake/treedata/optional/common/X11.txt deleted file mode 100644 index f4afa572dd..0000000000 --- a/cmake/treedata/optional/common/X11.txt +++ /dev/null @@ -1 +0,0 @@ -xbmc/windowing/X11 windowing/X11 # X11 diff --git a/docs/README.ios.md b/docs/README.ios.md index 0a3adb56da..c7f9332153 100644 --- a/docs/README.ios.md +++ b/docs/README.ios.md @@ -60,6 +60,8 @@ constellations of Xcode and macOS versions (to be updated once we know more): 5. Xcode 7.x against iOS SDK 9.x on 10.10 (Yosemite) 6. Xcode 7.x against iOS SDK 9.x on 10.11 (El Capitan) 7. Xcode 7.x against iOS SDK 9.x on 10.12 (Sierra) +8. Xcode 8.x against iOS SDK 10.x (El Capitan) +9. Xcode 8.x against iOS SDK 10.x (Sierra) The preferred iOS SDK Version is 8.1. diff --git a/system/addon-manifest.xml b/system/addon-manifest.xml index fd7737470e..8d557bde9d 100644 --- a/system/addon-manifest.xml +++ b/system/addon-manifest.xml @@ -6,6 +6,7 @@ <addon>kodi.audiodecoder</addon> <addon>kodi.game</addon> <addon>kodi.guilib</addon> + <addon>kodi.imagedecoder</addon> <addon>kodi.inputstream</addon> <addon>kodi.peripheral</addon> <addon>kodi.resource</addon> diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml index 0db5d7d9cb..eefa1dd0d2 100644 --- a/system/keymaps/keyboard.xml +++ b/system/keymaps/keyboard.xml @@ -183,6 +183,7 @@ </Home> <VirtualKeyboard> <keyboard> + <c mod="longpress">noop</c> <left>Left</left> <right>Right</right> <up>Up</up> diff --git a/system/library/video/movies/actors.xml b/system/library/video/movies/actors.xml index 48a0912272..ceccc45dc9 100644 --- a/system/library/video/movies/actors.xml +++ b/system/library/video/movies/actors.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="4" type="filter"> +<node order="5" type="filter"> <label>344</label> <icon>DefaultActor.png</icon> <content>movies</content> diff --git a/system/library/video/movies/country.xml b/system/library/video/movies/country.xml index 1b68b82201..2f5a54f6d0 100644 --- a/system/library/video/movies/country.xml +++ b/system/library/video/movies/country.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="8" type="filter"> +<node order="9" type="filter"> <label>20451</label> <icon>DefaultCountry.png</icon> <content>movies</content> diff --git a/system/library/video/movies/directors.xml b/system/library/video/movies/directors.xml index f074dcb6c0..60c672442f 100644 --- a/system/library/video/movies/directors.xml +++ b/system/library/video/movies/directors.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="5" type="filter"> +<node order="6" type="filter"> <label>20348</label> <icon>DefaultDirector.png</icon> <content>movies</content> diff --git a/system/library/video/movies/genres.xml b/system/library/video/movies/genres.xml index 1764b03ed3..d57c7069dd 100644 --- a/system/library/video/movies/genres.xml +++ b/system/library/video/movies/genres.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="1" type="filter"> +<node order="2" type="filter"> <label>135</label> <icon>DefaultGenre.png</icon> <content>movies</content> diff --git a/system/library/video/movies/recentlyaddedmovies.xml b/system/library/video/movies/recentlyaddedmovies.xml index 721d45237a..e61c22af2e 100644 --- a/system/library/video/movies/recentlyaddedmovies.xml +++ b/system/library/video/movies/recentlyaddedmovies.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="10" type="folder"> - <label>20386</label> +<node order="1" type="folder"> + <label>20382</label> <icon>DefaultRecentlyAddedMovies.png</icon> <path>videodb://recentlyaddedmovies/</path> </node> diff --git a/system/library/video/movies/sets.xml b/system/library/video/movies/sets.xml index 4f1e065b30..e8e9491907 100644 --- a/system/library/video/movies/sets.xml +++ b/system/library/video/movies/sets.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="7" type="filter" visible="Library.HasContent(MovieSets)"> +<node order="8" type="filter" visible="Library.HasContent(MovieSets)"> <label>20434</label> <icon>DefaultSets.png</icon> <content>movies</content> diff --git a/system/library/video/movies/studios.xml b/system/library/video/movies/studios.xml index 6dd1f77ed8..d167cb8945 100644 --- a/system/library/video/movies/studios.xml +++ b/system/library/video/movies/studios.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="6" type="filter"> +<node order="7" type="filter"> <label>20388</label> <icon>DefaultStudios.png</icon> <content>movies</content> diff --git a/system/library/video/movies/tags.xml b/system/library/video/movies/tags.xml index f2f09c370e..92b6521b2e 100644 --- a/system/library/video/movies/tags.xml +++ b/system/library/video/movies/tags.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="9" type="filter"> +<node order="10" type="filter"> <label>20459</label> <icon>DefaultTags.png</icon> <content>movies</content> diff --git a/system/library/video/movies/titles.xml b/system/library/video/movies/titles.xml index ec41450b2f..9dfd483080 100644 --- a/system/library/video/movies/titles.xml +++ b/system/library/video/movies/titles.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="2" type="filter"> +<node order="3" type="filter"> <label>10024</label> <icon>DefaultMovieTitle.png</icon> <content>movies</content> diff --git a/system/library/video/movies/years.xml b/system/library/video/movies/years.xml index 234bd9a963..30217f7740 100644 --- a/system/library/video/movies/years.xml +++ b/system/library/video/movies/years.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="3" type="filter"> +<node order="4" type="filter"> <label>652</label> <icon>DefaultYear.png</icon> <content>movies</content> diff --git a/system/library/video/musicvideos/albums.xml b/system/library/video/musicvideos/albums.xml index ce44b5b6d6..ee0fbf9574 100644 --- a/system/library/video/musicvideos/albums.xml +++ b/system/library/video/musicvideos/albums.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="5" type="filter"> +<node order="6" type="filter"> <label>132</label> <icon>DefaultMusicAlbums.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/artists.xml b/system/library/video/musicvideos/artists.xml index 4913592fd8..f73acd8ad7 100644 --- a/system/library/video/musicvideos/artists.xml +++ b/system/library/video/musicvideos/artists.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="4" type="filter"> +<node order="5" type="filter"> <label>133</label> <icon>DefaultMusicArtists.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/directors.xml b/system/library/video/musicvideos/directors.xml index 880742b656..06cc0e06d4 100644 --- a/system/library/video/musicvideos/directors.xml +++ b/system/library/video/musicvideos/directors.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="6" type="filter"> +<node order="7" type="filter"> <label>20348</label> <icon>DefaultDirector.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/genres.xml b/system/library/video/musicvideos/genres.xml index ed4812150e..77745f8a01 100644 --- a/system/library/video/musicvideos/genres.xml +++ b/system/library/video/musicvideos/genres.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="1" type="filter"> +<node order="2" type="filter"> <label>135</label> <icon>DefaultGenre.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/recentlyaddedmusicvideos.xml b/system/library/video/musicvideos/recentlyaddedmusicvideos.xml index a8ee085e71..fed8cba25f 100644 --- a/system/library/video/musicvideos/recentlyaddedmusicvideos.xml +++ b/system/library/video/musicvideos/recentlyaddedmusicvideos.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="12" type="folder"> - <label>20390</label> +<node order="1" type="folder"> + <label>20382</label> <icon>DefaultRecentlyAddedMusicVideos.png</icon> <path>videodb://recentlyaddedmusicvideos/</path> </node> diff --git a/system/library/video/musicvideos/studios.xml b/system/library/video/musicvideos/studios.xml index 82023a4993..b6f2f779d3 100644 --- a/system/library/video/musicvideos/studios.xml +++ b/system/library/video/musicvideos/studios.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="7" type="filter"> +<node order="8" type="filter"> <label>20388</label> <icon>DefaultStudios.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/tags.xml b/system/library/video/musicvideos/tags.xml index c63f826200..284bd4c9dd 100644 --- a/system/library/video/musicvideos/tags.xml +++ b/system/library/video/musicvideos/tags.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="8" type="filter"> +<node order="9" type="filter"> <label>20459</label> <icon>DefaultTags.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/titles.xml b/system/library/video/musicvideos/titles.xml index adfcb1e254..aab72a993b 100644 --- a/system/library/video/musicvideos/titles.xml +++ b/system/library/video/musicvideos/titles.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="2" type="filter"> +<node order="3" type="filter"> <label>10024</label> <icon>DefaultMusicVideoTitle.png</icon> <content>musicvideos</content> diff --git a/system/library/video/musicvideos/years.xml b/system/library/video/musicvideos/years.xml index 1f11fdf114..622002bc48 100644 --- a/system/library/video/musicvideos/years.xml +++ b/system/library/video/musicvideos/years.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="3" type="filter"> +<node order="4" type="filter"> <label>652</label> <icon>DefaultYear.png</icon> <content>musicvideos</content> diff --git a/system/library/video/tvshows/actors.xml b/system/library/video/tvshows/actors.xml index 8e4f10ea04..19fc20eeb4 100644 --- a/system/library/video/tvshows/actors.xml +++ b/system/library/video/tvshows/actors.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="4" type="filter"> +<node order="6" type="filter"> <label>344</label> <icon>DefaultActor.png</icon> <content>tvshows</content> diff --git a/system/library/video/tvshows/genres.xml b/system/library/video/tvshows/genres.xml index f3445092b0..bc066ce55c 100644 --- a/system/library/video/tvshows/genres.xml +++ b/system/library/video/tvshows/genres.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="1" type="filter"> +<node order="3" type="filter"> <label>135</label> <icon>DefaultGenre.png</icon> <content>tvshows</content> diff --git a/system/library/video/tvshows/inprogressshows.xml b/system/library/video/tvshows/inprogressshows.xml index 146230c6ca..df725caee9 100644 --- a/system/library/video/tvshows/inprogressshows.xml +++ b/system/library/video/tvshows/inprogressshows.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="4" type="folder"> - <label>626</label> +<node order="2" type="folder"> + <label>575</label> <icon>DefaultInProgressShows.png</icon> <path>videodb://inprogresstvshows/</path> </node> diff --git a/system/library/video/tvshows/recentlyaddedepisodes.xml b/system/library/video/tvshows/recentlyaddedepisodes.xml index 6cf35dbfa6..3cfcda83cb 100644 --- a/system/library/video/tvshows/recentlyaddedepisodes.xml +++ b/system/library/video/tvshows/recentlyaddedepisodes.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="11" type="folder"> - <label>20387</label> +<node order="1" type="folder"> + <label>20382</label> <icon>DefaultRecentlyAddedEpisodes.png</icon> <path>videodb://recentlyaddedepisodes/</path> </node> diff --git a/system/library/video/tvshows/studios.xml b/system/library/video/tvshows/studios.xml index a7b49b9d3b..a7e1d24bda 100644 --- a/system/library/video/tvshows/studios.xml +++ b/system/library/video/tvshows/studios.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="5" type="filter"> +<node order="7" type="filter"> <label>20388</label> <icon>DefaultStudios.png</icon> <content>tvshows</content> diff --git a/system/library/video/tvshows/tags.xml b/system/library/video/tvshows/tags.xml index 3bf9076d6e..6577990817 100644 --- a/system/library/video/tvshows/tags.xml +++ b/system/library/video/tvshows/tags.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="6" type="filter"> +<node order="8" type="filter"> <label>20459</label> <icon>DefaultTags.png</icon> <content>tvshows</content> diff --git a/system/library/video/tvshows/titles.xml b/system/library/video/tvshows/titles.xml index c2415246ab..427f2674de 100644 --- a/system/library/video/tvshows/titles.xml +++ b/system/library/video/tvshows/titles.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="2" type="filter"> +<node order="4" type="filter"> <label>10024</label> <icon>DefaultTVShowTitle.png</icon> <content>tvshows</content> diff --git a/system/library/video/tvshows/years.xml b/system/library/video/tvshows/years.xml index 1ea069d30d..26e1f1edc9 100644 --- a/system/library/video/tvshows/years.xml +++ b/system/library/video/tvshows/years.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<node order="3" type="filter"> +<node order="5" type="filter"> <label>652</label> <icon>DefaultYear.png</icon> <content>tvshows</content> diff --git a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp index 3d232d26f8..a4efd8af65 100644 --- a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp +++ b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp @@ -163,7 +163,7 @@ void CWiiRemote::SetBluetoothAddress(const char *btaddr) bacpy(&m_btaddr, &b); } -void CWiiRemote::SetSensativity(float DeadX, float DeadY, int NumSamples) +void CWiiRemote::SetSensitivity(float DeadX, float DeadY, int NumSamples) { m_NumSamples = NumSamples; @@ -742,8 +742,8 @@ int main(int argc, char **argv) g_Ping = new CPacketHELO("WiiRemote", ICON_PNG, g_BluetoothIconPath.c_str()); g_WiiRemote.Initialize(my_addr, sockfd); g_WiiRemote.SetBluetoothAddress(btaddr); - g_WiiRemote.SetSensativity(DeadX, DeadY, NumSamples); - g_WiiRemote.SetSensativity(DeadX, DeadY, NumSamples); + g_WiiRemote.SetSensitivity(DeadX, DeadY, NumSamples); + g_WiiRemote.SetSensitivity(DeadX, DeadY, NumSamples); g_WiiRemote.SetJoystickMap(JoyMap); if (g_AllowMouse) g_WiiRemote.EnableMouseEmulation(); diff --git a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h index 3a60479ca1..5dd7333fd3 100644 --- a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h +++ b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h @@ -90,7 +90,7 @@ public: bool Connect(); void SetBluetoothAddress(const char * btaddr); - void SetSensativity(float DeadX, float DeadY, int Samples); + void SetSensitivity(float DeadX, float DeadY, int Samples); void SetJoystickMap(const char *JoyMap); private: int m_NumSamples; diff --git a/tools/codegenerator/Helper.groovy b/tools/codegenerator/Helper.groovy index cf195a2dfe..2b474aeb16 100644 --- a/tools/codegenerator/Helper.groovy +++ b/tools/codegenerator/Helper.groovy @@ -43,7 +43,7 @@ public class Helper public static String newline = System.getProperty("line.separator"); public static File curTemplateFile = null; - public static void setTempateFile(File templateFile) { curTemplateFile = templateFile } + public static void setTemplateFile(File templateFile) { curTemplateFile = templateFile } /** * In order to use any of the typemap helper features, the Helper class needs to be initialized with @@ -57,7 +57,7 @@ public class Helper public static void setup(def template,List pclasses, Map poutTypemap, def defaultOutTypemap, Map pinTypemap, def defaultInTypemap) { - setTempateFile(template.binding.templateFile) + setTemplateFile(template.binding.templateFile) classes = pclasses ? pclasses : [] if (poutTypemap) outTypemap.putAll(poutTypemap) if (defaultOutTypemap) defaultOutTypeConversion = defaultOutTypemap diff --git a/tools/darwin/Configurations/App-iOS.xcconfig b/tools/darwin/Configurations/App-iOS.xcconfig index b7145c3c04..b70faba9a7 100644 --- a/tools/darwin/Configurations/App-iOS.xcconfig +++ b/tools/darwin/Configurations/App-iOS.xcconfig @@ -23,7 +23,7 @@ PRODUCT_NAME = $(APP_NAME) //build against latest SDKROOT = iphoneos -IPHONEOS_DEPLOYMENT_TARGET = 5.1 +IPHONEOS_DEPLOYMENT_TARGET = 6.0 ARCHS = armv7 VALID_ARCHS = armv7 diff --git a/tools/darwin/Support/Codesign.command b/tools/darwin/Support/Codesign.command index ff09f12309..528f74a0be 100755 --- a/tools/darwin/Support/Codesign.command +++ b/tools/darwin/Support/Codesign.command @@ -28,8 +28,13 @@ if [ "${PLATFORM_NAME}" == "iphoneos" ] || [ "${PLATFORM_NAME}" == "appletvos" ] # pull the CFBundleIdentifier out of the built xxx.app BUNDLEID=`mdls -raw -name kMDItemCFBundleIdentifier ${CODESIGNING_FOLDER_PATH}` + if [ "${BUNDLEID}" == "(null)" ] ; then + BUNDLEID=`/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' ${CODESIGNING_FOLDER_PATH}/Info.plist` + fi + echo "CFBundleIdentifier is ${BUNDLEID}" + # Prefer the expanded name, if available. CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}" if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac index ac2ac3cf68..a947ec8e10 100644 --- a/tools/depends/configure.ac +++ b/tools/depends/configure.ac @@ -341,7 +341,7 @@ case $host in found_sdk_version=[`$use_xcodebuild -showsdks | grep $target_platform | sort | tail -n 1 | awk '{ print $2}'`] use_sdk="${use_sdk:-$found_sdk_version}" sdk_name=$target_platform$use_sdk - platform_min_version="$target_platform-version-min=5.1" + platform_min_version="$target_platform-version-min=6.0" fi case $use_sdk in 4.*);; @@ -350,6 +350,7 @@ case $host in 7.*);; 8.*);; 9.*);; + 10.*);; *) AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk) ;; diff --git a/tools/depends/target/config-binaddons.site.in b/tools/depends/target/config-binaddons.site.in index d71c378810..47b3fcecc4 100644 --- a/tools/depends/target/config-binaddons.site.in +++ b/tools/depends/target/config-binaddons.site.in @@ -128,6 +128,12 @@ fi if test "@platform_os@" = "ios"; then + # Xcode 8 + 10.11, clock_gettime getentropy is present + # in 10.12 but will get wrongly detected if building on 10.11 + ac_cv_search_clock_gettime=no + ac_cv_func_clock_gettime=no + ac_cv_func_getentropy=no + # tweaks for libffi (ios must use llvm-gcc-4.2) if test "${PACKAGE_NAME}" = "libffi" ; then case "@use_xcode@" in diff --git a/tools/depends/target/config.site.in b/tools/depends/target/config.site.in index 8c7e68d47b..76a32a9b4b 100644 --- a/tools/depends/target/config.site.in +++ b/tools/depends/target/config.site.in @@ -150,6 +150,12 @@ fi if test "@platform_os@" = "ios"; then + # Xcode 8 + 10.11, clock_gettime and getentropy is present + # in 10.12 but will get wrongly detected if building on 10.11 + ac_cv_search_clock_gettime=no + ac_cv_func_clock_gettime=no + ac_cv_func_getentropy=no + # tweaks for libffi (ios must use llvm-gcc-4.2) if test "${PACKAGE_NAME}" = "libffi" ; then case "@use_xcode@" in diff --git a/tools/depends/target/curl/Makefile b/tools/depends/target/curl/Makefile index 11d85b9ef6..1d1dff194f 100644 --- a/tools/depends/target/curl/Makefile +++ b/tools/depends/target/curl/Makefile @@ -30,6 +30,9 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) ifeq (osx, $(findstring osx, $(OS))) cd $(PLATFORM); patch -p1 < ../0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch endif +ifeq (darwin, $(findstring darwin, $(HOST))) + cd $(PLATFORM); sed -ie "s/elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)/#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC_NOPE)/" lib/timeval.c +endif cd $(PLATFORM); $(CONFIGURE) $(LIBDYLIB): $(PLATFORM) diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index eaf9fc4931..6368b778b5 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -79,6 +79,9 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) cd $(PLATFORM);\ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ ./configure $(ffmpg_config) +ifeq ($(OS), ios) + cd $(PLATFORM); sed -i -- 's/HAVE_CLOCK_GETTIME 1/HAVE_CLOCK_GETTIME 0/g' config.h +endif build: $(PLATFORM) $(MAKE) -C $(PLATFORM) diff --git a/tools/depends/target/gnutls/Makefile b/tools/depends/target/gnutls/Makefile index 1a7c2431c8..69efb3a5a1 100644 --- a/tools/depends/target/gnutls/Makefile +++ b/tools/depends/target/gnutls/Makefile @@ -33,7 +33,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) cd $(PLATFORM); patch -p0 < ../size-max.patch cd $(PLATFORM); $(CONFIGURE) -ifeq ($(OS),osx) +ifeq (darwin, $(findstring darwin, $(HOST))) cd $(PLATFORM); sed -ie "s/HAVE_GETENTROPY/HAVE_GETENTROPY_NOPE/" config.h endif diff --git a/tools/depends/target/samba-gplv3/Makefile b/tools/depends/target/samba-gplv3/Makefile index f5d84bac76..e15987d9c4 100644 --- a/tools/depends/target/samba-gplv3/Makefile +++ b/tools/depends/target/samba-gplv3/Makefile @@ -55,7 +55,7 @@ endif ifeq ($(TARGET_PLATFORM),appletvos) cd $(PLATFORM); patch -p0 < ../no_fork_and_exec.patch endif -ifeq ($(OS),osx) +ifeq (darwin, $(findstring darwin, $(HOST))) sed -ie "s|ifndef HAVE_CLOCK_GETTIME|if !defined(HAVE_CLOCK_GETTIME) \&\& !defined(CLOCK_REALTIME)|" "$(PLATFORM)/lib/replace/system/time.h" endif cd $(PLATFORM)/source3; $(CONFIGURE) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 8b812302f7..038a541d81 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -1067,10 +1067,10 @@ void CApplication::CreateUserDirs() const //Let's clear our archive cache before starting up anything more auto archiveCachePath = CSpecialProtocol::TranslatePath("special://temp/archive_cache/"); - if (CDirectory::RemoveRecursive(archiveCachePath)) - CDirectory::Create(archiveCachePath); - else - CLog::Log(LOGWARNING, "Failed to remove the archive cache at %s", archiveCachePath.c_str()); + if (CDirectory::Exists(archiveCachePath)) + if (!CDirectory::RemoveRecursive(archiveCachePath)) + CLog::Log(LOGWARNING, "Failed to remove the archive cache at %s", archiveCachePath.c_str()); + CDirectory::Create(archiveCachePath); } @@ -2585,7 +2585,7 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg) else pathToUrl = URIUtils::CreateArchivePath("rar", CURL(pMsg->strParam), ""); - CUtil::GetRecursiveListing(pathToUrl.Get(), items, g_advancedSettings.m_pictureExtensions, XFILE::DIR_FLAG_NO_FILE_DIRS); + CUtil::GetRecursiveListing(pathToUrl.Get(), items, g_advancedSettings.GetPictureExtensions(), XFILE::DIR_FLAG_NO_FILE_DIRS); if (items.Size() > 0) { pSlideShow->Reset(); @@ -2620,7 +2620,7 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg) CFileItemList items; std::string strPath = pMsg->strParam; - std::string extensions = g_advancedSettings.m_pictureExtensions; + std::string extensions = g_advancedSettings.GetPictureExtensions(); if (pMsg->param1) extensions += "|.tbn"; CUtil::GetRecursiveListing(strPath, items, extensions); @@ -2745,11 +2745,14 @@ void CApplication::FrameMove(bool processEvents, bool processGUI) CSingleExit ex(g_graphicsContext); m_frameMoveGuard.unlock(); // Calculate a window size between 2 and 10ms, 4 continuous requests let the window grow by 1ms - unsigned int sleepTime = std::max(static_cast<unsigned int>(2), std::min(m_ProcessedExternalCalls >> 2, static_cast<unsigned int>(10))); + // WHen not playing video we allow it to increase to 80ms + unsigned int max_sleep = m_pPlayer->IsPlayingVideo() && !m_pPlayer->IsPausedPlayback() ? 10 : 80; + unsigned int sleepTime = std::max(static_cast<unsigned int>(2), std::min(m_ProcessedExternalCalls >> 2, max_sleep)); Sleep(sleepTime); m_frameMoveGuard.lock(); + m_ProcessedExternalDecay = 5; } - else + if (m_ProcessedExternalDecay && --m_ProcessedExternalDecay == 0) m_ProcessedExternalCalls = 0; } @@ -5085,6 +5088,11 @@ void CApplication::StartMusicScan(const std::string &strDirectory, bool userInit flags |= CMusicInfoScanner::SCAN_ONLINE; if (!userInitiated || m_ServiceManager->GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE)) flags |= CMusicInfoScanner::SCAN_BACKGROUND; + // Ask for full rescan of music files + //! @todo replace with a music library setting in UI + if (g_advancedSettings.m_bMusicLibraryPromptFullTagScan) + if (CGUIDialogYesNo::ShowAndGetInput(CVariant{ 799 }, CVariant{ 38062 })) + flags |= CMusicInfoScanner::SCAN_RESCAN; } if (!(flags & CMusicInfoScanner::SCAN_BACKGROUND)) diff --git a/xbmc/Application.h b/xbmc/Application.h index 59a1ec96b2..93bf3cce99 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -519,6 +519,7 @@ private: CCriticalSection m_frameMoveGuard; /*!< critical section for synchronizing GUI actions from inside and outside (python) */ std::atomic_uint m_WaitingExternalCalls; /*!< counts threads wich are waiting to be processed in FrameMove */ unsigned int m_ProcessedExternalCalls; /*!< counts calls wich are processed during one "door open" cycle in FrameMove */ + unsigned int m_ProcessedExternalDecay = 0; /*!< counts to close door after a few frames of no python activity */ }; XBMC_GLOBAL_REF(CApplication,g_application); diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index b30c26f5b1..94d7bef42a 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -359,7 +359,7 @@ const CFileItem& CFileItem::operator=(const CFileItem& item) return *this; CGUIListItem::operator=(item); - m_bLabelPreformated=item.m_bLabelPreformated; + m_bLabelPreformatted=item.m_bLabelPreformatted; FreeMemory(); m_strPath = item.GetPath(); m_bIsParentFolder = item.m_bIsParentFolder; @@ -454,7 +454,7 @@ void CFileItem::Initialize() m_videoInfoTag = NULL; m_pictureInfoTag = NULL; m_gameInfoTag = NULL; - m_bLabelPreformated = false; + m_bLabelPreformatted = false; m_bIsAlbum = false; m_dwSize = 0; m_bIsParentFolder = false; @@ -517,7 +517,7 @@ void CFileItem::Archive(CArchive& ar) if (ar.IsStoring()) { ar << m_bIsParentFolder; - ar << m_bLabelPreformated; + ar << m_bLabelPreformatted; ar << m_strPath; ar << m_bIsShareOrDrive; ar << m_iDriveType; @@ -579,7 +579,7 @@ void CFileItem::Archive(CArchive& ar) else { ar >> m_bIsParentFolder; - ar >> m_bLabelPreformated; + ar >> m_bLabelPreformatted; ar >> m_strPath; ar >> m_bIsShareOrDrive; ar >> m_iDriveType; @@ -3093,6 +3093,9 @@ std::string CFileItem::GetFolderThumb(const std::string &folderJPG /* = "folder. if (IsMultiPath()) strFolder = CMultiPathDirectory::GetFirstPath(m_strPath); + if (IsPlugin()) + return ""; + return URIUtils::AddFileToFolder(strFolder, folderJPG); } @@ -3197,11 +3200,11 @@ std::string CFileItem::GetLocalFanart() const return ""; CFileItemList items; - CDirectory::GetDirectory(strDir, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO); + CDirectory::GetDirectory(strDir, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO); if (IsOpticalMediaFile()) { // grab from the optical media parent folder as well CFileItemList moreItems; - CDirectory::GetDirectory(GetLocalMetadataPath(), moreItems, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO); + CDirectory::GetDirectory(GetLocalMetadataPath(), moreItems, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO); items.Append(moreItems); } diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 0f4a4a0511..63882509a5 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -243,8 +243,8 @@ public: void SetFileSizeLabel(); virtual void SetLabel(const std::string &strLabel); int GetVideoContentType() const; /* return VIDEODB_CONTENT_TYPE, but don't want to include videodb in this header */ - bool IsLabelPreformatted() const { return m_bLabelPreformated; } - void SetLabelPreformatted(bool bYesNo) { m_bLabelPreformated=bYesNo; } + bool IsLabelPreformatted() const { return m_bLabelPreformatted; } + void SetLabelPreformatted(bool bYesNo) { m_bLabelPreformatted=bYesNo; } bool SortsOnTop() const { return m_specialSort == SortSpecialOnTop; } bool SortsOnBottom() const { return m_specialSort == SortSpecialOnBottom; } void SetSpecialSort(SortSpecial sort) { m_specialSort = sort; } @@ -562,7 +562,7 @@ private: SortSpecial m_specialSort; bool m_bIsParentFolder; bool m_bCanQueue; - bool m_bLabelPreformated; + bool m_bLabelPreformatted; std::string m_mimetype; std::string m_extrainfo; bool m_doContentLookup; diff --git a/xbmc/ServiceBroker.cpp b/xbmc/ServiceBroker.cpp index 762c26dce0..cea7ad9709 100644 --- a/xbmc/ServiceBroker.cpp +++ b/xbmc/ServiceBroker.cpp @@ -73,6 +73,11 @@ CSettings& CServiceBroker::GetSettings() return g_application.m_ServiceManager->GetSettings(); } +GAME::CGameServices& CServiceBroker::GetGameServices() +{ + return g_application.m_ServiceManager->GetGameServices(); +} + bool CServiceBroker::IsBinaryAddonCacheUp() { return g_application.m_ServiceManager->init_level > 1; diff --git a/xbmc/ServiceBroker.h b/xbmc/ServiceBroker.h index d68134d473..53a566e3e4 100644 --- a/xbmc/ServiceBroker.h +++ b/xbmc/ServiceBroker.h @@ -49,6 +49,11 @@ class XBPython; class CDataCacheCore; class CSettings; +namespace GAME +{ + class CGameServices; +} + class CServiceBroker { public: @@ -62,5 +67,6 @@ public: static CDataCacheCore& GetDataCacheCore(); static PLAYLIST::CPlayListPlayer& GetPlaylistPlayer(); static CSettings& GetSettings(); + static GAME::CGameServices& GetGameServices(); static bool IsBinaryAddonCacheUp(); }; diff --git a/xbmc/ServiceManager.cpp b/xbmc/ServiceManager.cpp index f5eaa7c322..091c9a3715 100644 --- a/xbmc/ServiceManager.cpp +++ b/xbmc/ServiceManager.cpp @@ -23,6 +23,7 @@ #include "ContextMenuManager.h" #include "cores/AudioEngine/Engines/ActiveAE/AudioDSPAddons/ActiveAEDSP.h" #include "cores/DataCacheCore.h" +#include "games/GameServices.h" #include "PlayListPlayer.h" #include "utils/log.h" #include "interfaces/AnnouncementManager.h" @@ -31,6 +32,15 @@ #include "pvr/PVRManager.h" #include "settings/Settings.h" +CServiceManager::CServiceManager() : + m_gameServices(new GAME::CGameServices) +{ +} + +CServiceManager::~CServiceManager() +{ +} + bool CServiceManager::Init1() { m_announcementManager.reset(new ANNOUNCEMENT::CAnnouncementManager()); @@ -80,6 +90,7 @@ bool CServiceManager::Init3() m_ADSPManager->Init(); m_PVRManager->Init(); m_contextMenuManager->Init(); + m_gameServices->Init(); init_level = 3; return true; @@ -87,6 +98,7 @@ bool CServiceManager::Init3() void CServiceManager::Deinit() { + m_gameServices->Deinit(); m_contextMenuManager.reset(); m_binaryAddonCache.reset(); if (m_PVRManager) @@ -159,6 +171,11 @@ CSettings& CServiceManager::GetSettings() return *m_settings; } +GAME::CGameServices& CServiceManager::GetGameServices() +{ + return *m_gameServices; +} + // deleters for unique_ptr void CServiceManager::delete_dataCacheCore::operator()(CDataCacheCore *p) const { diff --git a/xbmc/ServiceManager.h b/xbmc/ServiceManager.h index 7fb3ca95db..db7f7b6424 100644 --- a/xbmc/ServiceManager.h +++ b/xbmc/ServiceManager.h @@ -54,9 +54,17 @@ class XBPython; class CDataCacheCore; class CSettings; +namespace GAME +{ + class CGameServices; +} + class CServiceManager { public: + CServiceManager(); + ~CServiceManager(); + bool Init1(); bool Init2(); bool Init3(); @@ -74,6 +82,7 @@ public: /**\brief Get the platform object. This is save to be called after Init1() was called */ CPlatform& GetPlatform(); + GAME::CGameServices& GetGameServices(); PLAYLIST::CPlayListPlayer& GetPlaylistPlayer(); int init_level = 0; @@ -104,4 +113,5 @@ protected: std::unique_ptr<CPlatform> m_Platform; std::unique_ptr<PLAYLIST::CPlayListPlayer> m_playlistPlayer; std::unique_ptr<CSettings> m_settings; + std::unique_ptr<GAME::CGameServices> m_gameServices; }; diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp index fee73f5737..00ddb66346 100644 --- a/xbmc/URL.cpp +++ b/xbmc/URL.cpp @@ -705,7 +705,7 @@ std::string CURL::Encode(const std::string& strURLData) if (StringUtils::isasciialphanum(kar) || kar == '-' || kar == '.' || kar == '_' || kar == '!' || kar == '(' || kar == ')') strResult.push_back(kar); else - strResult += StringUtils::Format("%%%2.2X", (unsigned int)((unsigned char)kar)); + strResult += StringUtils::Format("%%%2.2x", (unsigned int)((unsigned char)kar)); } return strResult; diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index f2d69da28c..b705562c19 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -543,7 +543,7 @@ bool CUtil::IsTVRecording(const std::string& strFile) bool CUtil::IsPicture(const std::string& strFile) { return URIUtils::HasExtension(strFile, - g_advancedSettings.m_pictureExtensions + "|.tbn|.dds"); + g_advancedSettings.GetPictureExtensions()+ "|.tbn|.dds"); } bool CUtil::ExcludeFileOrFolder(const std::string& strFileOrFolder, const std::vector<std::string>& regexps) diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp index 3b94e5aa49..2a96ae09c1 100644 --- a/xbmc/addons/Addon.cpp +++ b/xbmc/addons/Addon.cpp @@ -110,6 +110,7 @@ static const TypeMapping types[] = {"kodi.adsp", ADDON_ADSPDLL, 24135, "DefaultAddonAudioDSP.png" }, {"kodi.inputstream", ADDON_INPUTSTREAM, 24048, "DefaultAddonInputstream.png" }, {"kodi.vfs", ADDON_VFS, 39013, "DefaultAddonVfs.png" }, + {"kodi.imagedecoder", ADDON_IMAGEDECODER, 39015, "DefaultAddonImageDecoder.png" }, }; std::string TranslateType(ADDON::TYPE type, bool pretty/*=false*/) @@ -349,8 +350,7 @@ void OnEnabled(const std::string& id) // If the addon is a special, call enabled handler AddonPtr addon; if (CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_PVRDLL) || - CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_ADSPDLL) || - CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_PERIPHERALDLL)) + CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_ADSPDLL)) return addon->OnEnabled(); if (CAddonMgr::GetInstance().ServicesHasStarted()) @@ -368,8 +368,7 @@ void OnDisabled(const std::string& id) AddonPtr addon; if (CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_PVRDLL, false) || - CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_ADSPDLL, false) || - CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_PERIPHERALDLL, false)) + CAddonMgr::GetInstance().GetAddon(id, addon, ADDON_ADSPDLL, false)) return addon->OnDisabled(); if (CAddonMgr::GetInstance().ServicesHasStarted()) diff --git a/xbmc/addons/AddonBuilder.cpp b/xbmc/addons/AddonBuilder.cpp index 2df8abcd3f..d47c5aa198 100644 --- a/xbmc/addons/AddonBuilder.cpp +++ b/xbmc/addons/AddonBuilder.cpp @@ -23,6 +23,7 @@ #include "addons/AudioEncoder.h" #include "addons/ContextMenuAddon.h" #include "addons/GameResource.h" +#include "addons/ImageDecoder.h" #include "addons/ImageResource.h" #include "addons/InputStream.h" #include "addons/LanguageResource.h" @@ -91,6 +92,7 @@ std::shared_ptr<IAddon> CAddonBuilder::Build() type == ADDON_AUDIOENCODER || type == ADDON_AUDIODECODER || type == ADDON_VFS || + type == ADDON_IMAGEDECODER || type == ADDON_INPUTSTREAM || type == ADDON_PERIPHERALDLL || type == ADDON_GAMEDLL) @@ -138,6 +140,8 @@ std::shared_ptr<IAddon> CAddonBuilder::Build() return CAudioEncoder::FromExtension(std::move(m_props), m_extPoint); case ADDON_AUDIODECODER: return CAudioDecoder::FromExtension(std::move(m_props), m_extPoint); + case ADDON_IMAGEDECODER: + return CImageDecoder::FromExtension(std::move(m_props), m_extPoint); case ADDON_INPUTSTREAM: return CInputStream::FromExtension(std::move(m_props), m_extPoint); case ADDON_PERIPHERALDLL: diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp index 67ad41d247..ad655d6ae8 100644 --- a/xbmc/addons/AddonDatabase.cpp +++ b/xbmc/addons/AddonDatabase.cpp @@ -539,7 +539,6 @@ bool CAddonDatabase::GetAvailableVersions(const std::string& addonId, "WHERE " "repo.checksum IS NOT NULL AND repo.checksum != '' " "AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repoID AND installed.enabled=1) " - "AND NOT EXISTS (SELECT * FROM broken WHERE broken.addonID=addons.addonID) " "AND addons.addonID='%s'", addonId.c_str()); m_pDS->query(sql.c_str()); diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp index 9f2480ce88..55d300904d 100644 --- a/xbmc/addons/AddonInstaller.cpp +++ b/xbmc/addons/AddonInstaller.cpp @@ -228,14 +228,15 @@ void CAddonInstaller::Install(const std::string& addonId, const AddonVersion& ve } bool CAddonInstaller::DoInstall(const AddonPtr &addon, const RepositoryPtr& repo, - const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */) + const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */, + bool autoUpdate /* = false*/) { // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) return false; - CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash); + CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash, autoUpdate); if (background) { // Workaround: because CAddonInstallJob is blocking waiting for other jobs, it needs to be run @@ -431,9 +432,18 @@ void CAddonInstaller::InstallUpdates() for (const auto& addon : updates) { if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID())) - CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID()); + { + AddonPtr toInstall; + RepositoryPtr repo; + std::string hash; + if (CAddonInstallJob::GetAddonWithHash(addon->ID(), repo, toInstall, hash)) + DoInstall(toInstall, repo, hash, true, false, true); + } } +} +void CAddonInstaller::InstallUpdatesAndWait() +{ CSingleLock lock(m_critSection); if (!m_downloadJobs.empty()) { @@ -464,13 +474,15 @@ int64_t CAddonInstaller::EnumeratePackageFolder(std::map<std::string,CFileItemLi return size; } -CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo, const std::string &hash /* = "" */) +CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo, + const std::string &hash, bool isAutoUpdate) : m_addon(addon), m_repo(repo), - m_hash(hash) + m_hash(hash), + m_isAutoUpdate(isAutoUpdate) { AddonPtr dummy; - m_update = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false); + m_isUpdate = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false); } bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, RepositoryPtr& repo, @@ -605,20 +617,30 @@ bool CAddonInstallJob::DoWork() g_localizeStrings.LoadAddonStrings(URIUtils::AddFileToFolder(m_addon->Path(), "resources/language/"), CServiceBroker::GetSettings().GetString(CSettings::SETTING_LOCALE_LANGUAGE), m_addon->ID()); - ADDON::OnPostInstall(m_addon, m_update, IsModal()); + ADDON::OnPostInstall(m_addon, m_isUpdate, IsModal()); { CAddonDatabase database; database.Open(); database.SetOrigin(m_addon->ID(), m_repo ? m_repo->ID() : ""); - if (m_update) + if (m_isUpdate) database.SetLastUpdated(m_addon->ID(), CDateTime::GetCurrentDateTime()); } CEventLog::GetInstance().Add( - EventPtr(new CAddonManagementEvent(m_addon, m_update ? 24065 : 24064)), + EventPtr(new CAddonManagementEvent(m_addon, m_isUpdate ? 24065 : 24064)), !IsModal() && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_ADDONS_NOTIFICATIONS), false); + if (m_isAutoUpdate && !m_addon->Broken().empty()) + { + CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: auto-disabling due to being marked as broken", m_addon->ID().c_str()); + CAddonMgr::GetInstance().DisableAddon(m_addon->ID()); + CEventLog::GetInstance().Add( + EventPtr(new CAddonManagementEvent(m_addon, 24094)), + CServiceBroker::GetSettings().GetBool(CSettings::SETTING_ADDONS_NOTIFICATIONS), + false); + } + // and we're done! MarkFinished(); return true; @@ -725,7 +747,7 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r return false; } - CAddonInstallJob dependencyJob(addon, repoForDep, hash); + CAddonInstallJob dependencyJob(addon, repoForDep, hash, false); // pass our progress indicators to the temporary job and don't allow it to // show progress or information updates (no progress, title or text changes) diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h index 57a38c9624..d42617adf2 100644 --- a/xbmc/addons/AddonInstaller.h +++ b/xbmc/addons/AddonInstaller.h @@ -95,6 +95,7 @@ public: bool HasJob(const std::string& ID) const; /*! Install update and block until all updates have installed. */ + void InstallUpdatesAndWait(); void InstallUpdates(); void OnJobComplete(unsigned int jobID, bool success, CJob* job); @@ -129,7 +130,7 @@ private: \return true on successful install, false on failure. */ bool DoInstall(const ADDON::AddonPtr &addon, const ADDON::RepositoryPtr &repo, - const std::string &hash = "", bool background = true, bool modal = false); + const std::string &hash = "", bool background = true, bool modal = false, bool autoUpdate = false); /*! \brief Check whether dependencies of an addon exist or are installable. Iterates through the addon's dependencies, checking they're installed or installable. @@ -153,7 +154,8 @@ private: class CAddonInstallJob : public CFileOperationJob { public: - CAddonInstallJob(const ADDON::AddonPtr &addon, const ADDON::AddonPtr &repo, const std::string &hash = ""); + CAddonInstallJob(const ADDON::AddonPtr& addon, const ADDON::AddonPtr& repo, + const std::string& hash, bool isAutoUpdate); virtual bool DoWork(); @@ -185,7 +187,8 @@ private: ADDON::AddonPtr m_addon; ADDON::AddonPtr m_repo; std::string m_hash; - bool m_update; + bool m_isUpdate; + bool m_isAutoUpdate; }; class CAddonUnInstallJob : public CFileOperationJob diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp index 4c7c1cd5a3..8dd7395c35 100644 --- a/xbmc/addons/AddonManager.cpp +++ b/xbmc/addons/AddonManager.cpp @@ -848,19 +848,7 @@ bool CAddonMgr::IsAddonInstalled(const std::string& ID) bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon) { - if (addon == NULL) - return false; - - CSingleLock lock(m_critSection); - // can't install already installed addon - if (IsAddonInstalled(addon->ID())) - return false; - - // can't install broken addons - if (!addon->Broken().empty()) - return false; - - return true; + return addon != nullptr &&!IsAddonInstalled(addon->ID()); } bool CAddonMgr::CanUninstall(const AddonPtr& addon) diff --git a/xbmc/addons/AddonSystemSettings.cpp b/xbmc/addons/AddonSystemSettings.cpp index 6f245936d5..f0f3dad990 100644 --- a/xbmc/addons/AddonSystemSettings.cpp +++ b/xbmc/addons/AddonSystemSettings.cpp @@ -148,7 +148,7 @@ std::vector<std::string> CAddonSystemSettings::MigrateAddons(std::function<void( CRepositoryUpdater::GetInstance().Await(); CLog::Log(LOGINFO, "ADDON: waiting for add-ons to update..."); - CAddonInstaller::GetInstance().InstallUpdates(); + CAddonInstaller::GetInstance().InstallUpdatesAndWait(); } auto incompatible = getIncompatible(); diff --git a/xbmc/addons/BinaryAddonCache.cpp b/xbmc/addons/BinaryAddonCache.cpp index 41f08ff6a5..c926c9eff3 100644 --- a/xbmc/addons/BinaryAddonCache.cpp +++ b/xbmc/addons/BinaryAddonCache.cpp @@ -34,6 +34,7 @@ void CBinaryAddonCache::Init() { m_addonsToCache = { ADDON_AUDIODECODER, + ADDON_IMAGEDECODER, ADDON_INPUTSTREAM, ADDON_PVRDLL, ADDON_GAMEDLL, diff --git a/xbmc/addons/CMakeLists.txt b/xbmc/addons/CMakeLists.txt index b6d26bcb5a..a2188c6739 100644 --- a/xbmc/addons/CMakeLists.txt +++ b/xbmc/addons/CMakeLists.txt @@ -18,6 +18,7 @@ set(SOURCES Addon.cpp GUIDialogAddonSettings.cpp GUIViewStateAddonBrowser.cpp GUIWindowAddonBrowser.cpp + ImageDecoder.cpp ImageResource.cpp InputStream.cpp LanguageResource.cpp @@ -58,6 +59,7 @@ set(HEADERS Addon.h GUIViewStateAddonBrowser.h GUIWindowAddonBrowser.h IAddon.h + ImageDecoder.h ImageResource.h InputStream.h LanguageResource.h diff --git a/xbmc/addons/GUIDialogAddonSettings.cpp b/xbmc/addons/GUIDialogAddonSettings.cpp index 274d30361b..7dc73d53f0 100644 --- a/xbmc/addons/GUIDialogAddonSettings.cpp +++ b/xbmc/addons/GUIDialogAddonSettings.cpp @@ -400,7 +400,7 @@ bool CGUIDialogAddonSettings::ShowVirtualKeyboard(int iControl) // convert mask qualifiers StringUtils::Replace(strMask, "$AUDIO", g_advancedSettings.GetMusicExtensions()); StringUtils::Replace(strMask, "$VIDEO", g_advancedSettings.m_videoExtensions); - StringUtils::Replace(strMask, "$IMAGE", g_advancedSettings.m_pictureExtensions); + StringUtils::Replace(strMask, "$IMAGE", g_advancedSettings.GetPictureExtensions()); #if defined(_WIN32_WINNT) StringUtils::Replace(strMask, "$EXECUTABLE", ".exe|.bat|.cmd|.py"); #else @@ -1039,6 +1039,12 @@ bool CGUIDialogAddonSettings::GetCondition(const std::string &condition, const i else value = StringUtils::Format("%i", ((CGUISpinControlEx*) control2)->GetValue()); break; + case CGUIControl::GUICONTROL_SETTINGS_SLIDER: + if (((CGUISettingsSliderControl *)control2)->GetType() == SLIDER_CONTROL_TYPE_INT) + value = StringUtils::Format("%i", ((CGUISettingsSliderControl *)control2)->GetIntValue()); + else + value = StringUtils::Format("%f", ((CGUISettingsSliderControl *)control2)->GetFloatValue()); + break; default: break; } diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h index b58e19e752..f7b3a279ed 100644 --- a/xbmc/addons/IAddon.h +++ b/xbmc/addons/IAddon.h @@ -65,6 +65,7 @@ namespace ADDON ADDON_RESOURCE_UISOUNDS, ADDON_RESOURCE_GAMES, ADDON_VFS, + ADDON_IMAGEDECODER, ADDON_VIDEO, // virtual addon types ADDON_AUDIO, ADDON_IMAGE, diff --git a/xbmc/addons/ImageDecoder.cpp b/xbmc/addons/ImageDecoder.cpp new file mode 100644 index 0000000000..c22eaf142e --- /dev/null +++ b/xbmc/addons/ImageDecoder.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 Arne Morten Kvarving + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#include "ImageDecoder.h" +#include "kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h" +#include "guilib/TextureFormats.h" + +static const std::map<int,int> KodiToAddonFormat = {{XB_FMT_A8R8G8B8, ADDON_IMG_FMT_A8R8G8B8}, + {XB_FMT_A8, ADDON_IMG_FMT_A8}, + {XB_FMT_RGBA8, ADDON_IMG_FMT_RGBA8}, + {XB_FMT_RGB8, ADDON_IMG_FMT_RGB8}}; + +namespace ADDON +{ + +std::unique_ptr<CImageDecoder> +CImageDecoder::FromExtension(AddonProps&& props, const cp_extension_t* ext) +{ + std::string mime = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@mimetype"); + std::string extension = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@extension"); + return std::unique_ptr<CImageDecoder>(new CImageDecoder(std::move(props), + std::move(mime), + std::move(extension))); +} + +CImageDecoder::CImageDecoder(AddonProps&& props, std::string mime, std::string extension) : + CAddonDll(std::move(props)), + m_mimetype(std::move(mime)), + m_extension(std::move(extension)) +{ +} + +CImageDecoder::~CImageDecoder() +{ + if (m_image && Initialized()) + m_struct.Close(m_image); +} + +bool CImageDecoder::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, + unsigned int width, unsigned int height) +{ + if (!Initialized()) + return false; + + m_width = width; + m_height = height; + m_image = m_struct.LoadImage(buffer, bufSize, &m_width, &m_height); + + return m_image != nullptr; +} + +bool CImageDecoder::Decode(unsigned char* const pixels, unsigned int width, + unsigned int height, unsigned int pitch, + unsigned int format) +{ + if (!Initialized()) + return false; + + auto it = KodiToAddonFormat.find(format & XB_FMT_MASK); + if (it == KodiToAddonFormat.end()) + return false; + + bool result = m_struct.Decode(m_image, pixels, width, height, pitch, it->second); + m_width = width; + m_height = height; + + return result; +} + +bool CImageDecoder::Create(const std::string& mimetype) +{ + m_info.mimetype = mimetype.c_str(); + + return CAddonDll::Create(&m_struct, &m_info) == ADDON_STATUS_OK; +} + +} /*namespace ADDON*/ diff --git a/xbmc/addons/ImageDecoder.h b/xbmc/addons/ImageDecoder.h new file mode 100644 index 0000000000..4743281e11 --- /dev/null +++ b/xbmc/addons/ImageDecoder.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013 Arne Morten Kvarving + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "AddonDll.h" +#include "addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h" +#include "guilib/iimage.h" + +namespace ADDON +{ + class CImageDecoder : public CAddonDll, + public IImage + { + public: + static std::unique_ptr<CImageDecoder> FromExtension(AddonProps&&, + const cp_extension_t* ext); + explicit CImageDecoder(AddonProps props) : + CAddonDll(std::move(props)) + {} + + CImageDecoder(AddonProps&& props, std::string mimetypes, std::string extensions); + virtual ~CImageDecoder(); + + bool Create(const std::string& mimetype); + + bool CreateThumbnailFromSurface(unsigned char*, unsigned int, unsigned int, + unsigned int, unsigned int, const std::string&, + unsigned char*&, unsigned int&) { return false; } + + bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, + unsigned int width, unsigned int height); + bool Decode(unsigned char* const pixels, unsigned int width, + unsigned int height, unsigned int pitch, + unsigned int format); + + const std::string& GetMimetypes() const { return m_mimetype; } + const std::string& GetExtensions() const { return m_extension; } + protected: + void* m_image = nullptr; + std::string m_mimetype; + std::string m_extension; + IMAGEDEC_PROPS m_info; + KodiToAddonFuncTable_ImageDecoder m_struct = {}; + }; + +} /*namespace ADDON*/ diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp index e64a3665c1..ce1e8ab7ed 100644 --- a/xbmc/addons/Repository.cpp +++ b/xbmc/addons/Repository.cpp @@ -257,48 +257,5 @@ bool CRepositoryUpdateJob::DoWork() } database.UpdateRepositoryContent(m_repo->ID(), m_repo->Version(), newChecksum, addons); - - //Notify about broken status changes - for (const auto& addon : addons) - { - AddonPtr localAddon; - if (!CAddonMgr::GetInstance().GetAddon(addon->ID(), localAddon)) - continue; - - if (localAddon && localAddon->Version() > addon->Version()) - //We have a newer version locally - continue; - - AddonPtr oldAddon; - database.GetAddon(addon->ID(), oldAddon); - - if (database.GetAddonVersion(addon->ID()).first > addon->Version()) - //Newer version in db (ie. in a different repo) - continue; - - std::string broken = addon->Broken(); - bool isBroken = !addon->Broken().empty(); - bool isBrokenInDb = oldAddon && !oldAddon->Broken().empty(); - if (isBroken && !isBrokenInDb) - { - //newly broken - if (HELPERS::ShowYesNoDialogLines(CVariant{addon->Name()}, CVariant{24096}, CVariant{24097}, CVariant{""}) - == DialogResponse::YES) - { - CAddonMgr::GetInstance().DisableAddon(addon->ID()); - } - - CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' marked broken. reason: \"%s\"", - m_repo->ID().c_str(), addon->ID().c_str(), broken.c_str()); - - CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24096))); - } - else if (!isBroken && isBrokenInDb) - { - //Unbroken - CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' unbroken", - m_repo->ID().c_str(), addon->ID().c_str()); - } - } return true; } diff --git a/xbmc/addons/RepositoryUpdater.cpp b/xbmc/addons/RepositoryUpdater.cpp index ca008ce8a5..659c39012d 100644 --- a/xbmc/addons/RepositoryUpdater.cpp +++ b/xbmc/addons/RepositoryUpdater.cpp @@ -87,11 +87,7 @@ void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* j if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON) { - for (const auto& addon : updates) - { - if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID())) - CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID()); - } + CAddonInstaller::GetInstance().InstallUpdates(); } ScheduleUpdate(); diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp index e47fd35836..bfa272ac57 100644 --- a/xbmc/addons/Scraper.cpp +++ b/xbmc/addons/Scraper.cpp @@ -496,6 +496,20 @@ CScraperUrl CScraper::ResolveIDToUrl(const std::string& externalID) { CScraperUrl scurlRet; + if (m_isPython) + { + std::stringstream str; + str << "plugin://" << ID() + << "?action=resolveid&key=" << CURL::Encode(externalID); + + CFileItem item("resolve me", false); + + if (XFILE::CPluginDirectory::GetPluginResult(str.str(), item)) + scurlRet.ParseString(item.GetPath()); + + return scurlRet; + } + // scraper function takes an external ID, returns XML (see below) std::vector<std::string> vcsIn; vcsIn.push_back(externalID); @@ -672,11 +686,7 @@ static void ParseThumbs(CScraperUrl& scurl, const CFileItem& item, prefix << tag << i+1; std::string url = FromString(item, prefix.str()+".url"); std::string aspect = FromString(item, prefix.str()+".aspect"); - TiXmlElement thumb("thumb"); - thumb.SetAttribute("aspect", aspect); - TiXmlText text(url); - thumb.InsertEndChild(text); - scurl.ParseElement(&thumb); + scurl.AddElement(url, aspect); } } @@ -691,9 +701,7 @@ static std::string ParseFanart(const CFileItem& item, prefix << tag << i+1; std::string url = FromString(item, prefix.str()+".url"); std::string preview = FromString(item, prefix.str()+".preview"); - std::string res = FromString(item, prefix.str()+".dim"); TiXmlElement thumb("thumb"); - thumb.SetAttribute("dim", res); thumb.SetAttribute("preview", preview); TiXmlText text(url); thumb.InsertEndChild(text); diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk index 6bbfe69dbe..aa2525b9b0 100644 --- a/xbmc/addons/addon-bindings.mk +++ b/xbmc/addons/addon-bindings.mk @@ -15,6 +15,8 @@ BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_codec_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h +BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h +BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_dll.h diff --git a/xbmc/addons/interfaces/Peripheral/AddonCallbacksPeripheral.cpp b/xbmc/addons/interfaces/Peripheral/AddonCallbacksPeripheral.cpp index 57a64c60e4..64130d48a0 100644 --- a/xbmc/addons/interfaces/Peripheral/AddonCallbacksPeripheral.cpp +++ b/xbmc/addons/interfaces/Peripheral/AddonCallbacksPeripheral.cpp @@ -21,10 +21,12 @@ #include "AddonCallbacksPeripheral.h" #include "games/controllers/Controller.h" #include "games/controllers/ControllerLayout.h" +#include "games/GameServices.h" #include "peripherals/Peripherals.h" #include "peripherals/addons/PeripheralAddon.h" #include "peripherals/addons/PeripheralAddonTranslator.h" #include "utils/log.h" +#include "ServiceBroker.h" using namespace ADDON; using namespace PERIPHERALS; @@ -78,18 +80,14 @@ void CAddonCallbacksPeripheral::RefreshButtonMaps(void* addonData, const char* d unsigned int CAddonCallbacksPeripheral::FeatureCount(void* addonData, const char* controllerId, JOYSTICK_FEATURE_TYPE type) { - using namespace ADDON; using namespace GAME; unsigned int count = 0; - AddonPtr addon; - if (CAddonMgr::GetInstance().GetAddon(controllerId, addon, ADDON_GAME_CONTROLLER)) - { - ControllerPtr controller = std::static_pointer_cast<CController>(addon); - if (controller->LoadLayout()) - count = controller->Layout().FeatureCount(CPeripheralAddonTranslator::TranslateFeatureType(type)); - } + CGameServices& gameServices = CServiceBroker::GetGameServices(); + ControllerPtr controller = gameServices.GetController(controllerId); + if (controller) + count = controller->Layout().FeatureCount(CPeripheralAddonTranslator::TranslateFeatureType(type)); return count; } diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h index c09879dcd8..5d233a9f6b 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h @@ -233,7 +233,7 @@ GAME_ERROR CheatReset(void); * * \return the error, or GAME_ERROR_NO_ERROR if data was set to a valid buffer */ -GAME_ERROR GetMemory(GAME_MEMORY type, const uint8_t** data, size_t* size); +GAME_ERROR GetMemory(GAME_MEMORY type, uint8_t** data, size_t* size); /*! * \brief Set a cheat code diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h index 462dfb9403..02a522a3fc 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h @@ -21,10 +21,10 @@ #define KODI_GAME_TYPES_H_ /* current game API version */ -#define GAME_API_VERSION "1.0.28" +#define GAME_API_VERSION "1.0.29" /* min. game API version */ -#define GAME_MIN_API_VERSION "1.0.28" +#define GAME_MIN_API_VERSION "1.0.29" #include <stddef.h> #include <stdint.h> @@ -476,7 +476,7 @@ typedef struct KodiToAddonFuncTable_Game GAME_ERROR (__cdecl* Serialize)(uint8_t*, size_t); GAME_ERROR (__cdecl* Deserialize)(const uint8_t*, size_t); GAME_ERROR (__cdecl* CheatReset)(void); - GAME_ERROR (__cdecl* GetMemory)(GAME_MEMORY, const uint8_t**, size_t*); + GAME_ERROR (__cdecl* GetMemory)(GAME_MEMORY, uint8_t**, size_t*); GAME_ERROR (__cdecl* SetCheat)(unsigned int, bool, const char*); } KodiToAddonFuncTable_Game; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h new file mode 100644 index 0000000000..9438f242b9 --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <stdint.h> +#include "xbmc_addon_dll.h" +#include "kodi_imagedec_types.h" + +extern "C" +{ + void* LoadImage(unsigned char* buffer, unsigned int bufSize, + unsigned int* width, unsigned int* height); + + bool Decode(void* image, unsigned char* pixels, + unsigned int width, unsigned int height, + unsigned int pitch, unsigned int format); + + void Close(void* image); + + // function to export the above structure to Kodi + void __declspec(dllexport) get_addon(void* ptr) + { + KodiToAddonFuncTable_ImageDecoder* img = + static_cast<KodiToAddonFuncTable_ImageDecoder*>(ptr); + img->LoadImage = LoadImage; + img->Decode = Decode; + img->Close = Close; + } +}; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h new file mode 100644 index 0000000000..ad8eb54f23 --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <stdint.h> + +#define ADDON_IMG_FMT_A8R8G8B8 1 +#define ADDON_IMG_FMT_A8 2 +#define ADDON_IMG_FMT_RGBA8 3 +#define ADDON_IMG_FMT_RGB8 4 + +extern "C" +{ + struct IMAGEDEC_PROPS + { + const char* mimetype; + }; + + typedef struct KodiToAddonFuncTable_ImageDecoder + { + //! \brief Initialize an encoder + //! \param buffer The data to read from memory + //! \param bufSize The buffer size + //! \param width The optimal width of image on entry, obtained width on return + //! \param height The optimal height of image, actual obtained height on return + //! \return Image or nullptr on error + void* (__cdecl* LoadImage) (unsigned char* buffer, unsigned int bufSize, + unsigned int* width, unsigned int* height); + + //! \brief Decode previously loaded image + //! \param image Image to decode + //! \param pixels Output buffer + //! \param width Width of output image + //! \param height Height of output image + //! \param pitch Pitch of output image + //! \param format Format of output image + bool (__cdecl* Decode) (void* image, unsigned char* pixels, + unsigned int width, unsigned int height, + unsigned int pitch, unsigned int format); + + //! \brief Close an opened image + //! \param image Image to close + //! \return True on success, false on failure + void (__cdecl* Close)(void* image); + } KodiToAddonFuncTable_ImageDecoder; +} diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h index c72097287a..bd23899966 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_types.h @@ -1,4 +1,3 @@ - /* * Copyright (C) 2014-2016 Team Kodi * http://kodi.tv @@ -51,10 +50,10 @@ #endif /* current Peripheral API version */ -#define PERIPHERAL_API_VERSION "1.2.1" +#define PERIPHERAL_API_VERSION "1.3.0" /* min. Peripheral API version */ -#define PERIPHERAL_MIN_API_VERSION "1.2.0" +#define PERIPHERAL_MIN_API_VERSION "1.3.0" /* indicates a joystick has no preference for port number */ #define NO_PORT_REQUESTED (-1) @@ -223,7 +222,9 @@ extern "C" typedef struct JOYSTICK_DRIVER_SEMIAXIS { int index; + int center; JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction; + unsigned int range; } ATTRIBUTE_PACKED JOYSTICK_DRIVER_SEMIAXIS; typedef struct JOYSTICK_DRIVER_MOTOR diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp index f01180b1dc..e3a1b810be 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_peripheral_utils.hpp @@ -362,7 +362,9 @@ namespace ADDON * * Semiaxis: * - driver index + * - center * - semiaxis direction + * - range * * Motor: * - driver index @@ -377,7 +379,9 @@ namespace ADDON m_type(type), m_driverIndex(driverIndex), m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN), - m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN) + m_center(0), + m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN), + m_range(1) { } @@ -389,7 +393,9 @@ namespace ADDON m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN), m_driverIndex(0), m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN), - m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN) + m_center(0), + m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN), + m_range(1) { } @@ -409,7 +415,9 @@ namespace ADDON m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION), m_driverIndex(hatIndex), m_hatDirection(direction), - m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN) + m_center(0), + m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN), + m_range(1) { } @@ -417,11 +425,13 @@ namespace ADDON * \brief Construct a driver primitive representing the positive or negative * half of an axis */ - DriverPrimitive(unsigned int axisIndex, JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction) : + DriverPrimitive(unsigned int axisIndex, int center, JOYSTICK_DRIVER_SEMIAXIS_DIRECTION direction, unsigned int range) : m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS), m_driverIndex(axisIndex), m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN), - m_semiAxisDirection(direction) + m_center(center), + m_semiAxisDirection(direction), + m_range(range) { } @@ -437,7 +447,9 @@ namespace ADDON m_type(primitive.type), m_driverIndex(0), m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN), - m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN) + m_center(0), + m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN), + m_range(1) { switch (m_type) { @@ -455,7 +467,9 @@ namespace ADDON case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS: { m_driverIndex = primitive.semiaxis.index; + m_center = primitive.semiaxis.center; m_semiAxisDirection = primitive.semiaxis.direction; + m_range = primitive.semiaxis.range; break; } case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR: @@ -471,7 +485,9 @@ namespace ADDON JOYSTICK_DRIVER_PRIMITIVE_TYPE Type(void) const { return m_type; } unsigned int DriverIndex(void) const { return m_driverIndex; } JOYSTICK_DRIVER_HAT_DIRECTION HatDirection(void) const { return m_hatDirection; } + int Center(void) const { return m_center; } JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; } + unsigned int Range(void) const { return m_range; } bool operator==(const DriverPrimitive& other) const { @@ -492,7 +508,9 @@ namespace ADDON case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS: { return m_driverIndex == other.m_driverIndex && - m_semiAxisDirection == other.m_semiAxisDirection; + m_center == other.m_center && + m_semiAxisDirection == other.m_semiAxisDirection && + m_range == other.m_range; } default: break; @@ -520,7 +538,9 @@ namespace ADDON case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS: { driver_primitive.semiaxis.index = m_driverIndex; + driver_primitive.semiaxis.center = m_center; driver_primitive.semiaxis.direction = m_semiAxisDirection; + driver_primitive.semiaxis.range = m_range; break; } case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR: @@ -542,7 +562,9 @@ namespace ADDON JOYSTICK_DRIVER_PRIMITIVE_TYPE m_type; unsigned int m_driverIndex; JOYSTICK_DRIVER_HAT_DIRECTION m_hatDirection; + int m_center; JOYSTICK_DRIVER_SEMIAXIS_DIRECTION m_semiAxisDirection; + unsigned int m_range; }; typedef PeripheralVector<DriverPrimitive, JOYSTICK_DRIVER_PRIMITIVE> DriverPrimitives; diff --git a/xbmc/addons/test/TestAddonBuilder.cpp b/xbmc/addons/test/TestAddonBuilder.cpp index 51cd0b2f14..c30800b5f5 100644 --- a/xbmc/addons/test/TestAddonBuilder.cpp +++ b/xbmc/addons/test/TestAddonBuilder.cpp @@ -55,7 +55,7 @@ TEST_F(TestAddonBuilder, ShouldBuildDependencyAddons) EXPECT_EQ(deps, addon->GetDeps()); } -TEST_F(TestAddonBuilder, ShouldReturnDeivedType) +TEST_F(TestAddonBuilder, ShouldReturnDerivedType) { builder.SetType(ADDON_RESOURCE_LANGUAGE); auto addon = std::dynamic_pointer_cast<CLanguageResource>(builder.Build()); diff --git a/xbmc/addons/test/TestAddonFactory.cpp b/xbmc/addons/test/TestAddonFactory.cpp index c58539522c..00f37cd05c 100644 --- a/xbmc/addons/test/TestAddonFactory.cpp +++ b/xbmc/addons/test/TestAddonFactory.cpp @@ -57,7 +57,7 @@ TEST_F(TestAddonFactory, ShouldFailWhenAddonDoesNotHaveRequestedType) EXPECT_EQ(nullptr, addon); } -TEST_F(TestAddonFactory, ShouldPickFirstExtenstionWhenNotRequestingSpecificType) +TEST_F(TestAddonFactory, ShouldPickFirstExtensionWhenNotRequestingSpecificType) { cp_extension_t extensions[2] = { {&plugin, (char*)"xbmc.python.script", nullptr, nullptr, nullptr, nullptr}, @@ -71,7 +71,7 @@ TEST_F(TestAddonFactory, ShouldPickFirstExtenstionWhenNotRequestingSpecificType) EXPECT_EQ(ADDON_SCRIPT, addon->Type()); } -TEST_F(TestAddonFactory, ShouldIgnoreMetadataExtenstion) +TEST_F(TestAddonFactory, ShouldIgnoreMetadataExtension) { cp_extension_t extensions[2] = { {&plugin, (char*)"kodi.addon.metadata", nullptr, nullptr, nullptr, nullptr}, diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 54b0d866a9..61787f99f9 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -559,7 +559,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) m_extDeferData = true; return; case CActiveAEControlProtocol::DISPLAYLOST: - if (m_sink.GetDeviceType(m_mode == MODE_PCM ? m_settings.device : m_settings.passthoughdevice) == AE_DEVTYPE_HDMI) + if (m_sink.GetDeviceType(m_mode == MODE_PCM ? m_settings.device : m_settings.passthroughdevice) == AE_DEVTYPE_HDMI) { UnconfigureSink(); m_stats.SetSuspended(true); @@ -1097,7 +1097,7 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) ApplySettingsToFormat(m_sinkRequestFormat, m_settings, (int*)&m_mode); m_extKeepConfig = 0; - std::string device = (m_sinkRequestFormat.m_dataFormat == AE_FMT_RAW) ? m_settings.passthoughdevice : m_settings.device; + std::string device = (m_sinkRequestFormat.m_dataFormat == AE_FMT_RAW) ? m_settings.passthroughdevice : m_settings.device; std::string driver; CAESinkFactory::ParseDevice(device, driver); if ((!CompareFormat(m_sinkRequestFormat, m_sinkFormat) && !CompareFormat(m_sinkRequestFormat, oldSinkRequestFormat)) || @@ -1708,7 +1708,7 @@ bool CActiveAE::NeedReconfigureSink() AEAudioFormat newFormat = GetInputFormat(); ApplySettingsToFormat(newFormat, m_settings); - std::string device = (newFormat.m_dataFormat == AE_FMT_RAW) ? m_settings.passthoughdevice : m_settings.device; + std::string device = (newFormat.m_dataFormat == AE_FMT_RAW) ? m_settings.passthroughdevice : m_settings.device; std::string driver; CAESinkFactory::ParseDevice(device, driver); @@ -1725,7 +1725,7 @@ bool CActiveAE::InitSink() SinkConfig config; config.format = m_sinkRequestFormat; config.stats = &m_stats; - config.device = (m_sinkRequestFormat.m_dataFormat == AE_FMT_RAW) ? &m_settings.passthoughdevice : + config.device = (m_sinkRequestFormat.m_dataFormat == AE_FMT_RAW) ? &m_settings.passthroughdevice : &m_settings.device; // send message to sink @@ -2544,7 +2544,7 @@ void CActiveAE::Deamplify(CSoundPacket &dstSample) void CActiveAE::LoadSettings() { m_settings.device = CServiceBroker::GetSettings().GetString(CSettings::SETTING_AUDIOOUTPUT_AUDIODEVICE); - m_settings.passthoughdevice = CServiceBroker::GetSettings().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE); + m_settings.passthroughdevice = CServiceBroker::GetSettings().GetString(CSettings::SETTING_AUDIOOUTPUT_PASSTHROUGHDEVICE); m_settings.config = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_AUDIOOUTPUT_CONFIG); m_settings.channels = (m_sink.GetDeviceType(m_settings.device) == AE_DEVTYPE_IEC958) ? AE_CH_LAYOUT_2_0 : CServiceBroker::GetSettings().GetInt(CSettings::SETTING_AUDIOOUTPUT_CHANNELS); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h index e29eb5719a..77fc01a24e 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h @@ -55,7 +55,7 @@ struct AudioSettings { std::string device; std::string driver; - std::string passthoughdevice; + std::string passthroughdevice; int channels; bool ac3passthrough; bool ac3transcode; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index 9f5b8c24fc..bd85d4f771 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -245,7 +245,7 @@ bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device) int stream = CJNIAudioManager::STREAM_MUSIC; m_encoding = CJNIAudioFormat::ENCODING_PCM_16BIT; - uint32_t distance = 192000; // max upper distance + uint32_t distance = UINT32_MAX; // max upper distance, update at least ones to use one of our samplerates for (auto& s : m_sink_sampleRates) { // prefer best match or alternatively something that divides nicely and @@ -825,7 +825,7 @@ void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) else { bool supports_192khz = false; - int test_sample[] = { 32000, 44100, 48000, 96000, 192000 }; + int test_sample[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 }; int test_sample_sz = sizeof(test_sample) / sizeof(int); int encoding = CJNIAudioFormat::ENCODING_PCM_16BIT; if (CJNIAudioManager::GetSDKVersion() >= 21) diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp index 7596537302..ced1200f21 100644 --- a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp +++ b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp @@ -130,7 +130,7 @@ UInt32 CCoreAudioStream::GetDirection() // WARNING - don't rely on this method - the return value of // GetTerminalType is driver specific - the checked return // values are only recommendations from apple -bool CCoreAudioStream::IsDigitalOuptut(AudioStreamID id) +bool CCoreAudioStream::IsDigitalOutput(AudioStreamID id) { UInt32 type = GetTerminalType(id); // yes apple is mixing types here... diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h index 3f01060e85..ba6d883e8f 100644 --- a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h +++ b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h @@ -60,7 +60,7 @@ public: bool GetAvailablePhysicalFormats(StreamFormatList *pList); static bool GetAvailableVirtualFormats(AudioStreamID id, StreamFormatList *pList); static bool GetAvailablePhysicalFormats(AudioStreamID id, StreamFormatList *pList); - static bool IsDigitalOuptut(AudioStreamID id); + static bool IsDigitalOutput(AudioStreamID id); static bool GetStartingChannelInDevice(AudioStreamID id, UInt32 &startingChannel); protected: diff --git a/xbmc/cores/VideoPlayer/DVDAudio.cpp b/xbmc/cores/VideoPlayer/DVDAudio.cpp index 2dd9b3689a..de1ad64523 100644 --- a/xbmc/cores/VideoPlayer/DVDAudio.cpp +++ b/xbmc/cores/VideoPlayer/DVDAudio.cpp @@ -35,7 +35,7 @@ CDVDAudio::CDVDAudio(CDVDClock *clock) : m_pClock(clock) m_pAudioStream = NULL; m_bPassthrough = false; m_iBitsPerSample = 0; - m_sampeRate = 0; + m_sampleRate = 0; m_bPaused = true; m_playingPts = DVD_NOPTS_VALUE; //silence coverity uninitialized warning, is set elsewhere m_timeOfPts = 0.0; //silence coverity uninitialized warning, is set elsewhere @@ -74,7 +74,7 @@ bool CDVDAudio::Create(const DVDAudioFrame &audioframe, AVCodecID codec, bool ne if (!m_pAudioStream) return false; - m_sampeRate = audioframe.format.m_sampleRate; + m_sampleRate = audioframe.format.m_sampleRate; m_iBitsPerSample = audioframe.bits_per_sample; m_bPassthrough = audioframe.passthrough; m_channelLayout = audioframe.format.m_channelLayout; @@ -95,7 +95,7 @@ void CDVDAudio::Destroy() CAEFactory::FreeStream(m_pAudioStream); m_pAudioStream = NULL; - m_sampeRate = 0; + m_sampleRate = 0; m_iBitsPerSample = 0; m_bPassthrough = false; m_bPaused = true; @@ -249,7 +249,7 @@ bool CDVDAudio::IsValidFormat(const DVDAudioFrame &audioframe) if(audioframe.passthrough != m_bPassthrough) return false; - if(m_sampeRate != audioframe.format.m_sampleRate || + if(m_sampleRate != audioframe.format.m_sampleRate || m_iBitsPerSample != audioframe.bits_per_sample || m_channelLayout != audioframe.format.m_channelLayout) return false; diff --git a/xbmc/cores/VideoPlayer/DVDAudio.h b/xbmc/cores/VideoPlayer/DVDAudio.h index 59a828d982..0bbd2968b4 100644 --- a/xbmc/cores/VideoPlayer/DVDAudio.h +++ b/xbmc/cores/VideoPlayer/DVDAudio.h @@ -76,7 +76,7 @@ protected: double m_resampleRatio; CCriticalSection m_critSection; - unsigned int m_sampeRate; + unsigned int m_sampleRate; int m_iBitsPerSample; bool m_bPassthrough; CAEChannelInfo m_channelLayout; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp index 9f2270ef44..c49ec70ef9 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp @@ -26,36 +26,39 @@ #include "cores/VideoPlayer/DVDClock.h" #include "cores/VideoPlayer/VideoRenderers/RenderFlags.h" #include "cores/VideoPlayer/VideoRenderers/RenderManager.h" +#include "settings/AdvancedSettings.h" #include "guilib/GraphicContext.h" #include "settings/DisplaySettings.h" #include "settings/MediaSettings.h" #include "settings/Settings.h" +#include "threads/Atomics.h" #include "utils/AMLUtils.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/SysfsUtils.h" #include "utils/TimeUtils.h" -extern "C" { -#include "libavutil/avutil.h" -} // extern "C" - #include <unistd.h> #include <queue> #include <vector> #include <signal.h> -#include <semaphore.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> +#include <sys/utsname.h> #include <linux/videodev2.h> +#include <sys/poll.h> +#include <chrono> +#include <thread> // amcodec include extern "C" { #include <amcodec/codec.h> } // extern "C" +CEvent g_aml_sync_event; + class PosixFile { public: @@ -128,6 +131,11 @@ public: virtual int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode)=0; virtual int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh)=0; virtual int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh)=0; + + virtual int codec_set_av_threshold(codec_para_t *pcodec, int threshold)=0; + virtual int codec_set_video_delay_limited_ms(codec_para_t *pcodec,int delay_ms)=0; + virtual int codec_get_video_delay_limited_ms(codec_para_t *pcodec,int *delay_ms)=0; + virtual int codec_get_video_cur_delay_ms(codec_para_t *pcodec,int *delay_ms)=0; }; class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface @@ -151,6 +159,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface DEFINE_METHOD2(int, codec_set_cntl_avthresh, (codec_para_t *p1, unsigned int p2)) DEFINE_METHOD2(int, codec_set_cntl_syncthresh,(codec_para_t *p1, unsigned int p2)) + DEFINE_METHOD2(int, codec_set_av_threshold, (codec_para_t *p1, int p2)) + DEFINE_METHOD2(int, codec_set_video_delay_limited_ms, (codec_para_t *p1, int p2)) + DEFINE_METHOD2(int, codec_get_video_delay_limited_ms, (codec_para_t *p1, int *p2)) + DEFINE_METHOD2(int, codec_get_video_cur_delay_ms, (codec_para_t *p1, int *p2)) + BEGIN_METHOD_RESOLVE() RESOLVE_METHOD(codec_init) RESOLVE_METHOD(codec_close) @@ -167,6 +180,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface RESOLVE_METHOD(codec_set_cntl_mode) RESOLVE_METHOD(codec_set_cntl_avthresh) RESOLVE_METHOD(codec_set_cntl_syncthresh) + + RESOLVE_METHOD(codec_set_av_threshold) + RESOLVE_METHOD(codec_set_video_delay_limited_ms) + RESOLVE_METHOD(codec_get_video_delay_limited_ms) + RESOLVE_METHOD(codec_get_video_cur_delay_ms) END_METHOD_RESOLVE() public: @@ -218,14 +236,17 @@ public: #define TRICKMODE_I 0x01 #define TRICKMODE_FFFB 0x02 -// same as AV_NOPTS_VALUE -#define INT64_0 INT64_C(0x8000000000000000) +static const int64_t INT64_0 = 0x8000000000000000ULL; #define EXTERNAL_PTS (1) #define SYNC_OUTSIDE (2) +#define KEYFRAME_PTS_ONLY 0x100 // missing tags +#ifndef CODEC_TAG_VC_1 #define CODEC_TAG_VC_1 (0x312D4356) +#endif + #define CODEC_TAG_RV30 (0x30335652) #define CODEC_TAG_RV40 (0x30345652) #define CODEC_TAG_MJPEG (0x47504a4d) @@ -310,6 +331,19 @@ typedef struct am_private_t bool dumpdemux; } am_private_t; +typedef struct vframe_states +{ + int vf_pool_size; + int buf_free_num; + int buf_recycle_num; + int buf_avail_num; +} vframe_states_t; + +#ifndef AMSTREAM_IOC_VF_STATUS +#define AMSTREAM_IOC_MAGIC 'S' +#define AMSTREAM_IOC_VF_STATUS _IOR(AMSTREAM_IOC_MAGIC, 0x60, unsigned long) +#endif + /*************************************************************************/ /*************************************************************************/ void dumpfile_open(am_private_t *para) @@ -518,7 +552,7 @@ static void am_packet_init(am_packet_t *pkt) pkt->avduration = 0; pkt->isvalid = 0; pkt->newflag = 0; - pkt->lastpts = 0; + pkt->lastpts = INT64_0; pkt->data = NULL; pkt->buf = NULL; pkt->data_size = 0; @@ -543,46 +577,14 @@ void am_packet_release(am_packet_t *pkt) int check_in_pts(am_private_t *para, am_packet_t *pkt) { - int last_duration = 0; - static int last_v_duration = 0; - int64_t pts = 0; - - last_duration = last_v_duration; - - if (para->stream_type == AM_STREAM_ES) { - if ((int64_t)INT64_0 != pkt->avpts) { - pts = pkt->avpts; - - if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) { - CLog::Log(LOGDEBUG, "ERROR check in pts error!"); - return PLAYER_PTS_ERROR; - } - - } else if ((int64_t)INT64_0 != pkt->avdts) { - pts = pkt->avdts * last_duration; - - if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) { - CLog::Log(LOGDEBUG, "ERROR check in dts error!"); - return PLAYER_PTS_ERROR; - } - - last_v_duration = pkt->avduration ? pkt->avduration : 1; - } else { - if (!para->check_first_pts) { - if (para->m_dll->codec_checkin_pts(pkt->codec, 0) != 0) { - CLog::Log(LOGDEBUG, "ERROR check in 0 to video pts error!"); - return PLAYER_PTS_ERROR; - } - } - } - if (!para->check_first_pts) { - para->check_first_pts = 1; - } - } - if (pts > 0) - pkt->lastpts = pts; - - return PLAYER_SUCCESS; + if (para->stream_type == AM_STREAM_ES + && INT64_0 != pkt->avpts + && para->m_dll->codec_checkin_pts(pkt->codec, pkt->avpts) != 0) + { + CLog::Log(LOGDEBUG, "ERROR check in pts error!"); + return PLAYER_PTS_ERROR; + } + return PLAYER_SUCCESS; } static int write_header(am_private_t *para, am_packet_t *pkt) @@ -652,7 +654,7 @@ int write_av_packet(am_private_t *para, am_packet_t *pkt) } pkt->newflag = 0; } - + buf = pkt->data; size = pkt->data_size ; if (size == 0 && pkt->isvalid) { @@ -1319,9 +1321,14 @@ int set_header_info(am_private_t *para) /*************************************************************************/ CAMLCodec::CAMLCodec() - : CThread("CAMLCodec") + : m_opened(false) + , m_ptsIs64us(false) + , m_cur_pts(INT64_0) + , m_last_pts(0) + , m_bufferIndex(-1) + , m_state(0) + , m_frameSizeSum(0) { - m_opened = false; am_private = new am_private_t; memset(am_private, 0, sizeof(am_private_t)); m_dll = new DllLibAmCodec; @@ -1337,25 +1344,39 @@ CAMLCodec::CAMLCodec() CAMLCodec::~CAMLCodec() { - StopThread(); delete am_private; am_private = NULL; delete m_dll, m_dll = NULL; } +float CAMLCodec::OMXPtsToSeconds(int omxpts) +{ + return static_cast<float>(omxpts) / PTS_FREQ; +} + +int CAMLCodec::OMXDurationToNs(int duration) +{ + return static_cast<int>(static_cast<float>(duration) / PTS_FREQ * 1000000 ); +} + +int CAMLCodec::GetAmlDuration() const +{ + return am_private ? (am_private->video_rate * PTS_FREQ) / UNIT_FREQ : 0; +}; + bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) { m_speed = DVD_PLAYSPEED_NORMAL; - m_1st_pts = 0; - m_cur_pts = 0; + m_cur_pts = INT64_0; m_dst_rect.SetRect(0, 0, 0, 0); m_zoom = -1; m_contrast = -1; m_brightness = -1; - m_vbufsize = 500000 * 2; - m_start_dts = 0; - m_start_pts = 0; + m_start_adj = 0; m_hints = hints; + m_state = 0; + m_frameSizes.clear(); + m_frameSizeSum = 0; if (!OpenAmlVideo(hints)) { @@ -1480,6 +1501,8 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) break; case VFORMAT_MPEG4: am_private->gcodec.param = (void*)EXTERNAL_PTS; + if (m_hints.ptsinvalid) + am_private->gcodec.param = (void*)(EXTERNAL_PTS | KEYFRAME_PTS_ONLY); break; case VFORMAT_H264: case VFORMAT_H264MVC: @@ -1522,7 +1545,7 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) case VFORMAT_VC1: // vc1 in an avi file if (m_hints.ptsinvalid) - am_private->gcodec.param = (void*)EXTERNAL_PTS; + am_private->gcodec.param = (void*)KEYFRAME_PTS_ONLY; break; case VFORMAT_HEVC: am_private->gcodec.format = VIDEO_DEC_FORMAT_HEVC; @@ -1546,9 +1569,10 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) am_private->dumpdemux = false; dumpfile_open(am_private); - //! @bug make sure we are not stuck in pause (amcodec bug) - m_dll->codec_resume(&am_private->vcodec); + m_dll->codec_pause(&am_private->vcodec); + m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE); + m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000); m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH); m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0); @@ -1558,8 +1582,6 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) am_private->am_pkt.codec = &am_private->vcodec; pre_header_feeding(am_private, &am_private->am_pkt); - Create(); - m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iHeight); std::string strScaler; @@ -1567,21 +1589,25 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints) if (strScaler.find("enabled") == std::string::npos) // Scaler not enabled, use screen size m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenHeight); -/* - // if display is set to 1080xxx, then disable deinterlacer for HD content - // else bandwidth usage is too heavy and it will slow down video decoder. - char display_mode[256] = {0}; - SysfsUtils::GetString("/sys/class/display/mode", display_mode, 255); - if (strstr(display_mode,"1080")) - SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 1); - else - SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 0); -*/ + SysfsUtils::SetInt("/sys/class/video/freerun_mode", 1); + + + struct utsname un; + if (uname(&un) == 0) + { + int linuxversion[2]; + sscanf(un.release,"%d.%d", &linuxversion[0], &linuxversion[1]); + if (linuxversion[0] > 3 || (linuxversion[0] == 3 && linuxversion[1] >= 14)) + m_ptsIs64us = true; + } + + CLog::Log(LOGNOTICE, "CAMLCodec::OpenDecoder - using V4L2 pts format: %s", m_ptsIs64us ? "64Bit":"32Bit"); m_opened = true; // vcodec is open, update speed if it was // changed before VideoPlayer called OpenDecoder. SetSpeed(m_speed); + SetPollDevice(am_private->vcodec.cntl_handle); return true; } @@ -1600,7 +1626,7 @@ bool CAMLCodec::OpenAmlVideo(const CDVDStreamInfo &hints) m_defaultVfmMap = GetVfmMap("default"); SetVfmMap("default", "decoder ppmgr deinterlace amlvideo amvideo"); - SysfsUtils::SetInt("/sys/module/amlvideodri/parameters/freerun_mode", 1); + SysfsUtils::SetInt("/sys/module/amlvideodri/parameters/freerun_mode", 3); return true; } @@ -1636,12 +1662,13 @@ void CAMLCodec::SetVfmMap(const std::string &name, const std::string &map) void CAMLCodec::CloseDecoder() { CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder"); - StopThread(); + + SetPollDevice(-1); // never leave vcodec ff/rw or paused. if (m_speed != DVD_PLAYSPEED_NORMAL) { - m_dll->codec_resume(&am_private->vcodec); + //m_dll->codec_resume(&am_private->vcodec); m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE); } m_dll->codec_close(&am_private->vcodec); @@ -1672,6 +1699,8 @@ void CAMLCodec::Reset() if (!m_opened) return; + SetPollDevice(-1); + // set the system blackout_policy to leave the last frame showing int blackout_policy; SysfsUtils::GetInt("/sys/class/video/blackout_policy", blackout_policy); @@ -1680,11 +1709,14 @@ void CAMLCodec::Reset() // restore the speed (some amcodec versions require this) if (m_speed != DVD_PLAYSPEED_NORMAL) { - m_dll->codec_resume(&am_private->vcodec); m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE); } + m_dll->codec_pause(&am_private->vcodec); + // reset the decoder m_dll->codec_reset(&am_private->vcodec); + m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000); + dumpfile_close(am_private); dumpfile_open(am_private); @@ -1697,20 +1729,31 @@ void CAMLCodec::Reset() // restore the saved system blackout_policy value SysfsUtils::SetInt("/sys/class/video/blackout_policy", blackout_policy); - // reset some internal vars - m_1st_pts = 0; - m_cur_pts = 0; - m_ptsQueue.clear(); + // reset some interal vars + m_cur_pts = INT64_0; + m_state = 0; + m_start_adj = 0; + m_frameSizes.clear(); + m_frameSizeSum = 0; + SetSpeed(m_speed); + + SetPollDevice(am_private->vcodec.cntl_handle); } int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts) { if (!m_opened) - return VC_BUFFER; + return VC_ERROR; + int rtn(0); + + float timesize(GetTimeSize()); if (pData) { + m_frameSizes.push_back(iSize); + m_frameSizeSum += iSize; + am_private->am_pkt.data = pData; am_private->am_pkt.data_size = iSize; @@ -1721,31 +1764,39 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts) // handle pts, including 31bit wrap, aml can only handle 31 // bit pts as it uses an int in kernel. if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE) - am_private->am_pkt.avpts = AV_NOPTS_VALUE; + am_private->am_pkt.avpts = INT64_0; else { am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\ - if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff) - m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff; + if (!m_start_adj && am_private->am_pkt.avpts >= 0x7fffffff) + m_start_adj = am_private->am_pkt.avpts & ~0x0000ffff; + am_private->am_pkt.avpts -= m_start_adj; + m_state |= STATE_HASPTS; } - if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE) - am_private->am_pkt.avpts -= m_start_pts; // handle dts, including 31bit wrap, aml can only handle 31 // bit dts as it uses an int in kernel. if (dts == DVD_NOPTS_VALUE) - am_private->am_pkt.avdts = AV_NOPTS_VALUE; + am_private->am_pkt.avdts = am_private->am_pkt.avpts; else { am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE; - if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff) - m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff; - } - if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE) - am_private->am_pkt.avdts -= m_start_dts; + if (!m_start_adj && am_private->am_pkt.avdts >= 0x7fffffff) + m_start_adj = am_private->am_pkt.avdts & ~0x0000ffff; + am_private->am_pkt.avdts -= m_start_adj; - //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)", - // iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts); + // For VC1 AML decoder uses PTS only on I-Frames + if (am_private->am_pkt.avpts == INT64_0 && (((size_t)am_private->gcodec.param) & KEYFRAME_PTS_ONLY)) + am_private->am_pkt.avpts = am_private->am_pkt.avdts; + } + // We use this to determine the fill state if no PTS is given + if (m_cur_pts == INT64_0) + { + m_cur_pts = am_private->am_pkt.avdts; + // No PTS given -> use first DTS for AML ptsserver initialization + if ((m_state & STATE_HASPTS) == 0) + am_private->am_pkt.avpts = am_private->am_pkt.avdts; + } // some formats need header/data tweaks. // the actual write occurs once in write_av_packet @@ -1767,80 +1818,142 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts) loop++; } if (loop == 100) - { // Decoder got stuck; Reset Reset(); - } - // if we seek, then GetTimeSize is wrong as - // reports lastpts - cur_pts and hw decoder has - // not started outputing new pts values yet. - // so we grab the 1st pts sent into driver and - // use that to calc GetTimeSize. - if (m_1st_pts == 0) - m_1st_pts = am_private->am_pkt.lastpts; + if ((m_state & STATE_PREFILLED) == 0 && timesize >= 1.0) + m_state |= STATE_PREFILLED; } - // if we have still frames, demux size will be small - // and we need to pre-buffer more. - double target_timesize = 1.0; - if (iSize < 20) - target_timesize = 2.0; - - int rtn = 0; + if ((m_state & STATE_PREFILLED) != 0 && timesize > 0.5 && DequeueBuffer() == 0) + rtn |= VC_PICTURE; - // keep hw buffered demux above 1 second - if (GetTimeSize() < target_timesize) + if (((rtn & VC_PICTURE) == 0 && timesize < 2.0) || timesize < 1.0) rtn |= VC_BUFFER; - // wait until we get a new frame or 25ms, - if (m_ptsQueue.size() == 0) - m_ready_event.WaitMSec(25); - if (m_ptsQueue.size() > 0) + if (g_advancedSettings.CanLogComponent(LOGVIDEO)) { - CSingleLock lock(m_ptsQueueMutex); - m_cur_pts = m_ptsQueue.front(); - m_ptsQueue.pop_front(); - rtn |= VC_PICTURE; + CLog::Log(LOGDEBUG, "CAMLCodec::Decode: ret: %d, sz: %u, dts_in: %0.4lf[%llX], pts_in: %0.4lf[%llX], adj:%llu, ptsOut:%0.4f, amlpts:%d, idx:%u, timesize:%0.4f", + rtn, + static_cast<unsigned int>(iSize), + dts / DVD_TIME_BASE, am_private->am_pkt.avdts, + pts / DVD_TIME_BASE, am_private->am_pkt.avpts, + m_start_adj, + static_cast<float>(m_cur_pts)/PTS_FREQ, + static_cast<int>(m_cur_pts), + m_bufferIndex, + timesize + ); } -/* - CLog::Log(LOGDEBUG, "CAMLCodec::Decode: " - "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)", - rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize()); -*/ + return rtn; } -int CAMLCodec::DequeueBuffer(int64_t &pts) +std::atomic_flag CAMLCodec::m_pollSync = ATOMIC_FLAG_INIT; +int CAMLCodec::m_pollDevice; + +int CAMLCodec::PollFrame() +{ + CAtomicSpinLock lock(m_pollSync); + if (m_pollDevice < 0) + return 0; + + struct pollfd codec_poll_fd[1]; + + codec_poll_fd[0].fd = m_pollDevice; + codec_poll_fd[0].events = POLLOUT; + + if (poll(codec_poll_fd, 1, 100) > 0) + { + g_aml_sync_event.Set(); + return 1; + } + return 0; +} + +void CAMLCodec::SetPollDevice(int dev) { + CAtomicSpinLock lock(m_pollSync); + m_pollDevice = dev; +} + +int CAMLCodec::ReleaseFrame(const uint32_t index, bool drop) +{ + int ret; v4l2_buffer vbuf = { 0 }; vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.index = index; + + if (drop) + vbuf.flags |= V4L2_BUF_FLAG_DONE; + + if (g_advancedSettings.CanLogComponent(LOGVIDEO)) + CLog::Log(LOGDEBUG, "CAMLCodec::ReleaseFrame idx:%u", index); + + if ((ret = m_amlVideoFile->IOControl(VIDIOC_QBUF, &vbuf)) < 0) + CLog::Log(LOGERROR, "CAMLCodec::ReleaseFrame - VIDIOC_QBUF failed: %s", strerror(errno)); + return ret; +} + +int CAMLCodec::DequeueBuffer() +{ + v4l2_buffer vbuf = { 0 }; + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + //Driver change from 10 to 0ms latency, throttle here + std::chrono::time_point<std::chrono::system_clock> now(std::chrono::system_clock::now()); if (m_amlVideoFile->IOControl(VIDIOC_DQBUF, &vbuf) < 0) { if (errno != EAGAIN) CLog::Log(LOGERROR, "CAMLCodec::DequeueBuffer - VIDIOC_DQBUF failed: %s", strerror(errno)); + + std::chrono::milliseconds elapsed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now).count()); + + if (elapsed < std::chrono::milliseconds(10)) + std::this_thread::sleep_for(std::chrono::milliseconds(10) - elapsed); + return -errno; } // Since kernel 3.14 Amlogic changed length and units of PTS values reported here. // To differentiate such PTS values we check for existence of omx_pts_interval_lower // parameter, because it was introduced since kernel 3.14. - if (access("/sys/module/amvideo/parameters/omx_pts_interval_lower", F_OK) != -1) + m_last_pts = m_cur_pts; + + if (m_ptsIs64us) { - pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF; - pts <<= 32; - pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF; - pts = (pts * PTS_FREQ) / DVD_TIME_BASE; + m_cur_pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF; + m_cur_pts <<= 32; + m_cur_pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF; + m_cur_pts = (m_cur_pts * PTS_FREQ) / DVD_TIME_BASE; } else { - pts = vbuf.timestamp.tv_usec; + m_cur_pts = vbuf.timestamp.tv_usec; } + m_bufferIndex = vbuf.index; return 0; } +float CAMLCodec::GetTimeSize() +{ + struct buf_status bs; + m_dll->codec_get_vbuf_state(&am_private->vcodec, &bs); + + //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: buf status: s:%d dl:%d fl:%d rp:%u wp:%u",bs.size, bs.data_len, bs.free_len, bs.read_pointer, bs.write_pointer); + while (m_frameSizeSum > (unsigned int)bs.data_len) + { + m_frameSizeSum -= m_frameSizes.front(); + m_frameSizes.pop_front(); + } + if (bs.free_len < bs.data_len) + return 7.0; + + return (float)(m_frameSizes.size() * am_private->video_rate) / UNIT_FREQ; +} + bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture) { if (!m_opened) @@ -1848,24 +1961,23 @@ bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture) pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; pDvdVideoPicture->format = RENDER_FMT_AML; - pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ; - pDvdVideoPicture->dts = DVD_NOPTS_VALUE; - if (m_speed == DVD_PLAYSPEED_NORMAL) - pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE; + if (m_last_pts <= 0) + pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ; else - { - if (m_cur_pts == 0) - pDvdVideoPicture->pts = (double)m_1st_pts / PTS_FREQ * DVD_TIME_BASE; - else - pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE; - } + pDvdVideoPicture->iDuration = (double)((m_cur_pts - m_last_pts) * DVD_TIME_BASE) / PTS_FREQ; + + pDvdVideoPicture->dts = DVD_NOPTS_VALUE; + pDvdVideoPicture->pts = (double)GetCurPts() / PTS_FREQ * DVD_TIME_BASE; return true; } void CAMLCodec::SetSpeed(int speed) { + if (m_speed == speed) + return; + CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed); // update internal vars regardless @@ -1878,15 +1990,15 @@ void CAMLCodec::SetSpeed(int speed) switch(speed) { case DVD_PLAYSPEED_PAUSE: - m_dll->codec_pause(&am_private->vcodec); + //m_dll->codec_pause(&am_private->vcodec); m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE); break; case DVD_PLAYSPEED_NORMAL: - m_dll->codec_resume(&am_private->vcodec); + //m_dll->codec_resume(&am_private->vcodec); m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE); break; default: - m_dll->codec_resume(&am_private->vcodec); + //m_dll->codec_resume(&am_private->vcodec); if ((am_private->video_format == VFORMAT_H264) || (am_private->video_format == VFORMAT_H264_4K2K)) m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB); else @@ -1895,68 +2007,6 @@ void CAMLCodec::SetSpeed(int speed) } } -int CAMLCodec::GetDataSize() -{ - if (!m_opened) - return 0; - - struct buf_status vbuf ={0}; - if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0) - m_vbufsize = vbuf.size; - - return vbuf.data_len; -} - -double CAMLCodec::GetTimeSize() -{ - if (!m_opened) - return 0; - - // if m_cur_pts is zero, hw decoder was not started yet - // so we use the pts of the 1st demux packet that was send - // to hw decoder to calc timesize. - if (m_cur_pts == 0) - m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ; - else - m_timesize = (double)(am_private->am_pkt.lastpts - GetOMXPts()) / PTS_FREQ; - - // lie to VideoPlayer, it is hardcoded to a max of 8 seconds, - // if you buffer more than 8 seconds, it goes nuts. - double timesize = m_timesize; - if (timesize < 0.0) - timesize = 0.0; - else if (timesize > 7.0) - timesize = 7.0; - - return timesize; -} - -void CAMLCodec::Process() -{ - CLog::Log(LOGDEBUG, "CAMLCodec::Process Started"); - - while (!m_bStop) - { - if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0) - { - CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed"); - Sleep(10); - } - - { - CSingleLock lock(m_ptsQueueMutex); - int64_t pts = 0; - if (DequeueBuffer(pts) == 0) - { - m_ptsQueue.push_back(pts + m_start_pts); - m_ready_event.Set(); - } - } - } - - CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped"); -} - void CAMLCodec::ShowMainVideo(const bool show) { static int saved_disable_video = -1; @@ -2083,7 +2133,8 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect) case 1: case 3: { - int diff = (int) ((dst_rect.Height() - dst_rect.Width()) / 2); + double scale = (double)dst_rect.Height() / dst_rect.Width(); + int diff = (int) ((dst_rect.Height()*scale - dst_rect.Width()) / 2); dst_rect = CRect(DestRect.x1 - diff, DestRect.y1, DestRect.x2 + diff, DestRect.y2); } @@ -2208,3 +2259,9 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect) // that would show video playback, so show it. ShowMainVideo(true); } + +void CAMLCodec::SetVideoRate(int videoRate) +{ + if (am_private) + am_private->video_rate = videoRate; +} diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h index ede815d805..402ef7f93a 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h @@ -24,8 +24,9 @@ #include "cores/IPlayer.h" #include "guilib/Geometry.h" #include "rendering/RenderSystem.h" -#include "threads/Thread.h" + #include <deque> +#include <atomic> typedef struct am_private_t am_private_t; @@ -34,7 +35,7 @@ class DllLibAmCodec; class PosixFile; typedef std::shared_ptr<PosixFile> PosixFilePtr; -class CAMLCodec : public CThread +class CAMLCodec { public: CAMLCodec(); @@ -48,14 +49,18 @@ public: bool GetPicture(DVDVideoPicture* pDvdVideoPicture); void SetSpeed(int speed); - int GetDataSize(); - double GetTimeSize(); void SetVideoRect(const CRect &SrcRect, const CRect &DestRect); - int64_t GetCurPts() const { return m_cur_pts; } - int GetOMXPts() const { return static_cast<int>(m_cur_pts - m_start_pts); } + void SetVideoRate(int videoRate); + int64_t GetCurPts() const { return m_cur_pts + m_start_adj; } + int GetOMXPts() const { return static_cast<int>(m_cur_pts); } + uint32_t GetBufferIndex() const { return m_bufferIndex; }; + static float OMXPtsToSeconds(int omxpts); + static int OMXDurationToNs(int duration); + int GetAmlDuration() const; + int ReleaseFrame(const uint32_t index, bool bDrop = false); -protected: - virtual void Process(); + static int PollFrame(); + static void SetPollDevice(int device); private: void ShowMainVideo(const bool show); @@ -69,20 +74,20 @@ private: void CloseAmlVideo(); std::string GetVfmMap(const std::string &name); void SetVfmMap(const std::string &name, const std::string &map); - int DequeueBuffer(int64_t &pts); + int DequeueBuffer(); + float GetTimeSize(); DllLibAmCodec *m_dll; bool m_opened; + bool m_ptsIs64us; am_private_t *am_private; CDVDStreamInfo m_hints; - volatile int m_speed; - volatile int64_t m_1st_pts; - volatile int64_t m_cur_pts; - volatile double m_timesize; - volatile int64_t m_vbufsize; - int64_t m_start_dts; - int64_t m_start_pts; - CEvent m_ready_event; + int m_speed; + int64_t m_cur_pts; + uint32_t m_max_frame_size; + int64_t m_start_adj; + int64_t m_last_pts; + uint32_t m_bufferIndex; CRect m_dst_rect; CRect m_display_rect; @@ -95,8 +100,17 @@ private: int m_brightness; RESOLUTION m_video_res; + static const unsigned int STATE_PREFILLED = 1; + static const unsigned int STATE_HASPTS = 2; + + unsigned int m_state; + PosixFilePtr m_amlVideoFile; std::string m_defaultVfmMap; - std::deque<int64_t> m_ptsQueue; - CCriticalSection m_ptsQueueMutex; + + std::deque<uint32_t> m_frameSizes; + std::uint32_t m_frameSizeSum; + + static std::atomic_flag m_pollSync; + static int m_pollDevice; }; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp index d78631d0c6..ec0395974c 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp @@ -30,6 +30,7 @@ #include "utils/log.h" #include "utils/SysfsUtils.h" #include "settings/Settings.h" +#include "threads/Thread.h" #define __MODULE_NAME__ "DVDVideoCodecAmlogic" @@ -43,16 +44,17 @@ typedef struct frame_queue { CDVDVideoCodecAmlogic::CDVDVideoCodecAmlogic(CProcessInfo &processInfo) : CDVDVideoCodec(processInfo), m_Codec(NULL), m_pFormatName("amcodec"), + m_opened(false), m_last_pts(0.0), m_frame_queue(NULL), m_queue_depth(0), m_framerate(0.0), m_video_rate(0), m_mpeg2_sequence(NULL), + m_drop(false), + m_has_keyframe(false), m_bitparser(NULL), - m_bitstream(NULL), - m_opened(false), - m_drop(false) + m_bitstream(NULL) { pthread_mutex_init(&m_queue_mutex, NULL); } @@ -125,14 +127,18 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option { m_bitstream = new CBitstreamConverter; m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true); + m_bitstream->ResetKeyframe(); // make sure we do not leak the existing m_hints.extradata free(m_hints.extradata); m_hints.extrasize = m_bitstream->GetExtraSize(); m_hints.extradata = malloc(m_hints.extrasize); memcpy(m_hints.extradata, m_bitstream->GetExtraData(), m_hints.extrasize); } - //m_bitparser = new CBitstreamParser(); - //m_bitparser->Open(); + else + { + m_bitparser = new CBitstreamParser(); + m_bitparser->Open(); + } break; case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_MSMPEG4V2: @@ -147,9 +153,9 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option // amcodec can't handle h263 return false; break; - case AV_CODEC_ID_FLV1: - m_pFormatName = "am-flv1"; - break; +// case AV_CODEC_ID_FLV1: +// m_pFormatName = "am-flv1"; +// break; case AV_CODEC_ID_RV10: case AV_CODEC_ID_RV20: case AV_CODEC_ID_RV30: @@ -236,6 +242,9 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option m_processInfo.SetVideoDecoderName(m_pFormatName, true); m_processInfo.SetVideoDimensions(m_hints.width, m_hints.height); m_processInfo.SetVideoDeintMethod("hardware"); + m_processInfo.SetVideoDAR(m_hints.aspect); + + m_has_keyframe = false; CLog::Log(LOGINFO, "%s: Opened Amlogic Codec", __MODULE_NAME__); return true; @@ -277,21 +286,35 @@ int CDVDVideoCodecAmlogic::Decode(uint8_t *pData, int iSize, double dts, double if (!m_bitstream->Convert(pData, iSize)) return VC_ERROR; + if (!m_bitstream->HasKeyframe()) + { + CLog::Log(LOGDEBUG, "%s::Decode waiting for keyframe (bitstream)", __MODULE_NAME__); + return VC_BUFFER; + } pData = m_bitstream->GetConvertBuffer(); iSize = m_bitstream->GetConvertSize(); } - - if (m_bitparser) - m_bitparser->FindIdrSlice(pData, iSize); - + else if (!m_has_keyframe && m_bitparser) + { + if (!m_bitparser->HasKeyframe(pData, iSize)) + { + CLog::Log(LOGDEBUG, "%s::Decode waiting for keyframe (bitparser)", __MODULE_NAME__); + return VC_BUFFER; + } + else + m_has_keyframe = true; + } FrameRateTracking( pData, iSize, dts, pts); - } - if (!m_opened) - { - if (m_Codec && !m_Codec->OpenDecoder(m_hints)) - CLog::Log(LOGERROR, "%s: Failed to open Amlogic Codec", __MODULE_NAME__); - m_opened = true; + if (!m_opened) + { + if (pts == DVD_NOPTS_VALUE) + m_hints.ptsinvalid = true; + + if (m_Codec && !m_Codec->OpenDecoder(m_hints)) + CLog::Log(LOGERROR, "%s: Failed to open Amlogic Codec", __MODULE_NAME__); + m_opened = true; + } } if (m_hints.ptsinvalid) @@ -307,6 +330,9 @@ void CDVDVideoCodecAmlogic::Reset(void) m_Codec->Reset(); m_mpeg2_sequence_pts = 0; + m_has_keyframe = false; + if (m_bitstream && m_hints.codec == AV_CODEC_ID_H264) + m_bitstream->ResetKeyframe(); } bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture) @@ -315,7 +341,8 @@ bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture) m_Codec->GetPicture(&m_videobuffer); *pDvdVideoPicture = m_videobuffer; - CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec, m_Codec->GetOMXPts()); + CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec, + m_Codec->GetOMXPts(), m_Codec->GetAmlDuration(), m_Codec->GetBufferIndex()); { CSingleLock lock(m_secure); @@ -363,7 +390,7 @@ void CDVDVideoCodecAmlogic::SetDropState(bool bDrop) // Freerun mode causes amvideo driver to ignore timing and process frames // as quickly as they are coming from decoder. By enabling freerun mode we can // skip rendering of the frames that are requested to be dropped by VideoPlayer. - SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0); + //SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0); } void CDVDVideoCodecAmlogic::SetSpeed(int iSpeed) @@ -372,22 +399,6 @@ void CDVDVideoCodecAmlogic::SetSpeed(int iSpeed) m_Codec->SetSpeed(iSpeed); } -int CDVDVideoCodecAmlogic::GetDataSize(void) -{ - if (m_Codec) - return m_Codec->GetDataSize(); - - return 0; -} - -double CDVDVideoCodecAmlogic::GetTimeSize(void) -{ - if (m_Codec) - return m_Codec->GetTimeSize(); - - return 0.0; -} - void CDVDVideoCodecAmlogic::FrameQueuePop(void) { if (!m_frame_queue || m_queue_depth == 0) @@ -466,8 +477,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double m_framerate = m_mpeg2_sequence->rate; m_video_rate = (int)(0.5 + (96000.0 / m_framerate)); - CLog::Log(LOGDEBUG, "%s: detected mpeg2 aspect ratio(%f), framerate(%f), video_rate(%d)", - __MODULE_NAME__, m_mpeg2_sequence->ratio, m_framerate, m_video_rate); + m_processInfo.SetVideoFps(m_framerate); // update m_hints for 1st frame fixup. switch(m_mpeg2_sequence->rate_info) @@ -526,7 +536,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double if (cur_pts == DVD_NOPTS_VALUE) cur_pts = m_frame_queue->dts; - pthread_mutex_unlock(&m_queue_mutex); + pthread_mutex_unlock(&m_queue_mutex); float duration = cur_pts - m_last_pts; m_last_pts = cur_pts; @@ -559,22 +569,10 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double break; // 25.000 (40000.000000) - case 40000: + case 39900 ... 40100: framerate = 25000.0 / 1000.0; break; - // 24.975 (40040.000000) - case 40040: - framerate = 25000.0 / 1001.0; - break; - - /* - // 24.000 (41666.666666) - case 41667: - framerate = 24000.0 / 1000.0; - break; - */ - // 23.976 (41708.33333) case 40200 ... 43200: // 23.976 seems to have the crappiest encodings :) @@ -592,6 +590,12 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double { m_framerate = framerate; m_video_rate = (int)(0.5 + (96000.0 / framerate)); + + if (m_Codec) + m_Codec->SetVideoRate(m_video_rate); + + m_processInfo.SetVideoFps(m_framerate); + CLog::Log(LOGDEBUG, "%s: detected new framerate(%f), video_rate(%d)", __MODULE_NAME__, m_framerate, m_video_rate); } @@ -607,11 +611,14 @@ void CDVDVideoCodecAmlogic::RemoveInfo(CDVDAmlogicInfo *info) m_inflight.erase(m_inflight.find(info)); } -CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts) +CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration, uint32_t bufferIndex) : m_refs(0) , m_codec(codec) , m_amlCodec(amlcodec) , m_omxPts(omxPts) + , m_amlDuration(amlDuration) + , m_bufferIndex(bufferIndex) + , m_rendered(false) { } diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h index 2c442413eb..9e57295701 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h @@ -36,7 +36,7 @@ class CDVDVideoCodecAmlogic; class CDVDAmlogicInfo { public: - CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts); + CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration, uint32_t bufferIndex); // reference counting CDVDAmlogicInfo* Retain(); @@ -44,7 +44,11 @@ public: CAMLCodec *getAmlCodec() const; int GetOmxPts() const { return m_omxPts; } + int GetAmlDuration() const { return m_amlDuration; } + uint32_t GetBufferIndex() const { return m_bufferIndex; }; void invalidate(); + void SetRendered() { m_rendered = true; }; + bool IsRendered() { return m_rendered; }; protected: long m_refs; @@ -52,7 +56,9 @@ protected: CDVDVideoCodecAmlogic* m_codec; CAMLCodec* m_amlCodec; - int m_omxPts; + int m_omxPts, m_amlDuration; + uint32_t m_bufferIndex; + bool m_rendered; }; class CDVDVideoCodecAmlogic : public CDVDVideoCodec @@ -71,8 +77,6 @@ public: virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture); virtual void SetSpeed(int iSpeed); virtual void SetDropState(bool bDrop); - virtual int GetDataSize(void); - virtual double GetTimeSize(void); virtual const char* GetName(void) { return (const char*)m_pFormatName; } protected: @@ -98,6 +102,7 @@ protected: mpeg2_sequence *m_mpeg2_sequence; double m_mpeg2_sequence_pts; bool m_drop; + bool m_has_keyframe; CBitstreamParser *m_bitparser; CBitstreamConverter *m_bitstream; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp index 999a2ac8b8..297d198dc6 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp @@ -584,7 +584,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio } // blacklist of devices that cannot surface render. - m_render_sw = CanSurfaceRenderBlackList(m_codecname) || g_advancedSettings.m_mediacodecForceSoftwareRendring; + m_render_sw = CanSurfaceRenderBlackList(m_codecname) || g_advancedSettings.m_mediacodecForceSoftwareRendering; if (m_render_sw) { if (m_colorFormat == -1) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h index 063396e03c..0ac073a45a 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h @@ -96,7 +96,7 @@ protected: AVFilterContext* m_pFilterIn; AVFilterContext* m_pFilterOut; AVFrame* m_pFilterFrame; - bool m_filterEof; + bool m_filterEof = false; CDVDVideoPPFFmpeg m_postProc; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.cpp index de6072f43b..88c7980e88 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.cpp @@ -304,8 +304,8 @@ int COpenMaxVideo::EnqueueDemuxPacket(omx_demux_packet demux_packet) OMX_BUFFERHEADERTYPE* omx_buffer; // need to lock here to retrieve an input buffer and pop the queue - omx_buffer = m_omx_input_avaliable.front(); - m_omx_input_avaliable.pop(); + omx_buffer = m_omx_input_available.front(); + m_omx_input_available.pop(); // delete the previous demuxer buffer delete [] omx_buffer->pBuffer; @@ -361,7 +361,7 @@ int COpenMaxVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) m_demux_queue.push(demux_packet); - while(!m_omx_input_avaliable.empty() && !m_demux_queue.empty()) + while(!m_omx_input_available.empty() && !m_demux_queue.empty()) { demux_packet = m_demux_queue.front(); m_demux_queue.pop(); @@ -369,7 +369,7 @@ int COpenMaxVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) } #if defined(OMX_DEBUG_VERBOSE) - if (m_omx_input_avaliable.empty()) + if (m_omx_input_available.empty()) CLog::Log(LOGDEBUG, "%s::%s - buffering demux, m_demux_queue_size(%d), demuxer_bytes(%d)\n", CLASSNAME, __func__, m_demux_queue.size(), demuxer_bytes); @@ -378,7 +378,7 @@ int COpenMaxVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) int returnCode = VC_BUFFER; - if (m_omx_input_avaliable.empty() && m_omx_output_ready.empty()) { + if (m_omx_input_available.empty() && m_omx_output_ready.empty()) { // Sleep for some time until either an image has been decoded or there's space in the input buffer again struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); @@ -393,7 +393,7 @@ int COpenMaxVideo::Decode(uint8_t* pData, int iSize, double dts, double pts) if (!m_omx_output_ready.empty()) { returnCode |= VC_PICTURE; } - if (!m_omx_input_avaliable.empty()) { + if (!m_omx_input_available.empty()) { returnCode |= VC_BUFFER; } @@ -515,7 +515,7 @@ int COpenMaxVideo::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; pDvdVideoPicture->iFlags |= m_drop_state ? DVP_FLAG_DROPPED : 0; - returnCode |= m_omx_input_avaliable.empty() ? 0 : VC_BUFFER; + returnCode |= m_omx_input_available.empty() ? 0 : VC_BUFFER; return returnCode; } @@ -536,8 +536,8 @@ OMX_ERRORTYPE COpenMaxVideo::DecoderEmptyBufferDone( // queue free input buffer to available list. pthread_mutex_lock(&m_omx_queue_mutex); - ctx->m_omx_input_avaliable.push(pBuffer); - if(!ctx->m_omx_input_avaliable.empty()) { + ctx->m_omx_input_available.push(pBuffer); + if(!ctx->m_omx_input_available.empty()) { if (!ctx->m_demux_queue.empty()) { omx_demux_packet demux_packet = m_demux_queue.front(); ctx->m_demux_queue.pop(); @@ -659,7 +659,7 @@ OMX_ERRORTYPE COpenMaxVideo::AllocOMXInputBuffers(void) } m_omx_input_buffers.push_back(buffer); // don't have to lock/unlock here, we are not decoding - m_omx_input_avaliable.push(buffer); + m_omx_input_available.push(buffer); } m_omx_input_eos = false; @@ -686,8 +686,8 @@ OMX_ERRORTYPE COpenMaxVideo::FreeOMXInputBuffers(bool wait) m_omx_input_buffers.clear(); // empty input buffer queue. not decoding so don't need lock/unlock. - while (!m_omx_input_avaliable.empty()) - m_omx_input_avaliable.pop(); + while (!m_omx_input_available.empty()) + m_omx_input_available.pop(); while (!m_demux_queue.empty()) m_demux_queue.pop(); while (!m_dts_queue.empty()) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.h index 6c835e8141..a1dac00373 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/OpenMaxVideo.h @@ -148,7 +148,7 @@ protected: pthread_cond_t m_omx_queue_available; // OpenMax input buffers (demuxer packets) - std::queue<OMX_BUFFERHEADERTYPE*> m_omx_input_avaliable; + std::queue<OMX_BUFFERHEADERTYPE*> m_omx_input_available; std::vector<OMX_BUFFERHEADERTYPE*> m_omx_input_buffers; bool m_omx_input_eos; int m_omx_input_port; diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp index 6f2d4f98cb..87cdc52dac 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp @@ -97,8 +97,8 @@ bool CDVDInputStreamFile::Open() return false; } - if (m_pFile->GetImplemenation() && (content.empty() || content == "application/octet-stream")) - m_content = m_pFile->GetImplemenation()->GetContent(); + if (m_pFile->GetImplementation() && (content.empty() || content == "application/octet-stream")) + m_content = m_pFile->GetImplementation()->GetContent(); m_eof = false; return true; diff --git a/xbmc/cores/VideoPlayer/DVDMessage.h b/xbmc/cores/VideoPlayer/DVDMessage.h index 7291399222..729068ef03 100644 --- a/xbmc/cores/VideoPlayer/DVDMessage.h +++ b/xbmc/cores/VideoPlayer/DVDMessage.h @@ -87,10 +87,6 @@ public: VIDEO_SET_ASPECT, // set aspectratio of video VIDEO_DRAIN, // wait for decoder to output last frame - // audio related messages - - AUDIO_SILENCE, - // subtitle related messages SUBTITLE_CLUTCHANGE, SUBTITLE_ADDFILE @@ -221,7 +217,6 @@ public: int time = 0; bool relative = false; bool backward = false; - bool flush = true; bool accurate = true; bool sync = true; bool restore = true; @@ -234,7 +229,6 @@ public: int GetTime() { return m_mode.time; } bool GetRelative() { return m_mode.relative; } bool GetBackward() { return m_mode.backward; } - bool GetFlush() { return m_mode.flush; } bool GetAccurate() { return m_mode.accurate; } bool GetRestore() { return m_mode.restore; } bool GetTrickPlay() { return m_mode.trickplay; } diff --git a/xbmc/cores/VideoPlayer/Edl.cpp b/xbmc/cores/VideoPlayer/Edl.cpp index c87fe21a79..9d2edda39d 100644 --- a/xbmc/cores/VideoPlayer/Edl.cpp +++ b/xbmc/cores/VideoPlayer/Edl.cpp @@ -46,6 +46,7 @@ void CEdl::Clear() m_vecCuts.clear(); m_vecSceneMarkers.clear(); m_iTotalCutTime = 0; + m_lastQueryTime = 0; } bool CEdl::ReadEditDecisionLists(const std::string& strMovie, const float fFrameRate, const int iHeight) @@ -822,8 +823,10 @@ std::string CEdl::GetInfo() const return strInfo.empty() ? "-" : strInfo; } -bool CEdl::InCut(const int iSeek, Cut *pCut) const +bool CEdl::InCut(const int iSeek, Cut *pCut) { + m_lastQueryTime = iSeek; + for (int i = 0; i < (int)m_vecCuts.size(); i++) { if (iSeek < m_vecCuts[i].start) // Early exit if not even up to the cut start time. @@ -840,6 +843,11 @@ bool CEdl::InCut(const int iSeek, Cut *pCut) const return false; } +int CEdl::GetLastQueryTime() const +{ + return m_lastQueryTime; +} + bool CEdl::GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const { if (bPlus) @@ -885,7 +893,7 @@ bool CEdl::GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const } } -bool CEdl::GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker) const +bool CEdl::GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker) { if (!HasSceneMarker()) return false; diff --git a/xbmc/cores/VideoPlayer/Edl.h b/xbmc/cores/VideoPlayer/Edl.h index c19b69fa5c..21c99088ea 100644 --- a/xbmc/cores/VideoPlayer/Edl.h +++ b/xbmc/cores/VideoPlayer/Edl.h @@ -53,18 +53,19 @@ public: int RemoveCutTime(int iSeek) const; int RestoreCutTime(int iClock) const; - bool InCut(int iSeek, Cut *pCut = NULL) const; + bool InCut(int iSeek, Cut *pCut = NULL); bool GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const; + int GetLastQueryTime() const; - bool GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker) const; + bool GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker); static std::string MillisecondsToTimeString(const int iMilliseconds); -protected: private: int m_iTotalCutTime; // ms std::vector<Cut> m_vecCuts; std::vector<int> m_vecSceneMarkers; + int m_lastQueryTime; bool ReadEdl(const std::string& strMovie, const float fFramesPerSecond); bool ReadComskip(const std::string& strMovie, const float fFramesPerSecond); diff --git a/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp b/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp index dab7a05956..f2fbe81aec 100644 --- a/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp +++ b/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp @@ -48,7 +48,7 @@ EINTERLACEMETHOD CProcessInfoPi::GetFallbackDeintMethod() bool CProcessInfoPi::AllowDTSHDDecode() { - if (g_RBP.RasberryPiVersion() == 1) + if (g_RBP.RaspberryPiVersion() == 1) return false; return true; } diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index 5945d06dea..131139a285 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -635,7 +635,6 @@ CVideoPlayer::CVideoPlayer(IPlayerCallback& callback) m_dvd.Clear(); m_State.Clear(); - m_EdlAutoSkipMarkers.Clear(); m_UpdateApplication = 0; m_bAbortRequest = false; @@ -747,7 +746,6 @@ bool CVideoPlayer::CloseFile(bool reopen) StopThread(); m_Edl.Clear(); - m_EdlAutoSkipMarkers.Clear(); m_HasVideo = false; m_HasAudio = false; @@ -1274,7 +1272,6 @@ void CVideoPlayer::Process() // look for any EDL files m_Edl.Clear(); - m_EdlAutoSkipMarkers.Clear(); if (m_CurrentVideo.id >= 0 && m_CurrentVideo.hint.fpsrate > 0 && m_CurrentVideo.hint.fpsscale > 0) { float fFramesPerSecond = (float)m_CurrentVideo.hint.fpsrate / (float)m_CurrentVideo.hint.fpsscale; @@ -1288,7 +1285,7 @@ void CVideoPlayer::Process() */ CEdl::Cut cut; int starttime = 0; - if(m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0) + if (m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0) { if (m_PlayerOptions.startpercent > 0 && m_pDemuxer) { @@ -1301,7 +1298,7 @@ void CVideoPlayer::Process() } CLog::Log(LOGDEBUG, "%s - Start position set to last stopped position: %d", __FUNCTION__, starttime); } - else if(m_Edl.InCut(0, &cut)) + else if (m_Edl.InCut(starttime, &cut)) { if (cut.action == CEdl::CUT) { @@ -1318,20 +1315,13 @@ void CVideoPlayer::Process() std::string strTimeString = StringUtils::SecondsToTimeString(cut.end / 1000, TIME_FORMAT_MM_SS); CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString); - - /* - * Setup auto skip markers as if the commercial break had been skipped using standard - * detection. - */ - m_EdlAutoSkipMarkers.commbreak_start = cut.start; - m_EdlAutoSkipMarkers.commbreak_end = cut.end; - m_EdlAutoSkipMarkers.seek_to_start = true; } } - if(starttime > 0) + + if (starttime > 0) { double startpts = DVD_NOPTS_VALUE; - if(m_pDemuxer) + if (m_pDemuxer) { if (m_pDemuxer->SeekTime(starttime, false, &startpts)) CLog::Log(LOGDEBUG, "%s - starting demuxer from: %d", __FUNCTION__, starttime); @@ -1339,13 +1329,15 @@ void CVideoPlayer::Process() CLog::Log(LOGDEBUG, "%s - failed to start demuxing from: %d", __FUNCTION__, starttime); } - if(m_pSubtitleDemuxer) + if (m_pSubtitleDemuxer) { if(m_pSubtitleDemuxer->SeekTime(starttime, false, &startpts)) CLog::Log(LOGDEBUG, "%s - starting subtitle demuxer from: %d", __FUNCTION__, starttime); else CLog::Log(LOGDEBUG, "%s - failed to start subtitle demuxing from: %d", __FUNCTION__, starttime); } + + m_clock.Discontinuity(DVD_MSEC_TO_TIME(starttime)); } // make sure application know our info @@ -1372,7 +1364,6 @@ void CVideoPlayer::Process() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = true; - mode.flush = true; mode.accurate = true; mode.sync = true; m_messenger.Put(new CDVDMsgPlayerSeek(mode)); @@ -1387,6 +1378,9 @@ void CVideoPlayer::Process() continue; } + // check if in a cut or commercial break that should be automatically skipped + CheckAutoSceneSkip(); + // handle messages send to this thread, like seek or demuxer reset requests HandleMessages(); @@ -1627,9 +1621,6 @@ void CVideoPlayer::Process() // process the packet ProcessPacket(pStream, pPacket); - // check if in a cut or commercial break that should be automatically skipped - CheckAutoSceneSkip(); - // update the player info for streams if (m_player_status_timer.IsTimePast()) { @@ -1727,24 +1718,13 @@ void CVideoPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket) /* * If CheckSceneSkip() returns true then demux point is inside an EDL cut and the packets are dropped. - * If not inside a hard cut, but the demux point has reached an EDL mute section then trigger the - * AUDIO_SILENCE state. The AUDIO_SILENCE state is reverted as soon as the demux point is outside - * of any EDL section while EDL mute is still active. */ CEdl::Cut cut; if (CheckSceneSkip(m_CurrentAudio)) drop = true; - else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE // Inside EDL mute - && !m_EdlAutoSkipMarkers.mute) // Mute not already triggered - { - m_VideoPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, true)); - m_EdlAutoSkipMarkers.mute = true; - } - else if (!m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) // Outside of any EDL - && m_EdlAutoSkipMarkers.mute) // But the mute hasn't been removed yet + else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE) { - m_VideoPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, false)); - m_EdlAutoSkipMarkers.mute = false; + drop = true; } m_VideoPlayerAudio->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop)); @@ -1951,7 +1931,7 @@ void CVideoPlayer::HandlePlaySpeed() { CLog::Log(LOGDEBUG, "Stream stalled, start buffering. Audio: %d - Video: %d", m_VideoPlayerAudio->GetLevel(),m_VideoPlayerVideo->GetLevel()); - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); } } else @@ -1967,11 +1947,10 @@ void CVideoPlayer::HandlePlaySpeed() m_VideoPlayerAudio->GetLevel() == 0) { CLog::Log(LOGDEBUG,"CVideoPlayer::HandlePlaySpeed - audio stream stalled, triggering re-sync"); - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = false; - mode.flush = true; mode.accurate = true; mode.sync = true; m_messenger.Put(new CDVDMsgPlayerSeek(mode)); @@ -2076,6 +2055,7 @@ void CVideoPlayer::HandlePlaySpeed() m_VideoPlayerAudio->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1); m_VideoPlayerVideo->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1); SetCaching(CACHESTATE_DONE); + UpdatePlayState(0); m_syncTimer.Set(3000); } @@ -2089,7 +2069,7 @@ void CVideoPlayer::HandlePlaySpeed() m_VideoPlayerVideo->IsStalled()) { CLog::Log(LOGWARNING, "VideoPlayer::Sync - stream player video does not start, flushing buffers"); - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); } } } @@ -2164,7 +2144,6 @@ void CVideoPlayer::HandlePlaySpeed() CDVDMsgPlayerSeek::CMode mode; mode.time = iTime; mode.backward = (GetPlaySpeed() < 0); - mode.flush = true; mode.accurate = false; mode.restore = false; mode.trickplay = true; @@ -2347,86 +2326,71 @@ void CVideoPlayer::CheckAutoSceneSkip() if (!m_Edl.HasCut()) return; - // Check that there is an audio and video stream. - if(m_CurrentAudio.id < 0 || - m_CurrentVideo.id < 0) + if((m_CurrentAudio.id < 0 || m_CurrentAudio.syncState != IDVDStreamPlayer::SYNC_INSYNC) || + (m_CurrentVideo.id < 0 || m_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_INSYNC)) return; - // If there is a startpts defined for either the audio or video stream then VideoPlayer is still // still decoding frames to get to the previously requested seek point. - if (m_CurrentAudio.inited == false || m_CurrentVideo.inited == false) return; - if (m_CurrentAudio.dts == DVD_NOPTS_VALUE || - m_CurrentVideo.dts == DVD_NOPTS_VALUE) - return; - - const int64_t clock = m_omxplayer_mode ? GetTime() : DVD_TIME_TO_MSEC(std::min(m_CurrentAudio.dts, m_CurrentVideo.dts) + m_offset_pts); + const int64_t clock = GetTime(); + int lastPos = m_Edl.GetLastQueryTime(); CEdl::Cut cut; if (!m_Edl.InCut(clock, &cut)) return; - if (cut.action == CEdl::CUT && - !(cut.end == m_EdlAutoSkipMarkers.cut || cut.start == m_EdlAutoSkipMarkers.cut)) // To prevent looping if same cut again + if (cut.action == CEdl::CUT) { - CLog::Log(LOGDEBUG, "%s - Clock in EDL cut [%s - %s]: %s. Automatically skipping over.", - __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), - CEdl::MillisecondsToTimeString(cut.end).c_str(), CEdl::MillisecondsToTimeString(clock).c_str()); - - //Seeking either goes to the start or the end of the cut depending on the play direction. - int seek = GetPlaySpeed() >= 0 ? cut.end : cut.start; - - // Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. - CDVDMsgPlayerSeek::CMode mode; - mode.time = seek; - mode.backward = true; - mode.flush = false; - mode.accurate = false; - mode.restore = true; - mode.trickplay = false; - mode.sync = true; - m_messenger.Put(new CDVDMsgPlayerSeek(mode)); - - // Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping - // if there was an error with seeking and it landed somewhere unexpected, perhaps back in the - // cut. The cut automatic skip marker is reset every 500ms allowing another attempt at the seek. - m_EdlAutoSkipMarkers.cut = GetPlaySpeed() >= 0 ? cut.end : cut.start; - } - else if (cut.action == CEdl::COMM_BREAK && GetPlaySpeed() >= 0 && - cut.start > m_EdlAutoSkipMarkers.commbreak_end) - { - std::string strTimeString = StringUtils::SecondsToTimeString((cut.end - cut.start) / 1000, TIME_FORMAT_MM_SS); - CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString); - - if (m_SkipCommercials) + if ((GetPlaySpeed() > 0 && clock < cut.end - 1000) || + (GetPlaySpeed() < 0 && clock < cut.start + 1000)) { - CLog::Log(LOGDEBUG, "%s - Clock in commercial break [%s - %s]: %s. Automatically skipping to end of commercial break (only done once per break)", - __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), CEdl::MillisecondsToTimeString(cut.end).c_str(), - CEdl::MillisecondsToTimeString(clock).c_str()); + CLog::Log(LOGDEBUG, "%s - Clock in EDL cut [%s - %s]: %s. Automatically skipping over.", + __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), + CEdl::MillisecondsToTimeString(cut.end).c_str(), CEdl::MillisecondsToTimeString(clock).c_str()); + + //Seeking either goes to the start or the end of the cut depending on the play direction. + int seek = GetPlaySpeed() >= 0 ? cut.end : cut.start; - // Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. CDVDMsgPlayerSeek::CMode mode; - mode.time = cut.end + 1; + mode.time = seek; mode.backward = true; - mode.flush = false; - mode.accurate = false; + mode.accurate = true; mode.restore = true; mode.trickplay = false; mode.sync = true; m_messenger.Put(new CDVDMsgPlayerSeek(mode)); } + } + else if (cut.action == CEdl::COMM_BREAK) + { + // marker for commbrak may be inaccurate. allow user to skip into break from the back + if (GetPlaySpeed() >= 0 && lastPos <= cut.start && clock < cut.end - 1000) + { + std::string strTimeString = StringUtils::SecondsToTimeString((cut.end - cut.start) / 1000, TIME_FORMAT_MM_SS); + CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString); + + if (m_SkipCommercials) + { + CLog::Log(LOGDEBUG, "%s - Clock in commercial break [%s - %s]: %s. Automatically skipping to end of commercial break", + __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), + CEdl::MillisecondsToTimeString(cut.end).c_str(), + CEdl::MillisecondsToTimeString(clock).c_str()); - // Each commercial break is only skipped once so poorly detected commercial breaks can be - // manually re-entered. Start and end are recorded to prevent looping and to allow seeking back - // to the start of the commercial break if incorrectly flagged. - m_EdlAutoSkipMarkers.commbreak_start = cut.start; - m_EdlAutoSkipMarkers.commbreak_end = cut.end; - m_EdlAutoSkipMarkers.seek_to_start = true; // Allow backwards Seek() to go directly to the start + CDVDMsgPlayerSeek::CMode mode; + mode.time = cut.end; + mode.backward = true; + mode.accurate = true; + mode.restore = false; + mode.trickplay = false; + mode.sync = true; + m_messenger.Put(new CDVDMsgPlayerSeek(mode)); + } + } } } @@ -2559,8 +2523,7 @@ void CVideoPlayer::HandleMessages() if (!msg.GetTrickPlay()) { g_infoManager.SetDisplayAfterSeek(100000); - if(msg.GetFlush()) - SetCaching(CACHESTATE_FLUSH); + SetCaching(CACHESTATE_FLUSH); } double start = DVD_NOPTS_VALUE; @@ -2596,7 +2559,7 @@ void CVideoPlayer::HandleMessages() m_State.dts = start; m_State.lastSeek = m_clock.GetAbsoluteClock(); - FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync()); + FlushBuffers(start, msg.GetAccurate(), msg.GetSync()); } else if (m_pDemuxer) { @@ -2607,7 +2570,7 @@ void CVideoPlayer::HandleMessages() m_State.dts = start; - FlushBuffers(false, start, false, true); + FlushBuffers(start, false, true); if (m_playSpeed != DVD_PLAYSPEED_PAUSE) { SetPlaySpeed(DVD_PLAYSPEED_NORMAL); @@ -2639,7 +2602,7 @@ void CVideoPlayer::HandleMessages() // This should always be the case. if(m_pDemuxer && m_pDemuxer->SeekChapter(msg.GetChapter(), &start)) { - FlushBuffers(false, start, true); + FlushBuffers(start, true, true); offset = DVD_TIME_TO_MSEC(start) - beforeSeek; m_callback.OnPlayBackSeekChapter(msg.GetChapter()); } @@ -2675,7 +2638,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = true; - mode.flush = true; mode.accurate = true; mode.trickplay = true; mode.sync = true; @@ -2691,7 +2653,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = true; - mode.flush = true; mode.accurate = true; mode.trickplay = true; mode.sync = true; @@ -2716,7 +2677,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = true; - mode.flush = true; mode.accurate = true; mode.trickplay = true; mode.sync = true; @@ -2730,7 +2690,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = true; - mode.flush = true; mode.accurate = true; mode.trickplay = true; mode.sync = true; @@ -2793,7 +2752,7 @@ void CVideoPlayer::HandleMessages() } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) { - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); } else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED)) { @@ -2839,7 +2798,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = iTime; mode.backward = m_playSpeed < 0; - mode.flush = true; mode.accurate = false; mode.trickplay = true; mode.sync = true; @@ -2858,7 +2816,6 @@ void CVideoPlayer::HandleMessages() CDVDMsgPlayerSeek::CMode mode; mode.time = (int)GetTime(); mode.backward = (speed < 0); - mode.flush = true; mode.accurate = true; mode.restore = false; mode.trickplay = true; @@ -2887,7 +2844,7 @@ void CVideoPlayer::HandleMessages() else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) == 0) { - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); CDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream); //! @todo find a better solution for the "otherStreamHack" //! a stream is not supposed to be terminated before demuxer @@ -2914,7 +2871,7 @@ void CVideoPlayer::HandleMessages() else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT) == 0) { - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); CDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream); if (input && input->IsOtherStreamHack()) { @@ -2947,7 +2904,7 @@ void CVideoPlayer::HandleMessages() if (!bShowPreview) { g_infoManager.SetDisplayAfterSeek(100000); - FlushBuffers(false); + FlushBuffers(DVD_NOPTS_VALUE, true, true); if (input->IsOtherStreamHack()) { CloseDemuxer(); @@ -3185,52 +3142,6 @@ void CVideoPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride) } bool restore = true; - if (m_Edl.HasCut()) - { - /* - * Alter the standard seek position based on whether any commercial breaks have been - * automatically skipped. - */ - const int clock = DVD_TIME_TO_MSEC(m_clock.GetClock()); - /* - * If a large backwards seek occurs within 10 seconds of the end of the last automated - * commercial skip, then seek back to the start of the commercial break under the assumption - * it was flagged incorrectly. 10 seconds grace period is allowed in case the watcher has to - * fumble around finding the remote. Only happens once per commercial break. - * - * Small skip does not trigger this in case the start of the commercial break was in fact fine - * but it skipped too far into the program. In that case small skip backwards behaves as normal. - */ - if (!bPlus && bLargeStep && - m_EdlAutoSkipMarkers.seek_to_start && - clock >= m_EdlAutoSkipMarkers.commbreak_end && - clock <= m_EdlAutoSkipMarkers.commbreak_end + 10*1000) // Only if within 10 seconds of the end (in msec) - { - CLog::Log(LOGDEBUG, "%s - Seeking back to start of commercial break [%s - %s] as large backwards skip activated within 10 seconds of the automatic commercial skip (only done once per break).", - __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(), - CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str()); - seekTarget = m_EdlAutoSkipMarkers.commbreak_start; - restore = false; - m_EdlAutoSkipMarkers.seek_to_start = false; // So this will only happen within the 10 second grace period once. - } - /* - * If big skip forward within the last "reverted" commercial break, seek to the end of the - * commercial break under the assumption that the break was incorrectly flagged and playback has - * now reached the actual start of the commercial break. Assume that the end is flagged more - * correctly than the landing point for a standard big skip (ends seem to be flagged more - * accurately than the start). - */ - else if (bPlus && bLargeStep && - clock >= m_EdlAutoSkipMarkers.commbreak_start && - clock <= m_EdlAutoSkipMarkers.commbreak_end) - { - CLog::Log(LOGDEBUG, "%s - Seeking to end of previously skipped commercial break [%s - %s] as big forwards skip activated within the break.", - __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(), - CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str()); - seekTarget = m_EdlAutoSkipMarkers.commbreak_end; - restore = false; - } - } int64_t time = GetTime(); if(g_application.CurrentFileItem().IsStack() && @@ -3245,7 +3156,6 @@ void CVideoPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride) CDVDMsgPlayerSeek::CMode mode; mode.time = (int)seekTarget; mode.backward = !bPlus; - mode.flush = true; mode.accurate = false; mode.restore = restore; mode.trickplay = false; @@ -3280,7 +3190,6 @@ bool CVideoPlayer::SeekScene(bool bPlus) CDVDMsgPlayerSeek::CMode mode; mode.time = iScenemarker; mode.backward = !bPlus; - mode.flush = true; mode.accurate = false; mode.restore = false; mode.trickplay = false; @@ -3577,7 +3486,6 @@ void CVideoPlayer::SeekTime(int64_t iTime) CDVDMsgPlayerSeek::CMode mode; mode.time = (int)iTime; mode.backward = true; - mode.flush = true; mode.accurate = true; mode.trickplay = false; mode.sync = true; @@ -3595,7 +3503,6 @@ bool CVideoPlayer::SeekTimeRelative(int64_t iTime) mode.time = (int)iTime; mode.relative = true; mode.backward = (iTime < 0) ? true : false; - mode.flush = true; mode.accurate = false; mode.trickplay = false; mode.sync = true; @@ -4027,7 +3934,7 @@ bool CVideoPlayer::CloseStream(CCurrentStream& current, bool bWaitForBuffers) return true; } -void CVideoPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync) +void CVideoPlayer::FlushBuffers(double pts, bool accurate, bool sync) { CLog::Log(LOGDEBUG, "CVideoPlayer::FlushBuffers - flushing buffers"); @@ -4068,63 +3975,45 @@ void CVideoPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool syn m_CurrentRadioRDS.startpts = startpts; m_CurrentRadioRDS.packets = 0; - if (queued) - { - m_VideoPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET)); - m_VideoPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET)); - m_VideoPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET)); - m_VideoPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET)); - m_VideoPlayerRadioRDS->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET)); + m_VideoPlayerAudio->Flush(sync); + m_VideoPlayerVideo->Flush(sync); + m_VideoPlayerSubtitle->Flush(); + m_VideoPlayerTeletext->Flush(); + m_VideoPlayerRadioRDS->Flush(); + + // clear subtitle and menu overlays + m_overlayContainer.Clear(); - CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(10*1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO); + if(m_playSpeed == DVD_PLAYSPEED_NORMAL || + m_playSpeed == DVD_PLAYSPEED_PAUSE) + { + // make sure players are properly flushed, should put them in stalled state + CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO); m_VideoPlayerAudio->SendMessage(msg->Acquire(), 1); m_VideoPlayerVideo->SendMessage(msg->Acquire(), 1); msg->Wait(m_bStop, 0); msg->Release(); - } - else - { - m_VideoPlayerAudio->Flush(sync); - m_VideoPlayerVideo->Flush(sync); - m_VideoPlayerSubtitle->Flush(); - m_VideoPlayerTeletext->Flush(); - m_VideoPlayerRadioRDS->Flush(); - // clear subtitle and menu overlays - m_overlayContainer.Clear(); + // purge any pending PLAYER_STARTED messages + m_messenger.Flush(CDVDMsg::PLAYER_STARTED); - if(m_playSpeed == DVD_PLAYSPEED_NORMAL - || m_playSpeed == DVD_PLAYSPEED_PAUSE) + // we should now wait for init cache + SetCaching(CACHESTATE_FLUSH); + if (sync) { - // make sure players are properly flushed, should put them in stalled state - CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO); - m_VideoPlayerAudio->SendMessage(msg->Acquire(), 1); - m_VideoPlayerVideo->SendMessage(msg->Acquire(), 1); - msg->Wait(m_bStop, 0); - msg->Release(); - - // purge any pending PLAYER_STARTED messages - m_messenger.Flush(CDVDMsg::PLAYER_STARTED); - - // we should now wait for init cache - SetCaching(CACHESTATE_FLUSH); - if (sync) - { - m_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING; - m_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING; - } + m_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING; + m_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING; } - - if(pts != DVD_NOPTS_VALUE && sync) - m_clock.Discontinuity(pts); - UpdatePlayState(0); } + if(pts != DVD_NOPTS_VALUE && sync) + m_clock.Discontinuity(pts); + UpdatePlayState(0); + if (m_omxplayer_mode) { m_OmxPlayerState.av_clock.OMXFlush(); - if (!queued) - m_OmxPlayerState.av_clock.OMXStop(); + m_OmxPlayerState.av_clock.OMXStop(); m_OmxPlayerState.av_clock.OMXPause(); m_OmxPlayerState.av_clock.OMXMediaTime(0.0); } @@ -4315,7 +4204,7 @@ int CVideoPlayer::OnDVDNavResult(void* pData, int iMessage) else { bool sync = !IsInMenuInternal(); - FlushBuffers(false, DVD_NOPTS_VALUE, false, sync); + FlushBuffers(DVD_NOPTS_VALUE, false, sync); m_dvd.syncClock = true; m_dvd.state = DVDSTATE_NORMAL; if (m_pDemuxer) @@ -4572,7 +4461,6 @@ bool CVideoPlayer::OnAction(const CAction &action) CDVDMsgPlayerSeek::CMode mode; mode.time = cut.end + 1; mode.backward = false; - mode.flush = true; mode.accurate = false; mode.restore = true; mode.trickplay = false; @@ -4612,7 +4500,6 @@ bool CVideoPlayer::OnAction(const CAction &action) CDVDMsgPlayerSeek::CMode mode; mode.time = cut.start - 1; mode.backward = true; - mode.flush = true; mode.accurate = false; mode.restore = true; mode.trickplay = false; @@ -4627,7 +4514,6 @@ bool CVideoPlayer::OnAction(const CAction &action) CDVDMsgPlayerSeek::CMode mode; mode.time = 0; mode.backward = true; - mode.flush = true; mode.accurate = false; mode.restore = true; mode.trickplay = false; diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h index 1cc1abbf5a..a19f3d1d7f 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.h +++ b/xbmc/cores/VideoPlayer/VideoPlayer.h @@ -463,8 +463,7 @@ protected: double GetQueueTime(); bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset); - - void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true); + void FlushBuffers(double pts, bool accurate, bool sync); void HandleMessages(); void HandlePlaySpeed(); @@ -586,25 +585,6 @@ protected: CEdl m_Edl; bool m_SkipCommercials; - struct SEdlAutoSkipMarkers { - - void Clear() - { - cut = -1; - commbreak_start = -1; - commbreak_end = -1; - seek_to_start = false; - mute = false; - } - - int cut; // last automatically skipped EDL cut seek position - int commbreak_start; // start time of the last commercial break automatically skipped - int commbreak_end; // end time of the last commercial break automatically skipped - bool seek_to_start; // whether seeking can go back to the start of a previously skipped break - bool mute; // whether EDL mute is on - - } m_EdlAutoSkipMarkers; - CPlayerOptions m_PlayerOptions; bool m_HasVideo; diff --git a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp index a40c6191e5..9a5164eae9 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp @@ -70,7 +70,6 @@ CVideoPlayerAudio::CVideoPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent m_stalled = true; m_paused = false; m_syncState = IDVDStreamPlayer::SYNC_STARTING; - m_silence = false; m_synctype = SYNC_DISCON; m_setsynctype = SYNC_DISCON; m_prevsynctype = -1; @@ -151,7 +150,6 @@ void CVideoPlayerAudio::OpenStream(CDVDStreamInfo &hints, CDVDAudioCodec* codec) m_prevsynctype = -1; m_prevskipped = false; - m_silence = false; m_maxspeedadjust = 5.0; @@ -346,12 +344,6 @@ void CVideoPlayerAudio::Process() } m_speed = speed; } - else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE)) - { - m_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value; - CLog::Log(LOGDEBUG, "CVideoPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, %d)" - , m_audioClock, m_silence); - } else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE)) { CDVDMsgAudioCodecChange* msg(static_cast<CDVDMsgAudioCodecChange*>(pMsg)); @@ -458,14 +450,6 @@ void CVideoPlayerAudio::Process() m_messageParent.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE)); } - // Zero out the frame data if we are supposed to silence the audio - if (m_silence) - { - int size = audioframe.nb_frames * audioframe.framesize / audioframe.planes; - for (unsigned int i=0; i<audioframe.planes; i++) - memset(audioframe.data[i], 0, size); - } - SetSyncType(audioframe.passthrough); if (!bPacketDrop) diff --git a/xbmc/cores/VideoPlayer/VideoPlayerAudio.h b/xbmc/cores/VideoPlayer/VideoPlayerAudio.h index ca1da99a23..3345fcf49e 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayerAudio.h +++ b/xbmc/cores/VideoPlayer/VideoPlayerAudio.h @@ -95,7 +95,6 @@ protected: int m_speed; bool m_stalled; - bool m_silence; bool m_paused; IDVDStreamPlayer::ESyncState m_syncState; XbmcThreads::EndTime m_syncTimer; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp index d8674c8578..292f07b9b6 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp @@ -21,26 +21,58 @@ #include "RendererAML.h" #if defined(HAS_LIBAMCODEC) -#include "cores/IPlayer.h" -#include "windowing/egl/EGLWrapper.h" #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h" #include "cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h" #include "utils/log.h" -#include "utils/GLUtils.h" #include "utils/SysfsUtils.h" #include "settings/MediaSettings.h" #include "windowing/WindowingFactory.h" #include "cores/VideoPlayer/VideoRenderers/RenderCapture.h" +#include "settings/AdvancedSettings.h" CRendererAML::CRendererAML() + : m_prevVPts(-1) + , m_bConfigured(false) + , m_iRenderBuffer(0) { - m_prevPts = -1; } CRendererAML::~CRendererAML() { } +bool CRendererAML::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation) +{ + m_sourceWidth = width; + m_sourceHeight = height; + m_renderOrientation = orientation; + + // Save the flags. + m_iFlags = flags; + m_format = format; + + // Calculate the input frame aspect ratio. + CalculateFrameAspectRatio(d_width, d_height); + SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode); + ManageRenderArea(); + + m_bConfigured = true; + + for (int i = 0 ; i < m_numRenderBuffers ; ++i) + m_buffers[i].hwDec = 0; + + return true; +} + +CRenderInfo CRendererAML::GetRenderInfo() +{ + CRenderInfo info; + info.formats.push_back(RENDER_FMT_BYPASS); + info.max_buffer_size = m_numRenderBuffers; + info.optimal_buffer_size = m_numRenderBuffers; + return info; +} + bool CRendererAML::RenderCapture(CRenderCapture* capture) { capture->BeginRender(); @@ -48,27 +80,50 @@ bool CRendererAML::RenderCapture(CRenderCapture* capture) return true; } +int CRendererAML::GetImage(YV12Image *image, int source, bool readonly) +{ + if (image == nullptr) + return -1; + + /* take next available buffer */ + if (source == -1) + source = (m_iRenderBuffer + 1) % m_numRenderBuffers; + + return source; +} + void CRendererAML::AddVideoPictureHW(DVDVideoPicture &picture, int index) { - YUVBUFFER &buf = m_buffers[index]; + BUFFER &buf = m_buffers[index]; if (picture.amlcodec) buf.hwDec = picture.amlcodec->Retain(); } void CRendererAML::ReleaseBuffer(int idx) { - YUVBUFFER &buf = m_buffers[idx]; + BUFFER &buf = m_buffers[idx]; if (buf.hwDec) { CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(buf.hwDec); - SAFE_RELEASE(amli); + if (amli) + { + CAMLCodec *amlcodec; + if (!amli->IsRendered() && (amlcodec = amli->getAmlCodec())) + amlcodec->ReleaseFrame(amli->GetBufferIndex(), true); + SAFE_RELEASE(amli); + } buf.hwDec = NULL; } } -int CRendererAML::GetImageHook(YV12Image *image, int source, bool readonly) +void CRendererAML::FlipPage(int source) { - return source; + if( source >= 0 && source < m_numRenderBuffers ) + m_iRenderBuffer = source; + else + m_iRenderBuffer = (m_iRenderBuffer + 1) % m_numRenderBuffers; + + return; } bool CRendererAML::IsGuiLayer() @@ -104,37 +159,30 @@ EINTERLACEMETHOD CRendererAML::AutoInterlaceMethod() return VS_INTERLACEMETHOD_NONE; } -bool CRendererAML::LoadShadersHook() +void CRendererAML::Reset() { - CLog::Log(LOGNOTICE, "GL: Using AML render method"); - m_textureTarget = GL_TEXTURE_2D; - m_renderMethod = RENDER_BYPASS; - return false; + m_prevVPts = -1; } -bool CRendererAML::RenderHook(int index) -{ - return true;// nothing to be done for aml -} - -bool CRendererAML::RenderUpdateVideoHook(bool clear, DWORD flags, DWORD alpha) +void CRendererAML::RenderUpdate(bool clear, DWORD flags, DWORD alpha) { ManageRenderArea(); - CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iYV12RenderBuffer].hwDec); - if (amli && amli->GetOmxPts() != m_prevPts) - { - m_prevPts = amli->GetOmxPts(); - SysfsUtils::SetInt("/sys/module/amvideo/parameters/omx_pts", amli->GetOmxPts()); + CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iRenderBuffer].hwDec); + CAMLCodec *amlcodec = amli ? amli->getAmlCodec() : 0; - CAMLCodec *amlcodec = amli->getAmlCodec(); - if (amlcodec) + if(amlcodec) + { + int pts = amli->GetOmxPts(); + if (pts != m_prevVPts) + { + amlcodec->ReleaseFrame(amli->GetBufferIndex()); amlcodec->SetVideoRect(m_sourceRect, m_destRect); + amli->SetRendered(); + m_prevVPts = pts; + } } - - usleep(10000); - - return true; + CAMLCodec::PollFrame(); } #endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h index 828f584a94..cd68401953 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h @@ -24,17 +24,29 @@ #if defined(HAS_LIBAMCODEC) -#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" +#include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h" -class CRendererAML : public CLinuxRendererGLES +class CRendererAML : public CBaseRenderer { public: CRendererAML(); virtual ~CRendererAML(); - + virtual bool RenderCapture(CRenderCapture* capture); virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index); virtual void ReleaseBuffer(int idx); + virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation); + virtual bool IsConfigured(){ return m_bConfigured; }; + virtual CRenderInfo GetRenderInfo(); + virtual int GetImage(YV12Image *image, int source = -1, bool readonly = false); + virtual void ReleaseImage(int source, bool preserve = false){}; + virtual void FlipPage(int source); + virtual void PreInit(){}; + virtual void UnInit(){}; + virtual void Reset(); + virtual void Update(){}; + virtual void RenderUpdate(bool clear, unsigned int flags = 0, unsigned int alpha = 255); + virtual bool SupportsMultiPassRendering(){ return false; }; // Player functions virtual bool IsGuiLayer(); @@ -47,16 +59,19 @@ public: virtual EINTERLACEMETHOD AutoInterlaceMethod(); -protected: +private: + + int m_iRenderBuffer; + static const int m_numRenderBuffers = 4; - // hooks for hw dec renderer - virtual bool LoadShadersHook(); - virtual bool RenderHook(int index); - virtual int GetImageHook(YV12Image *image, int source = AUTOSOURCE, bool readonly = false); - virtual bool RenderUpdateVideoHook(bool clear, DWORD flags = 0, DWORD alpha = 255); + struct BUFFER + { + void *hwDec; + int duration; + } m_buffers[m_numRenderBuffers]; -private: - int m_prevPts; + int m_prevVPts; + bool m_bConfigured; }; #endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp index 2f9ed26a48..31a8e39d37 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp @@ -192,6 +192,13 @@ CLinuxRendererGL::~CLinuxRendererGL() delete m_pYUVShader; m_pYUVShader = NULL; } + + if (m_pVideoFilterShader) + { + m_pVideoFilterShader->Free(); + delete m_pVideoFilterShader; + m_pVideoFilterShader = NULL; + } } bool CLinuxRendererGL::ValidateRenderer() diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp index 1d64eb4110..d9afae743a 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp @@ -151,14 +151,12 @@ COverlayQuadsDX::COverlayQuadsDX(ASS_Image* images, int width, int height) CLog::Log(LOGERROR, "%s - failed to create vertex buffer", __FUNCTION__); m_texture.Release(); } - else - g_Windowing.Register(this); + delete[] vt; } COverlayQuadsDX::~COverlayQuadsDX() { - g_Windowing.Unregister(this); } void COverlayQuadsDX::Render(SRenderState &state) @@ -166,6 +164,10 @@ void COverlayQuadsDX::Render(SRenderState &state) if (m_count == 0) return; + ID3D11Buffer* vertexBuffer = m_vertex.Get(); + if (vertexBuffer == nullptr) + return; + ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader(); @@ -188,7 +190,6 @@ void COverlayQuadsDX::Render(SRenderState &state) const unsigned stride = sizeof(Vertex); const unsigned offset = 0; - ID3D11Buffer* vertexBuffer = m_vertex.Get(); // Set the vertex buffer to active in the input assembler so it can be rendered. pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. @@ -206,18 +207,8 @@ void COverlayQuadsDX::Render(SRenderState &state) pGUIShader->RestoreBuffers(); } -void COverlayQuadsDX::OnDestroyDevice(bool fatal) -{ - // fatal means that we have no valid buffer anymore - // resetting m_count will cause no rendering - if (fatal) - m_count = 0; -} - - COverlayImageDX::~COverlayImageDX() { - g_Windowing.Unregister(this); } COverlayImageDX::COverlayImageDX(CDVDOverlayImage* o) @@ -283,7 +274,6 @@ COverlayImageDX::COverlayImageDX(CDVDOverlayImage* o) m_width = (float)o->width; m_height = (float)o->height; } - g_Windowing.Register(this); } COverlayImageDX::COverlayImageDX(CDVDOverlaySpu* o) @@ -305,8 +295,6 @@ COverlayImageDX::COverlayImageDX(CDVDOverlaySpu* o) m_y = (float)(min_y + o->y); m_width = (float)(max_x - min_x); m_height = (float)(max_y - min_y); - - g_Windowing.Register(this); } void COverlayImageDX::Load(uint32_t* rgba, int width, int height, int stride) @@ -344,7 +332,8 @@ void COverlayImageDX::Load(uint32_t* rgba, int width, int height, int stride) void COverlayImageDX::Render(SRenderState &state) { - if (m_type == TYPE_NONE) + ID3D11Buffer* vertexBuffer = m_vertex.Get(); + if (vertexBuffer == nullptr) return; ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); @@ -371,7 +360,6 @@ void COverlayImageDX::Render(SRenderState &state) const unsigned stride = m_vertex.GetStride(); const unsigned offset = 0; - ID3D11Buffer* vertexBuffer = m_vertex.Get(); pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); pContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); @@ -387,12 +375,4 @@ void COverlayImageDX::Render(SRenderState &state) pGUIShader->RestoreBuffers(); } -void OVERLAY::COverlayImageDX::OnDestroyDevice(bool fatal) -{ - // fatal means that we have no valid texture and buffer anymore - // resetting m_type will cause no rendering - if (fatal) - m_type = TYPE_NONE; -} - #endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h index 23e40839bd..f5fd62bf3c 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h @@ -35,15 +35,12 @@ namespace OVERLAY { class COverlayQuadsDX : public COverlay - , public ID3DResource { public: COverlayQuadsDX(ASS_Image* images, int width, int height); virtual ~COverlayQuadsDX(); void Render(SRenderState& state); - void OnCreateDevice() override {} - void OnDestroyDevice(bool fatal) override; int m_count; DWORD m_fvf; @@ -53,7 +50,6 @@ namespace OVERLAY { class COverlayImageDX : public COverlay - , public ID3DResource { public: COverlayImageDX(CDVDOverlayImage* o); @@ -62,8 +58,6 @@ namespace OVERLAY { void Load(uint32_t* rgba, int width, int height, int stride); void Render(SRenderState& state); - void OnCreateDevice() override {} - void OnDestroyDevice(bool fatal) override; DWORD m_fvf; CD3DTexture m_texture; diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp index 920ac4ab75..e399556582 100644 --- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp +++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp @@ -65,7 +65,7 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) { AVCodec* pCodec = NULL; - if (hints.codec == AV_CODEC_ID_DTS && g_RBP.RasberryPiVersion() > 1) + if (hints.codec == AV_CODEC_ID_DTS && g_RBP.RaspberryPiVersion() > 1) pCodec = avcodec_find_decoder_by_name("dcadec"); if (!pCodec) diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp index 968724e81d..890d91c5cf 100644 --- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp +++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp @@ -85,7 +85,6 @@ OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent, CPr m_messageQueue.SetMaxTimeSize(8.0); m_passthrough = false; - m_silence = false; m_flush = false; } @@ -134,7 +133,6 @@ void OMXPlayerAudio::OpenStream(CDVDStreamInfo &hints, COMXAudioCodecOMX *codec) m_speed = DVD_PLAYSPEED_NORMAL; m_audioClock = DVD_NOPTS_VALUE; - m_silence = false; m_syncState = IDVDStreamPlayer::SYNC_STARTING; m_flush = false; m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; @@ -277,12 +275,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay) if(!bDropPacket) { - // Zero out the frame data if we are supposed to silence the audio - if(m_silence) - memset(decoded, 0x0, decoded_size); - ret = m_omxAudio.AddPackets(decoded, decoded_size, dts, pts, m_pAudioCodec->GetFrameSize(), settings_changed); - if(ret != decoded_size) { CLog::Log(LOGERROR, "error ret %d decoded_size %d\n", ret, decoded_size); @@ -316,9 +309,6 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay) if(!bDropPacket) { - if(m_silence) - memset(pkt->pData, 0x0, pkt->iSize); - m_omxAudio.AddPackets(pkt->pData, pkt->iSize, m_audioClock, m_audioClock, 0, settings_changed); } @@ -456,14 +446,6 @@ void OMXPlayerAudio::Process() CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_SETSPEED %d", m_speed); } } - else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE)) - { - m_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value; - if (m_silence) - CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 1)", m_audioClock); - else - CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 0)", m_audioClock); - } else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE)) { COMXMsgAudioCodecChange* msg(static_cast<COMXMsgAudioCodecChange*>(pMsg)); diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp index bd7974aeba..383ddb1606 100644 --- a/xbmc/dbwrappers/Database.cpp +++ b/xbmc/dbwrappers/Database.cpp @@ -574,7 +574,7 @@ bool CDatabase::Compress(bool bForce /* =true */) return true; } -void CDatabase::Interupt() +void CDatabase::Interrupt() { m_pDS->interrupt(); } diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h index 593a8eac47..cf4a795b31 100644 --- a/xbmc/dbwrappers/Database.h +++ b/xbmc/dbwrappers/Database.h @@ -78,7 +78,7 @@ public: bool IsOpen(); void Close(); bool Compress(bool bForce=true); - void Interupt(); + void Interrupt(); bool Open(const DatabaseSettings &db); diff --git a/xbmc/dialogs/GUIDialogFileBrowser.cpp b/xbmc/dialogs/GUIDialogFileBrowser.cpp index f6e002e016..f373d08ca1 100644 --- a/xbmc/dialogs/GUIDialogFileBrowser.cpp +++ b/xbmc/dialogs/GUIDialogFileBrowser.cpp @@ -653,12 +653,12 @@ bool CGUIDialogFileBrowser::ShowAndGetImage(const CFileItemList &items, const VE bool CGUIDialogFileBrowser::ShowAndGetImage(const VECSOURCES &shares, const std::string &heading, std::string &path) { - return ShowAndGetFile(shares, g_advancedSettings.m_pictureExtensions, heading, path, true); // true for use thumbs + return ShowAndGetFile(shares, g_advancedSettings.GetPictureExtensions(), heading, path, true); // true for use thumbs } bool CGUIDialogFileBrowser::ShowAndGetImageList(const VECSOURCES &shares, const std::string &heading, std::vector<std::string> &path) { - return ShowAndGetFileList(shares, g_advancedSettings.m_pictureExtensions, heading, path, true); // true for use thumbs + return ShowAndGetFileList(shares, g_advancedSettings.GetPictureExtensions(), heading, path, true); // true for use thumbs } bool CGUIDialogFileBrowser::ShowAndGetDirectory(const VECSOURCES &shares, const std::string &heading, std::string &path, bool bWriteOnly) diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 3416c204dc..af118e3865 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -573,7 +573,7 @@ int CEpg::Get(CFileItemList &results) const return results.Size() - iInitialSize; } -int CEpg::Get(CFileItemList &results, const EpgSearchFilter &filter) const +int CEpg::Get(CFileItemList &results, const CEpgSearchFilter &filter) const { int iInitialSize = results.Size(); @@ -584,7 +584,7 @@ int CEpg::Get(CFileItemList &results, const EpgSearchFilter &filter) const for (std::map<CDateTime, CEpgInfoTagPtr>::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it) { - if (filter.FilterEntry(*it->second)) + if (filter.FilterEntry(it->second)) results.Add(CFileItemPtr(new CFileItem(it->second))); } diff --git a/xbmc/epg/Epg.h b/xbmc/epg/Epg.h index 13eb8c0828..4c8099b9d0 100644 --- a/xbmc/epg/Epg.h +++ b/xbmc/epg/Epg.h @@ -233,7 +233,7 @@ namespace EPG * @param filter The filter to apply. * @return The amount of entries that were added. */ - int Get(CFileItemList &results, const EpgSearchFilter &filter) const; + int Get(CFileItemList &results, const CEpgSearchFilter &filter) const; /*! * @brief Persist this table in the database. diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index e922c76f74..15e1edb507 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -770,7 +770,7 @@ const CDateTime CEpgContainer::GetLastEPGDate(void) return returnValue; } -int CEpgContainer::GetEPGSearch(CFileItemList &results, const EpgSearchFilter &filter) +int CEpgContainer::GetEPGSearch(CFileItemList &results, const CEpgSearchFilter &filter) { int iInitialSize = results.Size(); @@ -782,8 +782,8 @@ int CEpgContainer::GetEPGSearch(CFileItemList &results, const EpgSearchFilter &f } /* remove duplicate entries */ - if (filter.m_bPreventRepeats) - EpgSearchFilter::RemoveDuplicates(results); + if (filter.ShouldRemoveDuplicates()) + filter.RemoveDuplicates(results); return results.Size() - iInitialSize; } diff --git a/xbmc/epg/EpgContainer.h b/xbmc/epg/EpgContainer.h index 8faec15a29..2ad49122c2 100644 --- a/xbmc/epg/EpgContainer.h +++ b/xbmc/epg/EpgContainer.h @@ -131,7 +131,7 @@ namespace EPG * @param filter The filter to apply. * @return The amount of entries that were added. */ - int GetEPGSearch(CFileItemList &results, const EpgSearchFilter &filter); + int GetEPGSearch(CFileItemList &results, const CEpgSearchFilter &filter); /*! * @brief Get the start time of the first entry. diff --git a/xbmc/epg/EpgSearchFilter.cpp b/xbmc/epg/EpgSearchFilter.cpp index f87d3e4618..3b39efd5e2 100644 --- a/xbmc/epg/EpgSearchFilter.cpp +++ b/xbmc/epg/EpgSearchFilter.cpp @@ -33,9 +33,15 @@ using namespace EPG; using namespace PVR; -void EpgSearchFilter::Reset() + +CEpgSearchFilter::CEpgSearchFilter() +{ + Reset(); +} + +void CEpgSearchFilter::Reset() { - m_strSearchTerm = ""; + m_strSearchTerm.clear(); m_bIsCaseSensitive = false; m_bSearchInDescription = false; m_iGenreType = EPG_SEARCH_UNSET; @@ -45,86 +51,98 @@ void EpgSearchFilter::Reset() m_startDateTime.SetFromUTCDateTime(g_EpgContainer.GetFirstEPGDate()); m_endDateTime.SetFromUTCDateTime(g_EpgContainer.GetLastEPGDate()); m_bIncludeUnknownGenres = false; - m_bPreventRepeats = false; + m_bRemoveDuplicates = false; /* pvr specific filters */ + m_bIsRadio = false; m_iChannelNumber = EPG_SEARCH_UNSET; - m_bFTAOnly = false; + m_bFreeToAirOnly = false; m_iChannelGroup = EPG_SEARCH_UNSET; m_bIgnorePresentTimers = true; m_bIgnorePresentRecordings = true; - m_iUniqueBroadcastId = 0; + m_iUniqueBroadcastId = EPG_TAG_INVALID_UID; } -bool EpgSearchFilter::MatchGenre(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchGenre(const CEpgInfoTagPtr &tag) const { bool bReturn(true); if (m_iGenreType != EPG_SEARCH_UNSET) { - bool bIsUnknownGenre(tag.GenreType() > EPG_EVENT_CONTENTMASK_USERDEFINED || - tag.GenreType() < EPG_EVENT_CONTENTMASK_MOVIEDRAMA); - bReturn = ((m_bIncludeUnknownGenres && bIsUnknownGenre) || tag.GenreType() == m_iGenreType); + bool bIsUnknownGenre(tag->GenreType() > EPG_EVENT_CONTENTMASK_USERDEFINED || + tag->GenreType() < EPG_EVENT_CONTENTMASK_MOVIEDRAMA); + bReturn = ((m_bIncludeUnknownGenres && bIsUnknownGenre) || tag->GenreType() == m_iGenreType); } return bReturn; } -bool EpgSearchFilter::MatchDuration(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchDuration(const CEpgInfoTagPtr &tag) const { bool bReturn(true); if (m_iMinimumDuration != EPG_SEARCH_UNSET) - bReturn = (tag.GetDuration() > m_iMinimumDuration * 60); + bReturn = (tag->GetDuration() > m_iMinimumDuration * 60); if (bReturn && m_iMaximumDuration != EPG_SEARCH_UNSET) - bReturn = (tag.GetDuration() < m_iMaximumDuration * 60); + bReturn = (tag->GetDuration() < m_iMaximumDuration * 60); return bReturn; } -bool EpgSearchFilter::MatchStartAndEndTimes(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchStartAndEndTimes(const CEpgInfoTagPtr &tag) const { - return (tag.StartAsLocalTime() >= m_startDateTime && tag.EndAsLocalTime() <= m_endDateTime); + return (tag->StartAsLocalTime() >= m_startDateTime && tag->EndAsLocalTime() <= m_endDateTime); } -bool EpgSearchFilter::MatchSearchTerm(const CEpgInfoTag &tag) const +void CEpgSearchFilter::SetSearchPhrase(const std::string &strSearchPhrase) +{ + // match the exact phrase + m_strSearchTerm = "\""; + m_strSearchTerm.append(strSearchPhrase); + m_strSearchTerm.append("\""); +} + +bool CEpgSearchFilter::MatchSearchTerm(const CEpgInfoTagPtr &tag) const { bool bReturn(true); if (!m_strSearchTerm.empty()) { CTextSearch search(m_strSearchTerm, m_bIsCaseSensitive, SEARCH_DEFAULT_OR); - bReturn = search.Search(tag.Title()) || - search.Search(tag.PlotOutline()); + bReturn = search.Search(tag->Title()) || + search.Search(tag->PlotOutline()) || + (m_bSearchInDescription && search.Search(tag->Plot())); } return bReturn; } -bool EpgSearchFilter::MatchBroadcastId(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchBroadcastId(const CEpgInfoTagPtr &tag) const { - if (m_iUniqueBroadcastId != 0) - return (tag.UniqueBroadcastID() == m_iUniqueBroadcastId); + if (m_iUniqueBroadcastId != EPG_TAG_INVALID_UID) + return (tag->UniqueBroadcastID() == m_iUniqueBroadcastId); return true; } -bool EpgSearchFilter::FilterEntry(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::FilterEntry(const CEpgInfoTagPtr &tag) const { return (MatchGenre(tag) && MatchBroadcastId(tag) && MatchDuration(tag) && MatchStartAndEndTimes(tag) && - MatchSearchTerm(tag)) && - (!tag.HasPVRChannel() || + MatchSearchTerm(tag) && + MatchTimers(tag) && + MatchRecordings(tag)) && + (!tag->HasPVRChannel() || (MatchChannelType(tag) && MatchChannelNumber(tag) && MatchChannelGroup(tag) && - (!m_bFTAOnly || !tag.ChannelTag()->IsEncrypted()))); + MatchFreeToAir(tag))); } -int EpgSearchFilter::RemoveDuplicates(CFileItemList &results) +int CEpgSearchFilter::RemoveDuplicates(CFileItemList &results) { unsigned int iSize = results.Size(); @@ -158,12 +176,12 @@ int EpgSearchFilter::RemoveDuplicates(CFileItemList &results) return iSize; } -bool EpgSearchFilter::MatchChannelType(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchChannelType(const CEpgInfoTagPtr &tag) const { - return (g_PVRManager.IsStarted() && tag.ChannelTag()->IsRadio() == m_bIsRadio); + return (g_PVRManager.IsStarted() && tag->ChannelTag()->IsRadio() == m_bIsRadio); } -bool EpgSearchFilter::MatchChannelNumber(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchChannelNumber(const CEpgInfoTagPtr &tag) const { bool bReturn(true); @@ -173,21 +191,36 @@ bool EpgSearchFilter::MatchChannelNumber(const CEpgInfoTag &tag) const if (!group) group = CPVRManager::GetInstance().ChannelGroups()->GetGroupAllTV(); - bReturn = (m_iChannelNumber == (int) group->GetChannelNumber(tag.ChannelTag())); + bReturn = (m_iChannelNumber == (int) group->GetChannelNumber(tag->ChannelTag())); } return bReturn; } -bool EpgSearchFilter::MatchChannelGroup(const CEpgInfoTag &tag) const +bool CEpgSearchFilter::MatchChannelGroup(const CEpgInfoTagPtr &tag) const { bool bReturn(true); if (m_iChannelGroup != EPG_SEARCH_UNSET && g_PVRManager.IsStarted()) { CPVRChannelGroupPtr group = g_PVRChannelGroups->GetByIdFromAll(m_iChannelGroup); - bReturn = (group && group->IsGroupMember(tag.ChannelTag())); + bReturn = (group && group->IsGroupMember(tag->ChannelTag())); } return bReturn; } + +bool CEpgSearchFilter::MatchFreeToAir(const CEpgInfoTagPtr &tag) const +{ + return (!m_bFreeToAirOnly || !tag->ChannelTag()->IsEncrypted()); +} + +bool CEpgSearchFilter::MatchTimers(const CEpgInfoTagPtr &tag) const +{ + return (!m_bIgnorePresentTimers || !g_PVRTimers->GetTimerForEpgTag(tag)); +} + +bool CEpgSearchFilter::MatchRecordings(const CEpgInfoTagPtr &tag) const +{ + return (!m_bIgnorePresentRecordings || !g_PVRRecordings->GetRecordingForEpgTag(tag)); +} diff --git a/xbmc/epg/EpgSearchFilter.h b/xbmc/epg/EpgSearchFilter.h index c6132e61ae..85551afd8d 100644 --- a/xbmc/epg/EpgSearchFilter.h +++ b/xbmc/epg/EpgSearchFilter.h @@ -20,42 +20,108 @@ */ #include "XBDateTime.h" +#include "EpgTypes.h" class CFileItemList; namespace EPG { - class CEpgInfoTag; - #define EPG_SEARCH_UNSET (-1) /** Filter to apply with on a CEpgInfoTag */ - struct EpgSearchFilter + class CEpgSearchFilter { + public: + CEpgSearchFilter(); + /*! * @brief Clear this filter. */ - virtual void Reset(); + void Reset(); /*! * @brief Check if a tag will be filtered or not. * @param tag The tag to check. * @return True if this tag matches the filter, false if not. */ - virtual bool FilterEntry(const CEpgInfoTag &tag) const; - - virtual bool MatchGenre(const CEpgInfoTag &tag) const; - virtual bool MatchDuration(const CEpgInfoTag &tag) const; - virtual bool MatchStartAndEndTimes(const CEpgInfoTag &tag) const; - virtual bool MatchSearchTerm(const CEpgInfoTag &tag) const; - virtual bool MatchChannelNumber(const CEpgInfoTag &tag) const; - virtual bool MatchChannelGroup(const CEpgInfoTag &tag) const; - virtual bool MatchBroadcastId(const CEpgInfoTag &tag) const; - virtual bool MatchChannelType(const CEpgInfoTag &tag) const; + bool FilterEntry(const CEpgInfoTagPtr &tag) const; + /*! + * @brief remove duplicates from a list of epg tags. + * @param results the list of epg tags. + * @return the number of items in the list after removing duplicates. + */ static int RemoveDuplicates(CFileItemList &results); + const std::string &GetSearchTerm() const { return m_strSearchTerm; } + void SetSearchTerm(const std::string &strSearchTerm) { m_strSearchTerm = strSearchTerm; } + void SetSearchPhrase(const std::string &strSearchPhrase); + + bool IsCaseSensitive() const { return m_bIsCaseSensitive; } + void SetCaseSensitive(bool bIsCaseSensitive) { m_bIsCaseSensitive = bIsCaseSensitive; } + + bool ShouldSearchInDescription() const { return m_bSearchInDescription; } + void SetSearchInDescription(bool bSearchInDescription) {m_bSearchInDescription = bSearchInDescription; } + + int GetGenreType() const { return m_iGenreType; } + void SetGenreType(int iGenreType) { m_iGenreType = iGenreType; } + + int GetGenreSubType() const { return m_iGenreSubType; } + void SetGenreSubType(int iGenreSubType) { m_iGenreSubType = iGenreSubType; } + + int GetMinimumDuration() const { return m_iMinimumDuration; } + void SetMinimumDuration(int iMinimumDuration) { m_iMinimumDuration = iMinimumDuration; } + + int GetMaximumDuration() const { return m_iMaximumDuration; } + void SetMaximumDuration(int iMaximumDuration) { m_iMaximumDuration = iMaximumDuration; } + + const CDateTime &GetStartDateTime() const { return m_startDateTime; } + void SetStartDateTime(const CDateTime &startDateTime) { m_startDateTime = startDateTime; } + + const CDateTime &GetEndDateTime() const { return m_endDateTime; } + void SetEndDateTime(const CDateTime &endDateTime) { m_endDateTime = endDateTime; } + + bool ShouldIncludeUnknownGenres() const { return m_bIncludeUnknownGenres; } + void SetIncludeUnknownGenres(bool bIncludeUnknownGenres) { m_bIncludeUnknownGenres = bIncludeUnknownGenres; } + + bool ShouldRemoveDuplicates() const { return m_bRemoveDuplicates; } + void SetRemoveDuplicates(bool bRemoveDuplicates) { m_bRemoveDuplicates = bRemoveDuplicates; } + + bool IsRadio() const { return m_bIsRadio; } + void SetIsRadio(bool bIsRadio) { m_bIsRadio = bIsRadio; } + + int GetChannelNumber() const { return m_iChannelNumber; } + void SetChannelNumber(int iChannelNumber) { m_iChannelNumber = iChannelNumber; } + + bool IsFreeToAirOnly() const { return m_bFreeToAirOnly; } + void SetFreeToAirOnly(bool bFreeToAirOnly) { m_bFreeToAirOnly = bFreeToAirOnly; } + + int GetChannelGroup() const { return m_iChannelGroup; } + void SetChannelGroup(int iChannelGroup) { m_iChannelGroup = iChannelGroup; } + + bool ShouldIgnorePresentTimers() const { return m_bIgnorePresentTimers; } + void SetIgnorePresentTimers(bool bIgnorePresentTimers) { m_bIgnorePresentTimers = bIgnorePresentTimers; } + + bool ShouldIgnorePresentRecordings() const { return m_bIgnorePresentRecordings; } + void SetIgnorePresentRecordings(bool bIgnorePresentRecordings) { m_bIgnorePresentRecordings = bIgnorePresentRecordings; } + + unsigned int GetUniqueBroadcastId() const { return m_iUniqueBroadcastId; } + void SetUniqueBroadcastId(unsigned int iUniqueBroadcastId) { m_iUniqueBroadcastId = iUniqueBroadcastId; } + + private: + bool MatchGenre(const CEpgInfoTagPtr &tag) const; + bool MatchDuration(const CEpgInfoTagPtr &tag) const; + bool MatchStartAndEndTimes(const CEpgInfoTagPtr &tag) const; + bool MatchSearchTerm(const CEpgInfoTagPtr &tag) const; + bool MatchChannelNumber(const CEpgInfoTagPtr &tag) const; + bool MatchChannelGroup(const CEpgInfoTagPtr &tag) const; + bool MatchBroadcastId(const CEpgInfoTagPtr &tag) const; + bool MatchChannelType(const CEpgInfoTagPtr &tag) const; + bool MatchFreeToAir(const CEpgInfoTagPtr &tag) const; + bool MatchTimers(const CEpgInfoTagPtr &tag) const; + bool MatchRecordings(const CEpgInfoTagPtr &tag) const; + std::string m_strSearchTerm; /*!< The term to search for */ bool m_bIsCaseSensitive; /*!< Do a case sensitive search */ bool m_bSearchInDescription; /*!< Search for strSearchTerm in the description too */ @@ -66,12 +132,12 @@ namespace EPG CDateTime m_startDateTime; /*!< The minimum start time for an entry */ CDateTime m_endDateTime; /*!< The maximum end time for an entry */ bool m_bIncludeUnknownGenres; /*!< Include unknown genres or not */ - bool m_bPreventRepeats; /*!< True to remove repeating events, false if not */ + bool m_bRemoveDuplicates; /*!< True to remove duplicate events, false if not */ bool m_bIsRadio; /*!< True to filter radio channels only, false to tv only */ /* PVR specific filters */ int m_iChannelNumber; /*!< The channel number in the selected channel group */ - bool m_bFTAOnly; /*!< Free to air only or not */ + bool m_bFreeToAirOnly; /*!< Include free to air channels only */ int m_iChannelGroup; /*!< The group this channel belongs to */ bool m_bIgnorePresentTimers; /*!< True to ignore currently present timers (future recordings), false if not */ bool m_bIgnorePresentRecordings; /*!< True to ignore currently active recordings, false if not */ diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp index 94dfa65502..d7c9e5972a 100644 --- a/xbmc/filesystem/AddonsDirectory.cpp +++ b/xbmc/filesystem/AddonsDirectory.cpp @@ -153,7 +153,7 @@ static bool IsGameAddon(const AddonPtr& addon) IsGameSupportAddon(addon); } -static bool IsDependecyType(TYPE type) +static bool IsDependencyType(TYPE type) { return dependencyTypes.find(type) != dependencyTypes.end(); } @@ -351,7 +351,7 @@ static void GenerateMainCategoryListing(const CURL& path, const VECADDONS& addon for (unsigned int i = ADDON_UNKNOWN + 1; i < ADDON_MAX - 1; ++i) { const TYPE type = (TYPE)i; - if (!IsInfoProviderType(type) && !IsLookAndFeelType(type) && !IsDependecyType(type) && !IsGameType(type)) + if (!IsInfoProviderType(type) && !IsLookAndFeelType(type) && !IsDependencyType(type) && !IsGameType(type)) uncategorized.insert(static_cast<TYPE>(i)); } GenerateTypeListing(path, uncategorized, addons, items); diff --git a/xbmc/filesystem/File.h b/xbmc/filesystem/File.h index adcac32bd8..02649a5088 100644 --- a/xbmc/filesystem/File.h +++ b/xbmc/filesystem/File.h @@ -129,7 +129,7 @@ public: int IoControl(EIoControl request, void* param); - IFile *GetImplemenation() { return m_pFile; } + IFile *GetImplementation() { return m_pFile; } // CURL interface static bool Exists(const CURL& file, bool bUseCache = true); diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp index afea2fe5d5..8e1c95c7e5 100644 --- a/xbmc/filesystem/FileCache.cpp +++ b/xbmc/filesystem/FileCache.cpp @@ -146,7 +146,7 @@ void CFileCache::SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache /* = IFile *CFileCache::GetFileImp() { - return m_source.GetImplemenation(); + return m_source.GetImplementation(); } bool CFileCache::Open(const CURL& url) @@ -568,15 +568,15 @@ void CFileCache::StopThread(bool bWait /*= true*/) std::string CFileCache::GetContent() { - if (!m_source.GetImplemenation()) + if (!m_source.GetImplementation()) return IFile::GetContent(); - return m_source.GetImplemenation()->GetContent(); + return m_source.GetImplementation()->GetContent(); } std::string CFileCache::GetContentCharset(void) { - IFile* impl = m_source.GetImplemenation(); + IFile* impl = m_source.GetImplementation(); if (!impl) return IFile::GetContentCharset(); diff --git a/xbmc/filesystem/PipeFile.cpp b/xbmc/filesystem/PipeFile.cpp index 28230fb447..72250e6e7c 100644 --- a/xbmc/filesystem/PipeFile.cpp +++ b/xbmc/filesystem/PipeFile.cpp @@ -217,8 +217,8 @@ void CPipeFile::RemoveListener(IPipeListener *l) } } -void CPipeFile::SetOpenThreashold(int threashold) +void CPipeFile::SetOpenThreshold(int threshold) { - m_pipe->SetOpenThreashold(threashold); + m_pipe->SetOpenThreshold(threshold); } diff --git a/xbmc/filesystem/PipeFile.h b/xbmc/filesystem/PipeFile.h index 27204f10e5..2991d1a68e 100644 --- a/xbmc/filesystem/PipeFile.h +++ b/xbmc/filesystem/PipeFile.h @@ -76,7 +76,7 @@ public: bool IsEmpty(); bool IsClosed(); - void SetOpenThreashold(int threashold); + void SetOpenThreshold(int threshold); protected: int64_t m_pos; diff --git a/xbmc/filesystem/PipesManager.cpp b/xbmc/filesystem/PipesManager.cpp index 2c8cc37fb8..5f91ba67f0 100644 --- a/xbmc/filesystem/PipesManager.cpp +++ b/xbmc/filesystem/PipesManager.cpp @@ -38,17 +38,17 @@ Pipe::Pipe(const std::string &name, int nMaxSize) m_strPipeName = name; m_bOpen = true; m_bEof = false; - m_nOpenThreashold = PIPE_DEFAULT_MAX_SIZE / 2; - m_bReadyForRead = true; // open threashold disabled atm + m_nOpenThreshold = PIPE_DEFAULT_MAX_SIZE / 2; + m_bReadyForRead = true; // open threshold disabled atm } Pipe::~Pipe() { } -void Pipe::SetOpenThreashold(int threashold) +void Pipe::SetOpenThreshold(int threshold) { - m_nOpenThreashold = threashold; + m_nOpenThreshold = threshold; } const std::string &Pipe::GetName() @@ -223,7 +223,7 @@ void Pipe::CheckStatus() m_readEvent.Reset(); else { - if (!m_bReadyForRead && (int)m_buffer.getMaxReadSize() >= m_nOpenThreashold) + if (!m_bReadyForRead && (int)m_buffer.getMaxReadSize() >= m_nOpenThreshold) m_bReadyForRead = true; m_readEvent.Set(); } diff --git a/xbmc/filesystem/PipesManager.h b/xbmc/filesystem/PipesManager.h index 6007bf5745..9e4b31aa0b 100644 --- a/xbmc/filesystem/PipesManager.h +++ b/xbmc/filesystem/PipesManager.h @@ -87,7 +87,7 @@ class Pipe bool IsEof(); int GetAvailableRead(); - void SetOpenThreashold(int threashold); + void SetOpenThreshold(int threshold); protected: @@ -98,7 +98,7 @@ class Pipe CRingBuffer m_buffer; std::string m_strPipeName; int m_nRefCount; - int m_nOpenThreashold; + int m_nOpenThreshold; CEvent m_readEvent; CEvent m_writeEvent; diff --git a/xbmc/filesystem/RSSDirectory.cpp b/xbmc/filesystem/RSSDirectory.cpp index 36768e7774..12693d774e 100644 --- a/xbmc/filesystem/RSSDirectory.cpp +++ b/xbmc/filesystem/RSSDirectory.cpp @@ -93,7 +93,7 @@ static bool IsPathToMedia(const std::string& strPath ) return URIUtils::HasExtension(strPath, g_advancedSettings.m_videoExtensions + '|' + g_advancedSettings.GetMusicExtensions() + '|' + - g_advancedSettings.m_pictureExtensions); + g_advancedSettings.GetPictureExtensions()); } static bool IsPathToThumbnail(const std::string& strPath ) @@ -101,7 +101,7 @@ static bool IsPathToThumbnail(const std::string& strPath ) // Currently just check if this is an image, maybe we will add some // other checks later return URIUtils::HasExtension(strPath, - g_advancedSettings.m_pictureExtensions); + g_advancedSettings.GetPictureExtensions()); } static time_t ParseDate(const std::string & strDate) diff --git a/xbmc/filesystem/SFTPFile.cpp b/xbmc/filesystem/SFTPFile.cpp index 8fad5bd882..c97203b130 100644 --- a/xbmc/filesystem/SFTPFile.cpp +++ b/xbmc/filesystem/SFTPFile.cpp @@ -111,7 +111,7 @@ CSFTPSession::~CSFTPSession() Disconnect(); } -sftp_file CSFTPSession::CreateFileHande(const std::string &file) +sftp_file CSFTPSession::CreateFileHandle(const std::string &file) { if (m_connected) { @@ -603,7 +603,7 @@ bool CSFTPFile::Open(const CURL& url) if (m_session) { m_file = url.GetFileName().c_str(); - m_sftp_handle = m_session->CreateFileHande(m_file); + m_sftp_handle = m_session->CreateFileHandle(m_file); return (m_sftp_handle != NULL); } diff --git a/xbmc/filesystem/SFTPFile.h b/xbmc/filesystem/SFTPFile.h index 973b2df226..229ce4686b 100644 --- a/xbmc/filesystem/SFTPFile.h +++ b/xbmc/filesystem/SFTPFile.h @@ -60,7 +60,7 @@ public: CSFTPSession(const std::string &host, unsigned int port, const std::string &username, const std::string &password); virtual ~CSFTPSession(); - sftp_file CreateFileHande(const std::string &file); + sftp_file CreateFileHandle(const std::string &file); void CloseFileHandle(sftp_file handle); bool GetDirectory(const std::string &base, const std::string &folder, CFileItemList &items); bool DirectoryExists(const char *path); diff --git a/xbmc/filesystem/ZipManager.cpp b/xbmc/filesystem/ZipManager.cpp index df6220bf8a..0e0701b770 100644 --- a/xbmc/filesystem/ZipManager.cpp +++ b/xbmc/filesystem/ZipManager.cpp @@ -34,6 +34,8 @@ using namespace XFILE; +static const size_t ZC_FLAG_EFS = 1 << 11; // general purpose bit 11 - zip holds utf-8 filenames + CZipManager::CZipManager() { } @@ -192,9 +194,13 @@ bool CZipManager::GetZipList(const CURL& url, std::vector<SZipEntry>& items) return false; std::string strName(bufName.get(), bufName.size()); bufName.clear(); - g_charsetConverter.unknownToUTF8(strName); + if ((ze.flags & ZC_FLAG_EFS) == 0) + { + std::string tmp(strName); + g_charsetConverter.ToUtf8("CP437", tmp, strName); + } ZeroMemory(ze.name, 255); - strncpy(ze.name, strName.c_str(), strName.size()>254 ? 254 : strName.size()); + strncpy(ze.name, strName.c_str(), strName.size() > 254 ? 254 : strName.size()); // Jump after central file header extra field and file comment mFile.Seek(ze.eclength + ze.clength,SEEK_CUR); diff --git a/xbmc/games/CMakeLists.txt b/xbmc/games/CMakeLists.txt index 759f0987b0..70b26f38d0 100644 --- a/xbmc/games/CMakeLists.txt +++ b/xbmc/games/CMakeLists.txt @@ -1,7 +1,9 @@ -set(SOURCES GameSettings.cpp +set(SOURCES GameServices.cpp + GameSettings.cpp GameUtils.cpp) -set(HEADERS GameSettings.h +set(HEADERS GameServices.h + GameSettings.h GameTypes.h GameUtils.h) diff --git a/xbmc/games/GameServices.cpp b/xbmc/games/GameServices.cpp new file mode 100644 index 0000000000..eec28c41b8 --- /dev/null +++ b/xbmc/games/GameServices.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GameServices.h" +#include "controllers/Controller.h" +#include "controllers/ControllerManager.h" + +using namespace GAME; + +CGameServices::CGameServices() : + m_controllerManager(new CControllerManager) +{ +} + +CGameServices::~CGameServices() +{ + Deinit(); +} + +ControllerPtr CGameServices::GetController(const std::string& controllerId) +{ + return m_controllerManager->GetController(controllerId); +} + +ControllerPtr CGameServices::GetDefaultController() +{ + return m_controllerManager->GetDefaultController(); +} + +ControllerVector CGameServices::GetControllers() +{ + return m_controllerManager->GetControllers(); +} diff --git a/xbmc/games/GameServices.h b/xbmc/games/GameServices.h new file mode 100644 index 0000000000..520fb02cfb --- /dev/null +++ b/xbmc/games/GameServices.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "controllers/ControllerTypes.h" + +#include <memory> +#include <string> + +namespace GAME +{ + class CControllerManager; + + class CGameServices + { + public: + CGameServices(); + ~CGameServices(); + + void Init() { } + void Deinit() { } + + ControllerPtr GetController(const std::string& controllerId); + ControllerPtr GetDefaultController(); + ControllerVector GetControllers(); + + private: + std::unique_ptr<CControllerManager> m_controllerManager; + }; +} diff --git a/xbmc/games/addons/CMakeLists.txt b/xbmc/games/addons/CMakeLists.txt index 8a89ec63c6..b6d98ab0e4 100644 --- a/xbmc/games/addons/CMakeLists.txt +++ b/xbmc/games/addons/CMakeLists.txt @@ -1,4 +1,5 @@ set(SOURCES GameClient.cpp + GameClientInGameSaves.cpp GameClientInput.cpp GameClientKeyboard.cpp GameClientMouse.cpp @@ -8,6 +9,7 @@ set(SOURCES GameClient.cpp set(HEADERS GameClient.h GameClientCallbacks.h + GameClientInGameSaves.h GameClientInput.h GameClientKeyboard.h GameClientMouse.h diff --git a/xbmc/games/addons/GameClient.cpp b/xbmc/games/addons/GameClient.cpp index 5d60aa43fc..7530294e1a 100644 --- a/xbmc/games/addons/GameClient.cpp +++ b/xbmc/games/addons/GameClient.cpp @@ -20,6 +20,7 @@ #include "GameClient.h" #include "GameClientCallbacks.h" +#include "GameClientInGameSaves.h" #include "GameClientInput.h" #include "GameClientKeyboard.h" #include "GameClientMouse.h" @@ -34,9 +35,9 @@ #include "games/addons/playback/GameClientReversiblePlayback.h" #include "games/controllers/Controller.h" #include "games/ports/PortManager.h" +#include "games/GameServices.h" #include "guilib/GUIWindowManager.h" #include "guilib/WindowIDs.h" -#include "input/joysticks/DefaultJoystick.h" // for DEFAULT_CONTROLLER_ID #include "input/joysticks/JoystickTypes.h" #include "peripherals/Peripherals.h" #include "profiles/ProfilesManager.h" @@ -55,6 +56,7 @@ #include <iterator> #include <utility> +using namespace KODI; using namespace GAME; #define EXTENSION_SEPARATOR "|" @@ -276,6 +278,9 @@ bool CGameClient::OpenFile(const CFileItem& file, IGameAudioCallback* audio, IGa if (!InitializeGameplay(file.GetPath(), audio, video)) return false; + m_inGameSaves.reset(new CGameClientInGameSaves(this, &m_struct)); + m_inGameSaves->Load(); + return true; } @@ -486,6 +491,9 @@ void CGameClient::CloseFile() if (m_bIsPlaying) { + m_inGameSaves->Save(); + m_inGameSaves.reset(); + try { LogError(m_struct.UnloadGame(), "UnloadGame()"); } catch (...) { LogException("UnloadGame()"); } } @@ -725,21 +733,18 @@ bool CGameClient::OpenPort(unsigned int port) //! @todo Choose controller ControllerPtr& controller = controllers[0]; - if (controller->LoadLayout()) - { - m_ports[port].reset(new CGameClientInput(this, port, controller, &m_struct)); + m_ports[port].reset(new CGameClientInput(this, port, controller, &m_struct)); - // If keyboard input is being captured by this add-on, force the port type to PERIPHERAL_JOYSTICK - PERIPHERALS::PeripheralType device = PERIPHERALS::PERIPHERAL_UNKNOWN; - if (m_bSupportsKeyboard) - device = PERIPHERALS::PERIPHERAL_JOYSTICK; + // If keyboard input is being captured by this add-on, force the port type to PERIPHERAL_JOYSTICK + PERIPHERALS::PeripheralType device = PERIPHERALS::PERIPHERAL_UNKNOWN; + if (m_bSupportsKeyboard) + device = PERIPHERALS::PERIPHERAL_JOYSTICK; - CPortManager::GetInstance().OpenPort(m_ports[port].get(), port, device); + CPortManager::GetInstance().OpenPort(m_ports[port].get(), port, device); - UpdatePort(port, controller); + UpdatePort(port, controller); - return true; - } + return true; } return false; @@ -806,24 +811,22 @@ ControllerVector CGameClient::GetControllers(void) const ControllerVector controllers; + CGameServices& gameServices = CServiceBroker::GetGameServices(); + const ADDONDEPS& dependencies = GetDeps(); for (ADDONDEPS::const_iterator it = dependencies.begin(); it != dependencies.end(); ++it) { - AddonPtr addon; - if (CAddonMgr::GetInstance().GetAddon(it->first, addon, ADDON_GAME_CONTROLLER)) - { - ControllerPtr controller = std::dynamic_pointer_cast<CController>(addon); - if (controller) - controllers.push_back(controller); - } + ControllerPtr controller = gameServices.GetController(it->first); + if (controller) + controllers.push_back(controller); } if (controllers.empty()) { // Use the default controller - AddonPtr addon; - if (CAddonMgr::GetInstance().GetAddon(DEFAULT_CONTROLLER_ID, addon, ADDON_GAME_CONTROLLER)) - controllers.push_back(std::static_pointer_cast<CController>(addon)); + ControllerPtr controller = gameServices.GetDefaultController(); + if (controller) + controllers.push_back(controller); } return controllers; diff --git a/xbmc/games/addons/GameClient.h b/xbmc/games/addons/GameClient.h index ba8738f877..52cc0baf4e 100644 --- a/xbmc/games/addons/GameClient.h +++ b/xbmc/games/addons/GameClient.h @@ -39,6 +39,7 @@ class CFileItem; namespace GAME { +class CGameClientInGameSaves; class CGameClientInput; class CGameClientKeyboard; class CGameClientMouse; @@ -161,6 +162,9 @@ private: std::unique_ptr<IGameClientPlayback> m_playback; // Interface to control playback GAME_REGION m_region; // Region of the loaded game + // In-game saves + std::unique_ptr<CGameClientInGameSaves> m_inGameSaves; + // Input std::map<int, std::unique_ptr<CGameClientInput>> m_ports; std::unique_ptr<CGameClientKeyboard> m_keyboard; diff --git a/xbmc/games/addons/GameClientInGameSaves.cpp b/xbmc/games/addons/GameClientInGameSaves.cpp new file mode 100644 index 0000000000..6db63da6b5 --- /dev/null +++ b/xbmc/games/addons/GameClientInGameSaves.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2016-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GameClientInGameSaves.h" + +#include "GameClient.h" +#include "GameClientTranslator.h" +#include "filesystem/File.h" +#include "filesystem/Directory.h" +#include "profiles/ProfilesManager.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +#include <assert.h> + +using namespace GAME; + +#define INGAME_SAVES_DIRECTORY "InGameSaves" +#define INGAME_SAVES_EXTENSION_SAVE_RAM ".sav" +#define INGAME_SAVES_EXTENSION_RTC ".rtc" + +CGameClientInGameSaves::CGameClientInGameSaves(CGameClient* addon, const KodiToAddonFuncTable_Game* dllStruct) : + m_gameClient(addon), + m_dllStruct(dllStruct) +{ + assert(m_gameClient != nullptr); + assert(m_dllStruct != nullptr); +} + +void CGameClientInGameSaves::Load() +{ + Load(GAME_MEMORY_SAVE_RAM); + Load(GAME_MEMORY_RTC); +} + +void CGameClientInGameSaves::Save() +{ + Save(GAME_MEMORY_SAVE_RAM); + Save(GAME_MEMORY_RTC); +} + +std::string CGameClientInGameSaves::GetPath(GAME_MEMORY memoryType) +{ + std::string path = URIUtils::AddFileToFolder(CProfilesManager::GetInstance().GetSavestatesFolder(), INGAME_SAVES_DIRECTORY); + if (!XFILE::CDirectory::Exists(path)) + XFILE::CDirectory::Create(path); + + // Append save game filename + std::string gamePath = URIUtils::GetFileName(m_gameClient->GetGamePath()); + path = URIUtils::AddFileToFolder(path, gamePath.empty() ? m_gameClient->ID() : gamePath); + + // Append file extension + switch (memoryType) + { + case GAME_MEMORY_SAVE_RAM: return path + INGAME_SAVES_EXTENSION_SAVE_RAM; + case GAME_MEMORY_RTC: return path + INGAME_SAVES_EXTENSION_RTC; + default: + break; + } + return std::string(); +} + +void CGameClientInGameSaves::Load(GAME_MEMORY memoryType) +{ + uint8_t *gameMemory = nullptr; + size_t size = 0; + + try + { + m_dllStruct->GetMemory(memoryType, &gameMemory, &size); + } + catch (...) + { + CLog::Log(LOGERROR, "GAME: %s: Exception caught in GetMemory()", m_gameClient->ID().c_str()); + } + + const std::string path = GetPath(memoryType); + if (size > 0 && XFILE::CFile::Exists(path)) + { + XFILE::CFile file; + if (file.Open(path)) + { + ssize_t read = file.Read(gameMemory, size); + if (read == static_cast<ssize_t>(size)) + { + CLog::Log(LOGINFO, "GAME: In-game saves (%s) loaded from %s", CGameClientTranslator::ToString(memoryType), path.c_str()); + } + else + { + CLog::Log(LOGERROR, "GAME: Failed to read in-game saves (%s): %ld/%ld bytes read", CGameClientTranslator::ToString(memoryType), read, size); + } + } + else + { + CLog::Log(LOGERROR, "GAME: Unable to open in-game saves (%s) from file %s", CGameClientTranslator::ToString(memoryType), path.c_str()); + } + } + else + { + CLog::Log(LOGDEBUG, "GAME: No in-game saves (%s) to load", CGameClientTranslator::ToString(memoryType)); + } +} + +void CGameClientInGameSaves::Save(GAME_MEMORY memoryType) +{ + uint8_t *gameMemory = nullptr; + size_t size = 0; + + try + { + m_dllStruct->GetMemory(memoryType, &gameMemory, &size); + } + catch (...) + { + CLog::Log(LOGERROR, "GAME: %s: Exception caught in GetMemory()", m_gameClient->ID().c_str()); + } + + if (size > 0) + { + const std::string path = GetPath(memoryType); + XFILE::CFile file; + if (file.OpenForWrite(path, true)) + { + ssize_t written = 0; + written = file.Write(gameMemory, size); + file.Close(); + if (written == static_cast<ssize_t>(size)) + { + CLog::Log(LOGINFO, "GAME: In-game saves (%s) written to %s", CGameClientTranslator::ToString(memoryType), path.c_str()); + } + else + { + CLog::Log(LOGERROR, "GAME: Failed to write in-game saves (%s): %ld/%ld bytes written", CGameClientTranslator::ToString(memoryType), written, size); + } + } + else + { + CLog::Log(LOGERROR, "GAME: Unable to open in-game saves (%s) from file %s", CGameClientTranslator::ToString(memoryType), path.c_str()); + } + } + else + { + CLog::Log(LOGDEBUG, "GAME: No in-game saves (%s) to save", CGameClientTranslator::ToString(memoryType)); + } +} diff --git a/xbmc/games/addons/GameClientInGameSaves.h b/xbmc/games/addons/GameClientInGameSaves.h new file mode 100644 index 0000000000..38d64dec02 --- /dev/null +++ b/xbmc/games/addons/GameClientInGameSaves.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h" + +#include <string> + +struct GameClient; + +namespace GAME +{ + class CGameClient; + + /*! + * \brief This class implements in-game saves. + * + * \details Some games do not implement state persistence on their own, but rely on the frontend for saving their current + * memory state to disk. This is mostly the case for emulators for SRAM (battery backed up ram on cartridges) or + * memory cards. + * + * Differences to save states: + * - Works only for supported games (e.g. emulated games with SRAM support) + * - Often works emulator independent (and can be used to start a game with one emulator and continue with another) + * - Visible in-game (e.g. in-game save game selection menus) + */ + class CGameClientInGameSaves + { + public: + /*! + * \brief Constructor. + * \param addon The game client implementation. + * \param dllStruct The emulator or game for which the in-game saves are processed. + */ + CGameClientInGameSaves(CGameClient* addon, const KodiToAddonFuncTable_Game* dllStruct); + + /*! + * \brief Load in-game data. + */ + void Load(); + + /*! + * \brief Save in-game data. + */ + void Save(); + + private: + std::string GetPath(GAME_MEMORY memoryType); + + void Load(GAME_MEMORY memoryType); + void Save(GAME_MEMORY memoryType); + + const CGameClient* const m_gameClient; + const KodiToAddonFuncTable_Game* const m_dllStruct; + }; +} diff --git a/xbmc/games/addons/GameClientInput.cpp b/xbmc/games/addons/GameClientInput.cpp index 5cfb05132f..8e694d4bfb 100644 --- a/xbmc/games/addons/GameClientInput.cpp +++ b/xbmc/games/addons/GameClientInput.cpp @@ -27,6 +27,7 @@ #include <algorithm> #include <assert.h> +using namespace KODI; using namespace GAME; CGameClientInput::CGameClientInput(CGameClient* gameClient, int port, const ControllerPtr& controller, const KodiToAddonFuncTable_Game *dllStruct) : diff --git a/xbmc/games/addons/GameClientInput.h b/xbmc/games/addons/GameClientInput.h index e65fae8cdd..546ec775d1 100644 --- a/xbmc/games/addons/GameClientInput.h +++ b/xbmc/games/addons/GameClientInput.h @@ -34,7 +34,7 @@ namespace GAME * * Listens to game controller events and forwards them to the games (as game_input_event). */ - class CGameClientInput : public JOYSTICK::IInputHandler + class CGameClientInput : public KODI::JOYSTICK::IInputHandler { public: /*! @@ -50,7 +50,7 @@ namespace GAME virtual std::string ControllerID(void) const override; virtual bool HasFeature(const std::string& feature) const override; virtual bool AcceptsInput(void) override; - virtual JOYSTICK::INPUT_TYPE GetInputType(const std::string& feature) const override; + virtual KODI::JOYSTICK::INPUT_TYPE GetInputType(const std::string& feature) const override; virtual bool OnButtonPress(const std::string& feature, bool bPressed) override; virtual void OnButtonHold(const std::string& feature, unsigned int holdTimeMs) override { } virtual bool OnButtonMotion(const std::string& feature, float magnitude) override; diff --git a/xbmc/games/addons/GameClientKeyboard.cpp b/xbmc/games/addons/GameClientKeyboard.cpp index 0154e3406d..917da282ed 100644 --- a/xbmc/games/addons/GameClientKeyboard.cpp +++ b/xbmc/games/addons/GameClientKeyboard.cpp @@ -26,6 +26,7 @@ #include "input/Key.h" #include "utils/log.h" +using namespace KODI; using namespace GAME; #define BUTTON_INDEX_MASK 0x01ff diff --git a/xbmc/games/addons/GameClientKeyboard.h b/xbmc/games/addons/GameClientKeyboard.h index 0482ef641e..a82236863f 100644 --- a/xbmc/games/addons/GameClientKeyboard.h +++ b/xbmc/games/addons/GameClientKeyboard.h @@ -33,7 +33,7 @@ namespace GAME * * Listens to keyboard events and forwards them to the games (as game_input_event). */ - class CGameClientKeyboard : public KEYBOARD::IKeyboardHandler + class CGameClientKeyboard : public KODI::KEYBOARD::IKeyboardHandler { public: /*! diff --git a/xbmc/games/addons/GameClientMouse.cpp b/xbmc/games/addons/GameClientMouse.cpp index df1a0403f6..727b662bfa 100644 --- a/xbmc/games/addons/GameClientMouse.cpp +++ b/xbmc/games/addons/GameClientMouse.cpp @@ -26,6 +26,7 @@ #include "input/Key.h" #include "utils/log.h" +using namespace KODI; using namespace GAME; CGameClientMouse::CGameClientMouse(const CGameClient* gameClient, const KodiToAddonFuncTable_Game* dllStruct) : diff --git a/xbmc/games/addons/GameClientMouse.h b/xbmc/games/addons/GameClientMouse.h index e1b34ca1c8..4ab7a127a5 100644 --- a/xbmc/games/addons/GameClientMouse.h +++ b/xbmc/games/addons/GameClientMouse.h @@ -33,7 +33,7 @@ namespace GAME * * Listens to mouse events and forwards them to the games (as game_input_event). */ - class CGameClientMouse : public MOUSE::IMouseInputHandler + class CGameClientMouse : public KODI::MOUSE::IMouseInputHandler { public: /*! diff --git a/xbmc/games/addons/GameClientTranslator.cpp b/xbmc/games/addons/GameClientTranslator.cpp index dda424fc03..afa03ca755 100644 --- a/xbmc/games/addons/GameClientTranslator.cpp +++ b/xbmc/games/addons/GameClientTranslator.cpp @@ -39,6 +39,25 @@ const char* CGameClientTranslator::ToString(GAME_ERROR error) return "unknown error"; } +const char* CGameClientTranslator::ToString(GAME_MEMORY memory) +{ + switch (memory) + { + case GAME_MEMORY_SAVE_RAM: return "save ram"; + case GAME_MEMORY_RTC: return "rtc"; + case GAME_MEMORY_SYSTEM_RAM: return "system ram"; + case GAME_MEMORY_VIDEO_RAM: return "video ram"; + case GAME_MEMORY_SNES_BSX_RAM: return "snes bsx ram"; + case GAME_MEMORY_SNES_SUFAMI_TURBO_A_RAM: return "snes sufami turbo a ram"; + case GAME_MEMORY_SNES_SUFAMI_TURBO_B_RAM: return "snes sufami turbo b ram"; + case GAME_MEMORY_SNES_GAME_BOY_RAM: return "snes game boy ram"; + case GAME_MEMORY_SNES_GAME_BOY_RTC: return "snes game boy rtc"; + default: + break; + } + return "unknown memory"; +} + AVPixelFormat CGameClientTranslator::TranslatePixelFormat(GAME_PIXEL_FORMAT format) { switch (format) diff --git a/xbmc/games/addons/GameClientTranslator.h b/xbmc/games/addons/GameClientTranslator.h index 55a4c94893..a9f4e504db 100644 --- a/xbmc/games/addons/GameClientTranslator.h +++ b/xbmc/games/addons/GameClientTranslator.h @@ -47,6 +47,13 @@ namespace GAME static const char* ToString(GAME_ERROR error); /*! + * \brief Translates game memory types to string representation (e.g. for logging). + * \param memory The memory type to translate. + * \return Translated memory type. + */ + static const char* ToString(GAME_MEMORY error); + + /*! * \brief Translate pixel format (Game API to FFMPEG). * \param format The pixel format to translate. * \return Translated pixel format. diff --git a/xbmc/games/controllers/CMakeLists.txt b/xbmc/games/controllers/CMakeLists.txt index 60e543c42f..564aaff121 100644 --- a/xbmc/games/controllers/CMakeLists.txt +++ b/xbmc/games/controllers/CMakeLists.txt @@ -1,12 +1,14 @@ set(SOURCES Controller.cpp ControllerFeature.cpp ControllerLayout.cpp + ControllerManager.cpp ControllerTranslator.cpp) set(HEADERS Controller.h ControllerDefinitions.h ControllerFeature.h ControllerLayout.h + ControllerManager.h ControllerTranslator.h ControllerTypes.h) diff --git a/xbmc/games/controllers/ControllerDefinitions.h b/xbmc/games/controllers/ControllerDefinitions.h index bcb1639e43..a766f309ff 100644 --- a/xbmc/games/controllers/ControllerDefinitions.h +++ b/xbmc/games/controllers/ControllerDefinitions.h @@ -21,7 +21,7 @@ #define LAYOUT_XML_ROOT "layout" -#define LAYOUT_XML_ELM_GROUP "category" +#define LAYOUT_XML_ELM_CATEGORY "category" #define LAYOUT_XML_ELM_BUTTON "button" #define LAYOUT_XML_ELM_ANALOG_STICK "analogstick" @@ -33,7 +33,8 @@ #define LAYOUT_XML_ATTR_LAYOUT_IMAGE "image" #define LAYOUT_XML_ATTR_LAYOUT_OVERLAY "overlay" -#define LAYOUT_XML_ATTR_GROUP_LABEL "label" +#define LAYOUT_XML_ATTR_CATEGORY_NAME "name" +#define LAYOUT_XML_ATTR_CATEGORY_LABEL "label" #define LAYOUT_XML_ATTR_FEATURE_NAME "name" #define LAYOUT_XML_ATTR_FEATURE_LABEL "label" diff --git a/xbmc/games/controllers/ControllerFeature.cpp b/xbmc/games/controllers/ControllerFeature.cpp index e0500eaeba..4b15c39492 100644 --- a/xbmc/games/controllers/ControllerFeature.cpp +++ b/xbmc/games/controllers/ControllerFeature.cpp @@ -28,13 +28,15 @@ #include <sstream> +using namespace KODI; using namespace GAME; using namespace JOYSTICK; void CControllerFeature::Reset(void) { m_type = FEATURE_TYPE::UNKNOWN; - m_group.clear(); + m_category = FEATURE_CATEGORY::UNKNOWN; + m_strCategory.clear(); m_strName.clear(); m_strLabel.clear(); m_labelId = 0; @@ -46,7 +48,8 @@ CControllerFeature& CControllerFeature::operator=(const CControllerFeature& rhs) if (this != &rhs) { m_type = rhs.m_type; - m_group = rhs.m_group; + m_category = rhs.m_category; + m_strCategory = rhs.m_strCategory; m_strName = rhs.m_strName; m_strLabel = rhs.m_strLabel; m_labelId = rhs.m_labelId; @@ -55,7 +58,10 @@ CControllerFeature& CControllerFeature::operator=(const CControllerFeature& rhs) return *this; } -bool CControllerFeature::Deserialize(const TiXmlElement* pElement, const CController* controller, const std::string& strGroup) +bool CControllerFeature::Deserialize(const TiXmlElement* pElement, + const CController* controller, + FEATURE_CATEGORY category, + const std::string& strCategory) { Reset(); @@ -72,8 +78,9 @@ bool CControllerFeature::Deserialize(const TiXmlElement* pElement, const CContro return false; } - // Group was obtained from parent XML node - m_group = strGroup; + // Cagegory was obtained from parent XML node + m_category = category; + m_strCategory = strCategory; // Name m_strName = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_FEATURE_NAME); diff --git a/xbmc/games/controllers/ControllerFeature.h b/xbmc/games/controllers/ControllerFeature.h index 7a2ae4336e..9b90f68653 100644 --- a/xbmc/games/controllers/ControllerFeature.h +++ b/xbmc/games/controllers/ControllerFeature.h @@ -39,22 +39,27 @@ public: CControllerFeature& operator=(const CControllerFeature& rhs); - JOYSTICK::FEATURE_TYPE Type(void) const { return m_type; } - const std::string& Group(void) const { return m_group; } + KODI::JOYSTICK::FEATURE_TYPE Type(void) const { return m_type; } + KODI::JOYSTICK::FEATURE_CATEGORY Category(void) const { return m_category; } + const std::string& CategoryLabel(void) const { return m_strCategory; } const std::string& Name(void) const { return m_strName; } const std::string& Label(void) const { return m_strLabel; } unsigned int LabelID(void) const { return m_labelId; } - JOYSTICK::INPUT_TYPE InputType(void) const { return m_inputType; } + KODI::JOYSTICK::INPUT_TYPE InputType(void) const { return m_inputType; } - bool Deserialize(const TiXmlElement* pElement, const CController* controller, const std::string& strGroup); + bool Deserialize(const TiXmlElement* pElement, + const CController* controller, + KODI::JOYSTICK::FEATURE_CATEGORY category, + const std::string& strCategory); private: - JOYSTICK::FEATURE_TYPE m_type; - std::string m_group; + KODI::JOYSTICK::FEATURE_TYPE m_type; + KODI::JOYSTICK::FEATURE_CATEGORY m_category; + std::string m_strCategory; std::string m_strName; std::string m_strLabel; unsigned int m_labelId; - JOYSTICK::INPUT_TYPE m_inputType; + KODI::JOYSTICK::INPUT_TYPE m_inputType; }; } diff --git a/xbmc/games/controllers/ControllerLayout.cpp b/xbmc/games/controllers/ControllerLayout.cpp index e27f31a20c..dc7f8d5ddb 100644 --- a/xbmc/games/controllers/ControllerLayout.cpp +++ b/xbmc/games/controllers/ControllerLayout.cpp @@ -21,6 +21,7 @@ #include "ControllerLayout.h" #include "Controller.h" #include "ControllerDefinitions.h" +#include "ControllerTranslator.h" #include "guilib/LocalizeStrings.h" #include "utils/log.h" #include "utils/XMLUtils.h" @@ -28,6 +29,7 @@ #include <algorithm> #include <sstream> +using namespace KODI; using namespace GAME; using namespace JOYSTICK; @@ -97,32 +99,36 @@ bool CControllerLayout::Deserialize(const TiXmlElement* pElement, const CControl CLog::Log(LOGDEBUG, "<%s> tag has no \"%s\" attribute", LAYOUT_XML_ROOT, LAYOUT_XML_ATTR_LAYOUT_IMAGE); // Features - for (const TiXmlElement* pGroup = pElement->FirstChildElement(); pGroup != nullptr; pGroup = pGroup->NextSiblingElement()) + for (const TiXmlElement* pCategory = pElement->FirstChildElement(); pCategory != nullptr; pCategory = pCategory->NextSiblingElement()) { - if (pGroup->ValueStr() != LAYOUT_XML_ELM_GROUP) + if (pCategory->ValueStr() != LAYOUT_XML_ELM_CATEGORY) { - CLog::Log(LOGDEBUG, "<%s> tag is misnamed: <%s>", LAYOUT_XML_ELM_GROUP, pGroup->Value() ? pGroup->Value() : ""); + CLog::Log(LOGERROR, "<%s> tag is misnamed: <%s>", LAYOUT_XML_ELM_CATEGORY, pCategory->Value() ? pCategory->Value() : ""); continue; } - // Group - std::string strGroup; + // Category + std::string strCategory = XMLUtils::GetAttribute(pCategory, LAYOUT_XML_ATTR_CATEGORY_NAME); + FEATURE_CATEGORY category = CControllerTranslator::TranslateFeatureCategory(strCategory); - std::string strGroupLabel = XMLUtils::GetAttribute(pGroup, LAYOUT_XML_ATTR_GROUP_LABEL); - if (!strGroupLabel.empty()) + // Category label + std::string strCategoryLabel; + + std::string strCategoryLabelId = XMLUtils::GetAttribute(pCategory, LAYOUT_XML_ATTR_CATEGORY_LABEL); + if (!strCategoryLabelId.empty()) { - unsigned int categoryId; - std::istringstream(strGroupLabel) >> categoryId; - strGroup = g_localizeStrings.GetAddonString(controller->ID(), categoryId); - if (strGroup.empty()) - strGroup = g_localizeStrings.Get(categoryId); + unsigned int categoryLabelId; + std::istringstream(strCategoryLabelId) >> categoryLabelId; + strCategoryLabel = g_localizeStrings.GetAddonString(controller->ID(), categoryLabelId); + if (strCategoryLabel.empty()) + strCategoryLabel = g_localizeStrings.Get(categoryLabelId); } - for (const TiXmlElement* pFeature = pGroup->FirstChildElement(); pFeature != nullptr; pFeature = pFeature->NextSiblingElement()) + for (const TiXmlElement* pFeature = pCategory->FirstChildElement(); pFeature != nullptr; pFeature = pFeature->NextSiblingElement()) { CControllerFeature feature; - if (!feature.Deserialize(pFeature, controller, strGroup)) + if (!feature.Deserialize(pFeature, controller, category, strCategoryLabel)) return false; m_features.push_back(feature); diff --git a/xbmc/games/controllers/ControllerLayout.h b/xbmc/games/controllers/ControllerLayout.h index 559fe27b43..db5dac2d7b 100644 --- a/xbmc/games/controllers/ControllerLayout.h +++ b/xbmc/games/controllers/ControllerLayout.h @@ -43,8 +43,8 @@ public: const std::vector<CControllerFeature>& Features(void) const { return m_features; } - unsigned int FeatureCount(JOYSTICK::FEATURE_TYPE type = JOYSTICK::FEATURE_TYPE::UNKNOWN, - JOYSTICK::INPUT_TYPE buttonType = JOYSTICK::INPUT_TYPE::UNKNOWN) const; + unsigned int FeatureCount(KODI::JOYSTICK::FEATURE_TYPE type = KODI::JOYSTICK::FEATURE_TYPE::UNKNOWN, + KODI::JOYSTICK::INPUT_TYPE buttonType = KODI::JOYSTICK::INPUT_TYPE::UNKNOWN) const; bool Deserialize(const TiXmlElement* pLayoutElement, const CController* controller); diff --git a/xbmc/games/controllers/ControllerManager.cpp b/xbmc/games/controllers/ControllerManager.cpp new file mode 100644 index 0000000000..fe19bf7d35 --- /dev/null +++ b/xbmc/games/controllers/ControllerManager.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "ControllerManager.h" +#include "Controller.h" +#include "addons/AddonManager.h" +#include "input/joysticks/DefaultJoystick.h" + +using namespace GAME; + +ControllerPtr CControllerManager::GetController(const std::string& controllerId) +{ + using namespace ADDON; + + ControllerPtr& cachedController = m_cache[controllerId]; + + if (!cachedController && m_failedControllers.find(controllerId) == m_failedControllers.end()) + { + AddonPtr addon; + if (CAddonMgr::GetInstance().GetAddon(controllerId, addon, ADDON_GAME_CONTROLLER, false)) + cachedController = LoadController(std::move(addon)); + } + + return cachedController; +} + +ControllerPtr CControllerManager::GetDefaultController() +{ + return GetController(DEFAULT_CONTROLLER_ID); +} + +ControllerVector CControllerManager::GetControllers() +{ + using namespace ADDON; + + ControllerVector controllers; + + VECADDONS addons; + if (CAddonMgr::GetInstance().GetInstalledAddons(addons, ADDON_GAME_CONTROLLER)) + { + for (auto& addon : addons) + { + ControllerPtr& cachedController = m_cache[addon->ID()]; + if (!cachedController && m_failedControllers.find(addon->ID()) == m_failedControllers.end()) + cachedController = LoadController(std::move(addon)); + + if (cachedController) + controllers.emplace_back(cachedController); + } + } + + return controllers; +} + +ControllerPtr CControllerManager::LoadController(ADDON::AddonPtr addon) +{ + ControllerPtr controller = std::static_pointer_cast<CController>(addon); + if (!controller->LoadLayout()) + { + m_failedControllers.insert(addon->ID()); + controller.reset(); + } + + return controller; +} diff --git a/xbmc/games/controllers/ControllerManager.h b/xbmc/games/controllers/ControllerManager.h new file mode 100644 index 0000000000..d7c6567351 --- /dev/null +++ b/xbmc/games/controllers/ControllerManager.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "ControllerTypes.h" +#include "addons/IAddon.h" + +#include <map> +#include <set> +#include <string> + +namespace GAME +{ + class CControllerManager + { + public: + CControllerManager() = default; + ~CControllerManager() = default; + + /*! + * \brief Get a controller + * + * A cache is used to avoid reloading controllers each time they are + * requested. + * + * \param controllerId The controller's ID + * + * \return The controller, or empty if the controller isn't installed or + * can't be loaded + */ + ControllerPtr GetController(const std::string& controllerId); + + /*! + * \brief Get the default controller + * + * \return The default controller, or empty if the controller failed to load + */ + ControllerPtr GetDefaultController(); + + /*! + * \brief Get installed controllers + * + * \return The installed controllers that loaded successfully + */ + ControllerVector GetControllers(); + + private: + ControllerPtr LoadController(ADDON::AddonPtr addon); + + std::map<std::string, ControllerPtr> m_cache; + std::set<std::string> m_failedControllers; // Controllers that failed to load + }; +} diff --git a/xbmc/games/controllers/ControllerTranslator.cpp b/xbmc/games/controllers/ControllerTranslator.cpp index 0b0867c1a2..72af8ed4e5 100644 --- a/xbmc/games/controllers/ControllerTranslator.cpp +++ b/xbmc/games/controllers/ControllerTranslator.cpp @@ -21,6 +21,7 @@ #include "ControllerTranslator.h" #include "ControllerDefinitions.h" +using namespace KODI; using namespace GAME; using namespace JOYSTICK; @@ -50,6 +51,34 @@ FEATURE_TYPE CControllerTranslator::TranslateFeatureType(const std::string& strT return FEATURE_TYPE::UNKNOWN; } +const char* CControllerTranslator::TranslateFeatureCategory(FEATURE_CATEGORY category) +{ + switch (category) + { + case FEATURE_CATEGORY::FACE: return "face"; + case FEATURE_CATEGORY::SHOULDER: return "shoulder"; + case FEATURE_CATEGORY::TRIGGER: return "triggers"; + case FEATURE_CATEGORY::ANALOG_STICK: return "analogsticks"; + case FEATURE_CATEGORY::ACCELEROMETER: return "accelerometer"; + case FEATURE_CATEGORY::HAPTICS: return "haptics"; + default: + break; + } + return ""; +} + +FEATURE_CATEGORY CControllerTranslator::TranslateFeatureCategory(const std::string& strCategory) +{ + if (strCategory == "face") return FEATURE_CATEGORY::FACE; + if (strCategory == "shoulder") return FEATURE_CATEGORY::SHOULDER; + if (strCategory == "triggers") return FEATURE_CATEGORY::TRIGGER; + if (strCategory == "analogsticks") return FEATURE_CATEGORY::ANALOG_STICK; + if (strCategory == "accelerometer") return FEATURE_CATEGORY::ACCELEROMETER; + if (strCategory == "haptics") return FEATURE_CATEGORY::HAPTICS; + + return FEATURE_CATEGORY::UNKNOWN; +} + const char* CControllerTranslator::TranslateInputType(INPUT_TYPE type) { switch (type) diff --git a/xbmc/games/controllers/ControllerTranslator.h b/xbmc/games/controllers/ControllerTranslator.h index c7436134e4..ea8b06d3c4 100644 --- a/xbmc/games/controllers/ControllerTranslator.h +++ b/xbmc/games/controllers/ControllerTranslator.h @@ -30,11 +30,14 @@ namespace GAME class CControllerTranslator { public: - static const char* TranslateFeatureType(JOYSTICK::FEATURE_TYPE type); - static JOYSTICK::FEATURE_TYPE TranslateFeatureType(const std::string& strType); + static const char* TranslateFeatureType(KODI::JOYSTICK::FEATURE_TYPE type); + static KODI::JOYSTICK::FEATURE_TYPE TranslateFeatureType(const std::string& strType); - static const char* TranslateInputType(JOYSTICK::INPUT_TYPE type); - static JOYSTICK::INPUT_TYPE TranslateInputType(const std::string& strType); + static const char* TranslateFeatureCategory(KODI::JOYSTICK::FEATURE_CATEGORY category); + static KODI::JOYSTICK::FEATURE_CATEGORY TranslateFeatureCategory(const std::string& strCategory); + + static const char* TranslateInputType(KODI::JOYSTICK::INPUT_TYPE type); + static KODI::JOYSTICK::INPUT_TYPE TranslateInputType(const std::string& strType); }; } diff --git a/xbmc/games/controllers/dialogs/CMakeLists.txt b/xbmc/games/controllers/dialogs/CMakeLists.txt index 436712ca8c..2b398e98ed 100644 --- a/xbmc/games/controllers/dialogs/CMakeLists.txt +++ b/xbmc/games/controllers/dialogs/CMakeLists.txt @@ -1,5 +1,11 @@ -set(SOURCES GUIDialogButtonCapture.cpp) +set(SOURCES GUIDialogAxisDetection.cpp + GUIDialogButtonCapture.cpp + GUIDialogIgnoreInput.cpp +) -set(HEADERS GUIDialogButtonCapture.h) +set(HEADERS GUIDialogAxisDetection.h + GUIDialogButtonCapture.h + GUIDialogIgnoreInput.h +) core_add_library(games_controller_dialogs) diff --git a/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp new file mode 100644 index 0000000000..fb74519fa1 --- /dev/null +++ b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GUIDialogAxisDetection.h" +#include "guilib/LocalizeStrings.h" +#include "input/joysticks/DriverPrimitive.h" +#include "input/joysticks/IButtonMap.h" +#include "input/joysticks/JoystickTranslator.h" +#include "utils/StringUtils.h" + +#include <algorithm> + +using namespace KODI; +using namespace GAME; + +std::string CGUIDialogAxisDetection::GetDialogText() +{ + // "Press all analog buttons now to detect them:[CR][CR]%s" + std::string dialogText = g_localizeStrings.Get(35020); + + std::vector<std::string> primitives; + + for (const auto& axisEntry : m_detectedAxes) + { + JOYSTICK::CDriverPrimitive axis(axisEntry.second, 0, JOYSTICK::SEMIAXIS_DIRECTION::POSITIVE, 1); + primitives.emplace_back(JOYSTICK::CJoystickTranslator::GetPrimitiveName(axis)); + } + + return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str()); +} + +std::string CGUIDialogAxisDetection::GetDialogHeader() +{ + return g_localizeStrings.Get(35058); // "Controller Configuration" +} + +bool CGUIDialogAxisDetection::MapPrimitiveInternal(JOYSTICK::IButtonMap* buttonMap, + JOYSTICK::IActionMap* actionMap, + const JOYSTICK::CDriverPrimitive& primitive) +{ + if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS) + AddAxis(buttonMap->DeviceName(), primitive.Index()); + + return true; +} + +void CGUIDialogAxisDetection::OnLateAxis(const JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) +{ + AddAxis(buttonMap->DeviceName(), axisIndex); +} + +void CGUIDialogAxisDetection::AddAxis(const std::string& deviceName, unsigned int axisIndex) +{ + auto it = std::find_if(m_detectedAxes.begin(), m_detectedAxes.end(), + [&deviceName, axisIndex](const AxisEntry& axis) + { + return axis.first == deviceName && + axis.second == axisIndex; + }); + + if (it == m_detectedAxes.end()) + { + m_detectedAxes.emplace_back(std::make_pair(deviceName, axisIndex)); + m_captureEvent.Set(); + } +} diff --git a/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h new file mode 100644 index 0000000000..2ad7c9b568 --- /dev/null +++ b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "GUIDialogButtonCapture.h" + +#include <string> +#include <vector> +#include <utility> + +namespace GAME +{ + class CGUIDialogAxisDetection : public CGUIDialogButtonCapture + { + public: + CGUIDialogAxisDetection() = default; + + virtual ~CGUIDialogAxisDetection() = default; + + // specialization of IButtonMapper via CGUIDialogButtonCapture + void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override; + + protected: + // implementation of CGUIDialogButtonCapture + virtual std::string GetDialogText() override; + virtual std::string GetDialogHeader() override; + virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap, + KODI::JOYSTICK::IActionMap* actionMap, + const KODI::JOYSTICK::CDriverPrimitive& primitive) override; + virtual void OnClose(bool bAccepted) override { } + + private: + void AddAxis(const std::string& deviceName, unsigned int axisIndex); + + // Axis types + using DeviceName = std::string; + using AxisIndex = unsigned int; + using AxisEntry = std::pair<DeviceName, AxisIndex>; + using AxisVector = std::vector<AxisEntry>; + + // Axis detection + AxisVector m_detectedAxes; + }; +} diff --git a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp index 6ed6cfaa78..490f97a2b4 100644 --- a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp +++ b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp @@ -21,22 +21,20 @@ #include "GUIDialogButtonCapture.h" #include "dialogs/GUIDialogOK.h" #include "guilib/GUIWindowManager.h" -#include "guilib/LocalizeStrings.h" #include "guilib/WindowIDs.h" #include "input/joysticks/DefaultJoystick.h" #include "input/joysticks/IActionMap.h" #include "input/joysticks/IButtonMap.h" #include "input/joysticks/IButtonMapCallback.h" #include "input/joysticks/JoystickUtils.h" -#include "input/Key.h" -#include "utils/log.h" +#include "input/ActionIDs.h" #include "peripherals/Peripherals.h" -#include "utils/StringUtils.h" #include "utils/Variant.h" #include <algorithm> #include <iterator> +using namespace KODI; using namespace GAME; CGUIDialogButtonCapture::CGUIDialogButtonCapture() : @@ -59,27 +57,13 @@ void CGUIDialogButtonCapture::Show() Create(); - bool bAccepted = CGUIDialogOK::ShowAndGetInput(CVariant{ 35013 }, CVariant{ GetDialogText() }); // "Fix skipping" + bool bAccepted = CGUIDialogOK::ShowAndGetInput(CVariant{ GetDialogHeader() }, CVariant{ GetDialogText() }); StopThread(false); m_captureEvent.Set(); - for (auto& callback : ButtonMapCallbacks()) - { - if (bAccepted) - { - // See documentation of IButtonMapCallback::ResetIgnoredPrimitives() - // for why this call is needed - if (m_deviceName.empty()) - callback.second->ResetIgnoredPrimitives(); - - if (m_deviceName.empty() || m_deviceName == callback.first) - callback.second->SaveButtonMap(); - } - else - callback.second->RevertButtonMap(); - } + OnClose(bAccepted); RemoveHooks(); } @@ -126,72 +110,7 @@ bool CGUIDialogButtonCapture::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, } } - // Check if we have already started capturing primitives for a device - const bool bHasDevice = !m_deviceName.empty(); - - // If a primitive comes from a different device, ignore it - if (bHasDevice && m_deviceName != buttonMap->DeviceName()) - { - CLog::Log(LOGDEBUG, "%s: ignoring input from device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); - return false; - } - - if (!bHasDevice) - { - CLog::Log(LOGDEBUG, "%s: capturing input for device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); - m_deviceName = buttonMap->DeviceName(); - } - - if (AddPrimitive(primitive)) - { - buttonMap->SetIgnoredPrimitives(m_capturedPrimitives); - m_captureEvent.Set(); - } - - return true; -} - -bool CGUIDialogButtonCapture::AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive) -{ - bool bValid = false; - - if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::BUTTON) - { - bValid = std::find(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), primitive) == m_capturedPrimitives.end(); - } - else if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS) - { - // Don't need to do anything if opposite semiaxis is already captured - JOYSTICK::CDriverPrimitive opposite(primitive.Index(), primitive.SemiAxisDirection() * -1); - - bValid = std::find(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), primitive) == m_capturedPrimitives.end() && - std::find(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), opposite) == m_capturedPrimitives.end(); - } - - if (bValid) - { - m_capturedPrimitives.emplace_back(primitive); - return true; - } - - return false; -} - -std::string CGUIDialogButtonCapture::GetDialogText() -{ - // "Some controllers have buttons and axes that interfere with mapping. Press - // these now to disable them:[CR][CR]%s" - std::string dialogText = g_localizeStrings.Get(35014); - - std::vector<std::string> primitives; - - std::transform(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), std::back_inserter(primitives), - [](const JOYSTICK::CDriverPrimitive& primitive) - { - return GetPrimitiveName(primitive); - }); - - return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str()); + return MapPrimitiveInternal(buttonMap, actionMap, primitive); } void CGUIDialogButtonCapture::InstallHooks(void) @@ -226,21 +145,3 @@ void CGUIDialogButtonCapture::Notify(const Observable& obs, const ObservableMess break; } } - -std::string CGUIDialogButtonCapture::GetPrimitiveName(const JOYSTICK::CDriverPrimitive& primitive) -{ - std::string primitiveTemplate; - - switch (primitive.Type()) - { - case JOYSTICK::PRIMITIVE_TYPE::BUTTON: - primitiveTemplate = g_localizeStrings.Get(35015); // "Button %d" - break; - case JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS: - primitiveTemplate = g_localizeStrings.Get(35016); // "Axis %d" - break; - default: break; - } - - return StringUtils::Format(primitiveTemplate.c_str(), primitive.Index()); -} diff --git a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h index fe242c3e44..00cda4046a 100644 --- a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h +++ b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h @@ -19,55 +19,59 @@ */ #pragma once -#include "input/joysticks/DriverPrimitive.h" #include "input/joysticks/IButtonMapper.h" #include "threads/Event.h" #include "threads/Thread.h" #include "utils/Observer.h" +#include <string> #include <vector> namespace GAME { - class CGUIDialogButtonCapture : public JOYSTICK::IButtonMapper, + class CGUIDialogButtonCapture : public KODI::JOYSTICK::IButtonMapper, public Observer, protected CThread { public: CGUIDialogButtonCapture(); + virtual ~CGUIDialogButtonCapture() = default; + // implementation of IButtonMapper virtual std::string ControllerID(void) const override; virtual bool NeedsCooldown(void) const override { return false; } virtual bool Emulation(void) const override { return false; } virtual unsigned int ControllerNumber(void) const override { return 0; } - virtual bool MapPrimitive(JOYSTICK::IButtonMap* buttonMap, - JOYSTICK::IActionMap* actionMap, - const JOYSTICK::CDriverPrimitive& primitive) override; - virtual void OnEventFrame(const JOYSTICK::IButtonMap* buttonMap, bool bMotion) override { } + virtual bool MapPrimitive(KODI::JOYSTICK::IButtonMap* buttonMap, + KODI::JOYSTICK::IActionMap* actionMap, + const KODI::JOYSTICK::CDriverPrimitive& primitive) override; + virtual void OnEventFrame(const KODI::JOYSTICK::IButtonMap* buttonMap, bool bMotion) override { } + virtual void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override { } // implementation of Observer virtual void Notify(const Observable &obs, const ObservableMessage msg) override; + /*! + * \brief Show the dialog + */ void Show(); protected: // implementation of CThread virtual void Process() override; - private: - bool AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive); + virtual std::string GetDialogText() = 0; + virtual std::string GetDialogHeader() = 0; + virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap, + KODI::JOYSTICK::IActionMap* actionMap, + const KODI::JOYSTICK::CDriverPrimitive& primitive) = 0; + virtual void OnClose(bool bAccepted) = 0; - std::string GetDialogText(); + CEvent m_captureEvent; + private: void InstallHooks(); void RemoveHooks(); - - static std::string GetPrimitiveName(const JOYSTICK::CDriverPrimitive& primitive); - - // Button capture parameters - std::string m_deviceName; - std::vector<JOYSTICK::CDriverPrimitive> m_capturedPrimitives; - CEvent m_captureEvent; }; } diff --git a/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp new file mode 100644 index 0000000000..a767340438 --- /dev/null +++ b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GUIDialogIgnoreInput.h" +#include "guilib/LocalizeStrings.h" +#include "input/joysticks/IButtonMap.h" +#include "input/joysticks/IButtonMapCallback.h" +#include "input/joysticks/JoystickTranslator.h" +#include "utils/log.h" +#include "utils/StringUtils.h" + +#include <algorithm> +#include <iterator> + +using namespace KODI; +using namespace GAME; + +std::string CGUIDialogIgnoreInput::GetDialogText() +{ + // "Some controllers have buttons and axes that interfere with mapping. Press + // these now to disable them:[CR]%s" + std::string dialogText = g_localizeStrings.Get(35014); + + std::vector<std::string> primitives; + + std::transform(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), std::back_inserter(primitives), + [](const JOYSTICK::CDriverPrimitive& primitive) + { + return JOYSTICK::CJoystickTranslator::GetPrimitiveName(primitive); + }); + + return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str()); +} + +std::string CGUIDialogIgnoreInput::GetDialogHeader() +{ + + return g_localizeStrings.Get(35019); // "Ignore input" +} + +bool CGUIDialogIgnoreInput::MapPrimitiveInternal(JOYSTICK::IButtonMap* buttonMap, + JOYSTICK::IActionMap* actionMap, + const JOYSTICK::CDriverPrimitive& primitive) +{ + // Check if we have already started capturing primitives for a device + const bool bHasDevice = !m_deviceName.empty(); + + // If a primitive comes from a different device, ignore it + if (bHasDevice && m_deviceName != buttonMap->DeviceName()) + { + CLog::Log(LOGDEBUG, "%s: ignoring input from device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); + return false; + } + + if (!bHasDevice) + { + CLog::Log(LOGDEBUG, "%s: capturing input for device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); + m_deviceName = buttonMap->DeviceName(); + } + + if (AddPrimitive(primitive)) + { + buttonMap->SetIgnoredPrimitives(m_capturedPrimitives); + m_captureEvent.Set(); + } + + return true; +} + +void CGUIDialogIgnoreInput::OnClose(bool bAccepted) +{ + for (auto& callback : ButtonMapCallbacks()) + { + if (bAccepted) + { + // See documentation of IButtonMapCallback::ResetIgnoredPrimitives() + // for why this call is needed + if (m_deviceName.empty()) + callback.second->ResetIgnoredPrimitives(); + + if (m_deviceName.empty() || m_deviceName == callback.first) + callback.second->SaveButtonMap(); + } + else + callback.second->RevertButtonMap(); + } +} + +bool CGUIDialogIgnoreInput::AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive) +{ + bool bValid = false; + + if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::BUTTON || + primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS) + { + auto PrimitiveMatch = [&primitive](const JOYSTICK::CDriverPrimitive& other) + { + return primitive.Type() == other.Type() && + primitive.Index() == other.Index(); + }; + + bValid = std::find_if(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), PrimitiveMatch) == m_capturedPrimitives.end(); + } + + if (bValid) + { + m_capturedPrimitives.emplace_back(primitive); + return true; + } + + return false; +} diff --git a/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h new file mode 100644 index 0000000000..a4b358412a --- /dev/null +++ b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "GUIDialogButtonCapture.h" +#include "input/joysticks/DriverPrimitive.h" + +#include <string> +#include <vector> + +namespace GAME +{ + class CGUIDialogIgnoreInput : public CGUIDialogButtonCapture + { + public: + CGUIDialogIgnoreInput() = default; + + virtual ~CGUIDialogIgnoreInput() = default; + + protected: + // implementation of CGUIDialogButtonCapture + virtual std::string GetDialogText() override; + virtual std::string GetDialogHeader() override; + virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap, + KODI::JOYSTICK::IActionMap* actionMap, + const KODI::JOYSTICK::CDriverPrimitive& primitive) override; + void OnClose(bool bAccepted) override; + + private: + bool AddPrimitive(const KODI::JOYSTICK::CDriverPrimitive& primitive); + + std::string m_deviceName; + std::vector<KODI::JOYSTICK::CDriverPrimitive> m_capturedPrimitives; + }; +} diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp index 8e1fb3971e..1ba9b81cba 100644 --- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp +++ b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp @@ -24,6 +24,7 @@ #include <string> +using namespace KODI; using namespace GAME; CGUIAnalogStickButton::CGUIAnalogStickButton(const CGUIButtonControl& buttonTemplate, diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h index 19990f36bf..c5d632b831 100644 --- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h +++ b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h @@ -36,7 +36,7 @@ namespace GAME // implementation of IFeatureButton virtual bool PromptForInput(CEvent& waitEvent) override; virtual bool IsFinished(void) const override; - virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override; + virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override; virtual void Reset(void) override; private: diff --git a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h index 354f314111..cd6583aaab 100644 --- a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h +++ b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h @@ -44,7 +44,7 @@ namespace GAME // partial implementation of IFeatureButton virtual const CControllerFeature& Feature(void) const override { return m_feature; } - virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override { return JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; } + virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override { return KODI::JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; } protected: bool DoPrompt(const std::string& strPrompt, const std::string& strWarn, const std::string& strFeature, CEvent& waitEvent); diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp index 525f83ca63..9071db44f8 100644 --- a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp +++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp @@ -19,16 +19,19 @@ */ #include "GUIConfigurationWizard.h" +#include "games/controllers/dialogs/GUIDialogAxisDetection.h" #include "games/controllers/guicontrols/GUIFeatureButton.h" #include "games/controllers/Controller.h" #include "games/controllers/ControllerFeature.h" #include "input/joysticks/IButtonMap.h" #include "input/joysticks/IButtonMapCallback.h" +#include "input/keyboard/KeymapActionMap.h" #include "input/InputManager.h" #include "peripherals/Peripherals.h" #include "threads/SingleLock.h" #include "utils/log.h" +using namespace KODI; using namespace GAME; #define ESC_KEY_CODE 27 @@ -41,20 +44,24 @@ CGUIConfigurationWizard::CGUIConfigurationWizard(bool bEmulation, unsigned int c CThread("GUIConfigurationWizard"), m_bEmulation(bEmulation), m_controllerNumber(controllerNumber), - m_callback(nullptr) + m_actionMap(new KEYBOARD::CKeymapActionMap) { InitializeState(); } +CGUIConfigurationWizard::~CGUIConfigurationWizard(void) +{ +} + void CGUIConfigurationWizard::InitializeState(void) { m_currentButton = nullptr; m_currentDirection = JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; m_history.clear(); - m_lastMappingActionMs = 0; + m_lateAxisDetected = false; } -void CGUIConfigurationWizard::Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons, IConfigurationWizardCallback* callback) +void CGUIConfigurationWizard::Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons) { Abort(); @@ -64,7 +71,6 @@ void CGUIConfigurationWizard::Run(const std::string& strControllerId, const std: // Set Run() parameters m_strControllerId = strControllerId; m_buttons = buttons; - m_callback = callback; // Reset synchronization variables m_inputEvent.Reset(); @@ -88,7 +94,7 @@ void CGUIConfigurationWizard::OnUnfocus(IFeatureButton* button) bool CGUIConfigurationWizard::Abort(bool bWait /* = true */) { - if (IsRunning()) + if (!m_bStop) { StopThread(false); @@ -107,10 +113,10 @@ void CGUIConfigurationWizard::Process(void) { CLog::Log(LOGDEBUG, "Starting configuration wizard"); - m_lastMappingActionMs = XbmcThreads::SystemClockMillis(); - InstallHooks(); + bool bLateAxisDetected = false; + { CSingleLock lock(m_stateMutex); for (IFeatureButton* button : m_buttons) @@ -143,6 +149,8 @@ void CGUIConfigurationWizard::Process(void) break; } + bLateAxisDetected = m_lateAxisDetected; + // Finished mapping InitializeState(); } @@ -150,17 +158,27 @@ void CGUIConfigurationWizard::Process(void) for (auto callback : ButtonMapCallbacks()) callback.second->SaveButtonMap(); - bool bInMotion; - + if (bLateAxisDetected) { - CSingleLock lock(m_motionMutex); - bInMotion = !m_bInMotion.empty(); + CGUIDialogAxisDetection dialog; + dialog.Show(); } - - if (bInMotion) + else { - CLog::Log(LOGDEBUG, "Configuration wizard: waiting %ums for axes to neutralize", POST_MAPPING_WAIT_TIME_MS); - m_motionlessEvent.WaitMSec(POST_MAPPING_WAIT_TIME_MS); + // Wait for motion to stop to avoid sending analog actions for the button + // that is pressed immediately after button mapping finishes. + bool bInMotion; + + { + CSingleLock lock(m_motionMutex); + bInMotion = !m_bInMotion.empty(); + } + + if (bInMotion) + { + CLog::Log(LOGDEBUG, "Configuration wizard: waiting %ums for axes to neutralize", POST_MAPPING_WAIT_TIME_MS); + m_motionlessEvent.WaitMSec(POST_MAPPING_WAIT_TIME_MS); + } } RemoveHooks(); @@ -231,16 +249,6 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, { m_history.insert(primitive); - // Detect button skipping - unsigned int elapsed = XbmcThreads::SystemClockMillis() - m_lastMappingActionMs; - if (elapsed <= SKIPPING_DETECTION_MS) - { - CLog::Log(LOGDEBUG, "%s: Possible skip detected after %ums", m_strControllerId.c_str(), elapsed); - if (m_callback) - m_callback->OnSkipDetected(); - } - m_lastMappingActionMs = XbmcThreads::SystemClockMillis(); - OnMotion(buttonMap); m_inputEvent.Set(); } @@ -258,6 +266,14 @@ void CGUIConfigurationWizard::OnEventFrame(const JOYSTICK::IButtonMap* buttonMap OnMotionless(buttonMap); } +void CGUIConfigurationWizard::OnLateAxis(const JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) +{ + CSingleLock lock(m_stateMutex); + + m_lateAxisDetected = true; + Abort(false); +} + void CGUIConfigurationWizard::OnMotion(const JOYSTICK::IButtonMap* buttonMap) { CSingleLock lock(m_motionMutex); @@ -275,7 +291,38 @@ void CGUIConfigurationWizard::OnMotionless(const JOYSTICK::IButtonMap* buttonMap bool CGUIConfigurationWizard::OnKeyPress(const CKey& key) { - return Abort(false); + using namespace KEYBOARD; + + bool bHandled = false; + + switch (m_actionMap->GetActionID(key)) + { + case ACTION_MOVE_LEFT: + case ACTION_MOVE_RIGHT: + case ACTION_MOVE_UP: + case ACTION_MOVE_DOWN: + case ACTION_PAGE_UP: + case ACTION_PAGE_DOWN: + // Abort and allow motion + Abort(false); + bHandled = false; + break; + + case ACTION_PARENT_DIR: + case ACTION_PREVIOUS_MENU: + case ACTION_STOP: + // Abort and prevent action + Abort(false); + bHandled = true; + break; + + default: + // Absorb keypress + bHandled = true; + break; + } + + return bHandled; } bool CGUIConfigurationWizard::OnButtonPress(const std::string& button) diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.h b/xbmc/games/controllers/windows/GUIConfigurationWizard.h index b37aa1a018..a006ae5f78 100644 --- a/xbmc/games/controllers/windows/GUIConfigurationWizard.h +++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.h @@ -29,26 +29,35 @@ #include "threads/Thread.h" #include "utils/Observer.h" +#include <memory> #include <set> #include <string> #include <vector> +namespace KODI +{ +namespace KEYBOARD +{ + class IActionMap; +} +} + namespace GAME { class CGUIConfigurationWizard : public IConfigurationWizard, - public JOYSTICK::IButtonMapper, - public KEYBOARD::IKeyboardHandler, - public MOUSE::IMouseInputHandler, + public KODI::JOYSTICK::IButtonMapper, + public KODI::KEYBOARD::IKeyboardHandler, + public KODI::MOUSE::IMouseInputHandler, public Observer, protected CThread { public: CGUIConfigurationWizard(bool bEmulation, unsigned int controllerNumber = 0); - virtual ~CGUIConfigurationWizard(void) { } + virtual ~CGUIConfigurationWizard(void); // implementation of IConfigurationWizard - virtual void Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons, IConfigurationWizardCallback* callback) override; + virtual void Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons) override; virtual void OnUnfocus(IFeatureButton* button) override; virtual bool Abort(bool bWait = true) override; @@ -57,10 +66,11 @@ namespace GAME virtual bool NeedsCooldown(void) const override { return true; } virtual bool Emulation(void) const override { return m_bEmulation; } virtual unsigned int ControllerNumber(void) const override { return m_controllerNumber; } - virtual bool MapPrimitive(JOYSTICK::IButtonMap* buttonMap, - JOYSTICK::IActionMap* actionMap, - const JOYSTICK::CDriverPrimitive& primitive) override; - virtual void OnEventFrame(const JOYSTICK::IButtonMap* buttonMap, bool bMotion) override; + virtual bool MapPrimitive(KODI::JOYSTICK::IButtonMap* buttonMap, + KODI::JOYSTICK::IActionMap* actionMap, + const KODI::JOYSTICK::CDriverPrimitive& primitive) override; + virtual void OnEventFrame(const KODI::JOYSTICK::IButtonMap* buttonMap, bool bMotion) override; + virtual void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override; // implementation of IKeyboardHandler virtual bool OnKeyPress(const CKey& key) override; @@ -84,8 +94,8 @@ namespace GAME void InstallHooks(void); void RemoveHooks(void); - void OnMotion(const JOYSTICK::IButtonMap* buttonMap); - void OnMotionless(const JOYSTICK::IButtonMap* buttonMap); + void OnMotion(const KODI::JOYSTICK::IButtonMap* buttonMap); + void OnMotionless(const KODI::JOYSTICK::IButtonMap* buttonMap); // Construction parameters const bool m_bEmulation; @@ -94,19 +104,21 @@ namespace GAME // Run() parameters std::string m_strControllerId; std::vector<IFeatureButton*> m_buttons; - IConfigurationWizardCallback* m_callback; // State variables and mutex IFeatureButton* m_currentButton; - JOYSTICK::ANALOG_STICK_DIRECTION m_currentDirection; - std::set<JOYSTICK::CDriverPrimitive> m_history; // History to avoid repeated features - unsigned int m_lastMappingActionMs; // The last mapping action, or 0 if not currently mapping + KODI::JOYSTICK::ANALOG_STICK_DIRECTION m_currentDirection; + std::set<KODI::JOYSTICK::CDriverPrimitive> m_history; // History to avoid repeated features + bool m_lateAxisDetected; // Set to true if an axis is detected during button mapping CCriticalSection m_stateMutex; // Synchronization events CEvent m_inputEvent; CEvent m_motionlessEvent; CCriticalSection m_motionMutex; - std::set<const JOYSTICK::IButtonMap*> m_bInMotion; + std::set<const KODI::JOYSTICK::IButtonMap*> m_bInMotion; + + // Keyboard handling + std::unique_ptr<KODI::KEYBOARD::IActionMap> m_actionMap; }; } diff --git a/xbmc/games/controllers/windows/GUIControllerList.cpp b/xbmc/games/controllers/windows/GUIControllerList.cpp index 655c3ebc74..23379b75c6 100644 --- a/xbmc/games/controllers/windows/GUIControllerList.cpp +++ b/xbmc/games/controllers/windows/GUIControllerList.cpp @@ -32,6 +32,7 @@ #include "games/controllers/Controller.h" #include "games/controllers/guicontrols/GUIControllerButton.h" #include "games/controllers/guicontrols/GUIGameController.h" +#include "games/GameServices.h" #include "guilib/GUIButtonControl.h" #include "guilib/GUIControlGroupList.h" #include "guilib/GUIWindow.h" @@ -39,6 +40,10 @@ #include "input/joysticks/DefaultJoystick.h" // for DEFAULT_CONTROLLER_ID #include "messaging/ApplicationMessenger.h" #include "peripherals/Peripherals.h" +#include "ServiceBroker.h" + +#include <algorithm> +#include <iterator> using namespace ADDON; using namespace GAME; @@ -154,30 +159,28 @@ void CGUIControllerList::OnEvent(const ADDON::AddonEvent& event) bool CGUIControllerList::RefreshControllers(void) { - // Cache discovered add-ons between function calls - VECADDONS addonCache; - - std::set<std::string> currentIds = GetControllerIDs(); - std::set<std::string> newIds = GetNewControllerIDs(addonCache); + // Get current controllers + CGameServices& gameServices = CServiceBroker::GetGameServices(); + ControllerVector newControllers = gameServices.GetControllers(); - std::set<std::string> added; - std::set<std::string> removed; + // Check for changes + std::set<std::string> oldControllerIds; + std::set<std::string> newControllerIds; - std::set_difference(newIds.begin(), newIds.end(), currentIds.begin(), currentIds.end(), std::inserter(added, added.end())); - std::set_difference(currentIds.begin(), currentIds.end(), newIds.begin(), newIds.end(), std::inserter(removed, removed.end())); - - // Register new controllers - for (const std::string& addonId : added) - RegisterController(addonId, addonCache); + auto GetControllerID = [](const ControllerPtr& controller) + { + return controller->ID(); + }; - // Erase removed controllers - for (const std::string& addonId : removed) - UnregisterController(addonId); + std::transform(m_controllers.begin(), m_controllers.end(), std::inserter(oldControllerIds, oldControllerIds.begin()), GetControllerID); + std::transform(newControllers.begin(), newControllers.end(), std::inserter(newControllerIds, newControllerIds.begin()), GetControllerID); - // Sort add-ons, with default controller first - const bool bChanged = !added.empty() || !removed.empty(); + const bool bChanged = (oldControllerIds != newControllerIds); if (bChanged) { + m_controllers = std::move(newControllers); + + // Sort add-ons, with default controller first std::sort(m_controllers.begin(), m_controllers.end(), [](const ControllerPtr& i, const ControllerPtr& j) { @@ -191,59 +194,6 @@ bool CGUIControllerList::RefreshControllers(void) return bChanged; } -std::set<std::string> CGUIControllerList::GetControllerIDs() const -{ - std::set<std::string> controllerIds; - - std::transform(m_controllers.begin(), m_controllers.end(), std::inserter(controllerIds, controllerIds.end()), - [](const ControllerPtr& addon) - { - return addon->ID(); - }); - - return controllerIds; -} - -std::set<std::string> CGUIControllerList::GetNewControllerIDs(ADDON::VECADDONS& addonCache) const -{ - std::set<std::string> controllerIds; - - CAddonMgr::GetInstance().GetAddons(addonCache, ADDON_GAME_CONTROLLER); - - std::transform(addonCache.begin(), addonCache.end(), std::inserter(controllerIds, controllerIds.end()), - [](const AddonPtr& addon) - { - return addon->ID(); - }); - - return controllerIds; -} - -void CGUIControllerList::RegisterController(const std::string& addonId, const ADDON::VECADDONS& addonCache) -{ - auto it = std::find_if(addonCache.begin(), addonCache.end(), - [addonId](const AddonPtr& addon) - { - return addon->ID() == addonId; - }); - - if (it != addonCache.end()) - { - ControllerPtr newController = std::dynamic_pointer_cast<CController>(*it); - if (newController && newController->LoadLayout()) - m_controllers.push_back(newController); - } -} - -void CGUIControllerList::UnregisterController(const std::string& controllerId) -{ - m_controllers.erase(std::remove_if(m_controllers.begin(), m_controllers.end(), - [controllerId](const ControllerPtr& controller) - { - return controller->ID() == controllerId; - }), m_controllers.end()); -} - void CGUIControllerList::CleanupButtons(void) { if (m_controllerList) diff --git a/xbmc/games/controllers/windows/GUIControllerList.h b/xbmc/games/controllers/windows/GUIControllerList.h index fe31d44b1c..3a9b741247 100644 --- a/xbmc/games/controllers/windows/GUIControllerList.h +++ b/xbmc/games/controllers/windows/GUIControllerList.h @@ -53,9 +53,6 @@ namespace GAME private: bool RefreshControllers(void); - std::set<std::string> GetControllerIDs() const; - std::set<std::string> GetNewControllerIDs(ADDON::VECADDONS& addonCache) const; - void RegisterController(const std::string& controllerId, const ADDON::VECADDONS& addonCache); void UnregisterController(const std::string& controllerId); diff --git a/xbmc/games/controllers/windows/GUIControllerWindow.cpp b/xbmc/games/controllers/windows/GUIControllerWindow.cpp index 6fb34a82f5..7316f8758d 100644 --- a/xbmc/games/controllers/windows/GUIControllerWindow.cpp +++ b/xbmc/games/controllers/windows/GUIControllerWindow.cpp @@ -26,7 +26,7 @@ #include "addons/GUIWindowAddonBrowser.h" #include "addons/IAddon.h" #include "addons/AddonManager.h" -#include "games/controllers/dialogs/GUIDialogButtonCapture.h" +#include "games/controllers/dialogs/GUIDialogIgnoreInput.h" #include "guilib/GUIButtonControl.h" #include "guilib/GUIControl.h" #include "guilib/GUIMessage.h" @@ -322,6 +322,6 @@ void CGUIControllerWindow::ShowHelp(void) void CGUIControllerWindow::ShowButtonCaptureDialog(void) { - CGUIDialogButtonCapture dialog; + CGUIDialogIgnoreInput dialog; dialog.Show(); } diff --git a/xbmc/games/controllers/windows/GUIFeatureList.cpp b/xbmc/games/controllers/windows/GUIFeatureList.cpp index 1dcb7fcb56..9633495e91 100644 --- a/xbmc/games/controllers/windows/GUIFeatureList.cpp +++ b/xbmc/games/controllers/windows/GUIFeatureList.cpp @@ -34,6 +34,7 @@ #include "guilib/GUIWindow.h" #include "messaging/ApplicationMessenger.h" +using namespace KODI; using namespace GAME; CGUIFeatureList::CGUIFeatureList(CGUIWindow* window, const std::string& windowParam) : @@ -160,12 +161,7 @@ void CGUIFeatureList::OnSelect(unsigned int index) buttons.push_back(control); } - m_wizard->Run(m_controller->ID(), buttons, this); -} - -void CGUIFeatureList::OnSkipDetected() -{ - //! @todo + m_wizard->Run(m_controller->ID(), buttons); } IFeatureButton* CGUIFeatureList::GetButtonControl(unsigned int featureIndex) @@ -191,8 +187,8 @@ std::vector<CGUIFeatureList::FeatureGroup> CGUIFeatureList::GetFeatureGroups(con std::vector<std::string> groupNames; for (const CControllerFeature& feature : features) { - if (std::find(groupNames.begin(), groupNames.end(), feature.Group()) == groupNames.end()) - groupNames.push_back(feature.Group()); + if (std::find(groupNames.begin(), groupNames.end(), feature.CategoryLabel()) == groupNames.end()) + groupNames.push_back(feature.CategoryLabel()); } // Divide features into groups @@ -201,7 +197,7 @@ std::vector<CGUIFeatureList::FeatureGroup> CGUIFeatureList::GetFeatureGroups(con FeatureGroup group = { groupName }; for (const CControllerFeature& feature : features) { - if (feature.Group() == groupName) + if (feature.CategoryLabel() == groupName) group.features.push_back(feature); } groups.emplace_back(std::move(group)); diff --git a/xbmc/games/controllers/windows/GUIFeatureList.h b/xbmc/games/controllers/windows/GUIFeatureList.h index 307025f1fd..28c77fbd1e 100644 --- a/xbmc/games/controllers/windows/GUIFeatureList.h +++ b/xbmc/games/controllers/windows/GUIFeatureList.h @@ -31,8 +31,7 @@ class CGUIWindow; namespace GAME { - class CGUIFeatureList : public IFeatureList, - public IConfigurationWizardCallback + class CGUIFeatureList : public IFeatureList { public: CGUIFeatureList(CGUIWindow* window, const std::string& windowParam); @@ -45,9 +44,6 @@ namespace GAME virtual void OnFocus(unsigned int index) override { } virtual void OnSelect(unsigned int index) override; - // implementation of IConfigurationWizardCallback - virtual void OnSkipDetected() override; - private: IFeatureButton* GetButtonControl(unsigned int featureIndex); diff --git a/xbmc/games/controllers/windows/IConfigurationWindow.h b/xbmc/games/controllers/windows/IConfigurationWindow.h index 42a7b4d1b6..43f141640e 100644 --- a/xbmc/games/controllers/windows/IConfigurationWindow.h +++ b/xbmc/games/controllers/windows/IConfigurationWindow.h @@ -173,7 +173,7 @@ namespace GAME * \return The next direction to be prompted, or UNKNOWN if this isn't an * analog stick or the prompt is finished */ - virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const = 0; + virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const = 0; /*! * \brief Reset button after prompting for input has finished @@ -182,20 +182,6 @@ namespace GAME }; /*! - * \brief Callback handler passed to the button mapping wizard - */ - class IConfigurationWizardCallback - { - public: - virtual ~IConfigurationWizardCallback() = default; - - /*! - * \brief Called when a "skip" is detected, defined as two mapping commands within a short duration - */ - virtual void OnSkipDetected() = 0; - }; - - /*! * \brief A wizard to direct user input */ class IConfigurationWizard @@ -207,7 +193,7 @@ namespace GAME * \brief Start the wizard at the specified feature * \param featureIndex The index of the feature to start at */ - virtual void Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons, IConfigurationWizardCallback* callback) = 0; + virtual void Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons) = 0; /*! * \brief Callback for feature losing focus diff --git a/xbmc/games/ports/PortManager.cpp b/xbmc/games/ports/PortManager.cpp index 5eafc923f9..6809e00959 100644 --- a/xbmc/games/ports/PortManager.cpp +++ b/xbmc/games/ports/PortManager.cpp @@ -26,6 +26,7 @@ #include <algorithm> +using namespace KODI; using namespace GAME; using namespace JOYSTICK; using namespace PERIPHERALS; diff --git a/xbmc/games/ports/PortManager.h b/xbmc/games/ports/PortManager.h index 289c9ee935..b466ca8814 100644 --- a/xbmc/games/ports/PortManager.h +++ b/xbmc/games/ports/PortManager.h @@ -26,8 +26,18 @@ #include <map> #include <vector> -namespace JOYSTICK { class IInputHandler; } -namespace PERIPHERALS { class CPeripheral; } +namespace KODI +{ +namespace JOYSTICK +{ + class IInputHandler; +} +} + +namespace PERIPHERALS +{ + class CPeripheral; +} namespace GAME { @@ -50,7 +60,7 @@ namespace GAME * \param port The port number belonging to the game client * \param requiredType Used to restrict port to devices of only a certain type */ - void OpenPort(JOYSTICK::IInputHandler* handler, + void OpenPort(KODI::JOYSTICK::IInputHandler* handler, unsigned int port, PERIPHERALS::PeripheralType requiredType = PERIPHERALS::PERIPHERAL_UNKNOWN); @@ -59,7 +69,7 @@ namespace GAME * * \param handler The handler used to open the port */ - void ClosePort(JOYSTICK::IInputHandler* handler); + void ClosePort(KODI::JOYSTICK::IInputHandler* handler); /*! * \brief Map a list of devices to the available ports @@ -72,14 +82,14 @@ namespace GAME * attempt to honor that request. */ void MapDevices(const PERIPHERALS::PeripheralVector& devices, - std::map<PERIPHERALS::PeripheralPtr, JOYSTICK::IInputHandler*>& deviceToPortMap); + std::map<PERIPHERALS::PeripheralPtr, KODI::JOYSTICK::IInputHandler*>& deviceToPortMap); private: - JOYSTICK::IInputHandler* AssignToPort(const PERIPHERALS::PeripheralPtr& device, bool checkPortNumber = true); + KODI::JOYSTICK::IInputHandler* AssignToPort(const PERIPHERALS::PeripheralPtr& device, bool checkPortNumber = true); struct SPort { - JOYSTICK::IInputHandler* handler; // Input handler for this port + KODI::JOYSTICK::IInputHandler* handler; // Input handler for this port unsigned int port; // Port number belonging to the game client PERIPHERALS::PeripheralType requiredType; void* device; diff --git a/xbmc/games/ports/PortMapper.cpp b/xbmc/games/ports/PortMapper.cpp index 2471c39a2b..282eb513ef 100644 --- a/xbmc/games/ports/PortMapper.cpp +++ b/xbmc/games/ports/PortMapper.cpp @@ -23,6 +23,7 @@ #include "peripherals/devices/Peripheral.h" #include "peripherals/Peripherals.h" +using namespace KODI; using namespace GAME; using namespace JOYSTICK; using namespace PERIPHERALS; diff --git a/xbmc/games/ports/PortMapper.h b/xbmc/games/ports/PortMapper.h index 60330039a2..4d14445812 100644 --- a/xbmc/games/ports/PortMapper.h +++ b/xbmc/games/ports/PortMapper.h @@ -24,7 +24,14 @@ #include <map> -namespace JOYSTICK { class IInputHandler; } +namespace KODI +{ +namespace JOYSTICK +{ + class IInputHandler; +} +} + namespace GAME { class CPortMapper : public Observer @@ -39,6 +46,6 @@ namespace GAME private: void ProcessPeripherals(); - std::map<PERIPHERALS::PeripheralPtr, JOYSTICK::IInputHandler*> m_portMap; + std::map<PERIPHERALS::PeripheralPtr, KODI::JOYSTICK::IInputHandler*> m_portMap; }; } diff --git a/xbmc/guilib/GUIKeyboardFactory.cpp b/xbmc/guilib/GUIKeyboardFactory.cpp index 2cf6b82cf0..9ddada904b 100644 --- a/xbmc/guilib/GUIKeyboardFactory.cpp +++ b/xbmc/guilib/GUIKeyboardFactory.cpp @@ -38,7 +38,7 @@ using namespace KODI::MESSAGING; -CGUIKeyboard *CGUIKeyboardFactory::g_activedKeyboard = NULL; +CGUIKeyboard *CGUIKeyboardFactory::g_activeKeyboard = NULL; FILTERING CGUIKeyboardFactory::m_filtering = FILTERING_NONE; CGUIKeyboardFactory::CGUIKeyboardFactory(void) @@ -75,9 +75,9 @@ void CGUIKeyboardFactory::keyTypedCB(CGUIKeyboard *ref, const std::string &typed bool CGUIKeyboardFactory::SendTextToActiveKeyboard(const std::string &aTextString, bool closeKeyboard /* = false */) { - if (!g_activedKeyboard) + if (!g_activeKeyboard) return false; - return g_activedKeyboard->SetTextToKeyboard(aTextString, closeKeyboard); + return g_activeKeyboard->SetTextToKeyboard(aTextString, closeKeyboard); } @@ -103,10 +103,10 @@ bool CGUIKeyboardFactory::ShowAndGetInput(std::string& aTextString, CVariant hea if (kb) { - g_activedKeyboard = kb; + g_activeKeyboard = kb; kb->startAutoCloseTimer(autoCloseMs); confirmed = kb->ShowAndGetInput(keyTypedCB, aTextString, aTextString, headingStr, hiddenInput); - g_activedKeyboard = NULL; + g_activeKeyboard = NULL; } if (confirmed) diff --git a/xbmc/guilib/GUIKeyboardFactory.h b/xbmc/guilib/GUIKeyboardFactory.h index 425af674fa..263799f9b2 100644 --- a/xbmc/guilib/GUIKeyboardFactory.h +++ b/xbmc/guilib/GUIKeyboardFactory.h @@ -43,9 +43,9 @@ class CGUIKeyboardFactory static bool SendTextToActiveKeyboard(const std::string &aTextString, bool closeKeyboard = false); - static bool isKeyboardActivated() { return g_activedKeyboard != NULL; } + static bool isKeyboardActivated() { return g_activeKeyboard != NULL; } private: - static CGUIKeyboard *g_activedKeyboard; + static CGUIKeyboard *g_activeKeyboard; static FILTERING m_filtering; static void keyTypedCB(CGUIKeyboard *ref, const std::string &typedString); }; diff --git a/xbmc/guilib/GUIMultiImage.cpp b/xbmc/guilib/GUIMultiImage.cpp index 4d43531401..83b8839637 100644 --- a/xbmc/guilib/GUIMultiImage.cpp +++ b/xbmc/guilib/GUIMultiImage.cpp @@ -315,7 +315,7 @@ bool CGUIMultiImage::CMultiImageJob::DoWork() URIUtils::AddSlashAtEnd(realPath); CFileItemList items; - CDirectory::GetDirectory(realPath, items, g_advancedSettings.m_pictureExtensions + "|.tbn|.dds", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_NO_FILE_INFO); + CDirectory::GetDirectory(realPath, items, g_advancedSettings.GetPictureExtensions()+ "|.tbn|.dds", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_NO_FILE_INFO); for (int i=0; i < items.Size(); i++) { CFileItem* pItem = items[i].get(); diff --git a/xbmc/guilib/GUISliderControl.h b/xbmc/guilib/GUISliderControl.h index 717be42376..196ef2586a 100644 --- a/xbmc/guilib/GUISliderControl.h +++ b/xbmc/guilib/GUISliderControl.h @@ -86,6 +86,7 @@ public: void SetIntInterval(int iInterval); void SetFloatInterval(float fInterval); void SetType(int iType) { m_iType = iType; }; + int GetType() const { return m_iType; } virtual std::string GetDescription() const; void SetTextValue(const std::string &textValue) { m_textValue = textValue; }; void SetAction(const std::string &action); diff --git a/xbmc/guilib/TextureFormats.h b/xbmc/guilib/TextureFormats.h new file mode 100644 index 0000000000..ee8b68dc37 --- /dev/null +++ b/xbmc/guilib/TextureFormats.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#define XB_FMT_MASK 0xffff ///< mask for format info - other flags are outside this +#define XB_FMT_DXT_MASK 15 +#define XB_FMT_UNKNOWN 0 +#define XB_FMT_DXT1 1 +#define XB_FMT_DXT3 2 +#define XB_FMT_DXT5 4 +#define XB_FMT_DXT5_YCoCg 8 +#define XB_FMT_A8R8G8B8 16 // texture.xbt byte order (matches BGRA8) +#define XB_FMT_A8 32 +#define XB_FMT_RGBA8 64 +#define XB_FMT_RGB8 128 +#define XB_FMT_OPAQUE 65536 diff --git a/xbmc/guilib/XBTF.h b/xbmc/guilib/XBTF.h index 53dc6d997e..4e6499ad80 100644 --- a/xbmc/guilib/XBTF.h +++ b/xbmc/guilib/XBTF.h @@ -28,18 +28,7 @@ static const std::string XBTF_MAGIC = "XBTF"; static const std::string XBTF_VERSION = "2"; -#define XB_FMT_MASK 0xffff ///< mask for format info - other flags are outside this -#define XB_FMT_DXT_MASK 15 -#define XB_FMT_UNKNOWN 0 -#define XB_FMT_DXT1 1 -#define XB_FMT_DXT3 2 -#define XB_FMT_DXT5 4 -#define XB_FMT_DXT5_YCoCg 8 -#define XB_FMT_A8R8G8B8 16 // texture.xbt byte order (matches BGRA8) -#define XB_FMT_A8 32 -#define XB_FMT_RGBA8 64 -#define XB_FMT_RGB8 128 -#define XB_FMT_OPAQUE 65536 +#include "TextureFormats.h" class CXBTFFrame { diff --git a/xbmc/guilib/imagefactory.cpp b/xbmc/guilib/imagefactory.cpp index 1500dfdba0..beb9d79ccd 100644 --- a/xbmc/guilib/imagefactory.cpp +++ b/xbmc/guilib/imagefactory.cpp @@ -20,7 +20,15 @@ #include "imagefactory.h" #include "guilib/FFmpegImage.h" +#include "addons/BinaryAddonCache.h" +#include "addons/ImageDecoder.h" #include "utils/Mime.h" +#include "utils/StringUtils.h" +#include "ServiceBroker.h" + +#include <algorithm> + +using namespace ADDON; IImage* ImageFactory::CreateLoader(const std::string& strFileName) { @@ -38,5 +46,20 @@ IImage* ImageFactory::CreateLoader(const CURL& url) IImage* ImageFactory::CreateLoaderFromMimeType(const std::string& strMimeType) { + VECADDONS codecs; + ADDON::CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache(); + addonCache.GetAddons(codecs, ADDON::ADDON_IMAGEDECODER); + for (auto& codec : codecs) + { + std::shared_ptr<CImageDecoder> enc(std::static_pointer_cast<CImageDecoder>(codec)); + std::vector<std::string> mime = StringUtils::Split(enc->GetMimetypes(), "|"); + if (std::find(mime.begin(), mime.end(), strMimeType) != mime.end()) + { + CImageDecoder* result = new CImageDecoder(*enc); + result->Create(strMimeType); + return result; + } + } + return new CFFmpegImage(strMimeType); } diff --git a/xbmc/input/Action.cpp b/xbmc/input/Action.cpp new file mode 100644 index 0000000000..5bab5ae99f --- /dev/null +++ b/xbmc/input/Action.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "Action.h" +#include "ActionIDs.h" +#include "ButtonTranslator.h" +#include "Key.h" + +CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const std::string &name /* = "" */, unsigned int holdTime /*= 0*/) +{ + m_id = actionID; + m_amount[0] = amount1; + m_amount[1] = amount2; + for (unsigned int i = 2; i < max_amounts; i++) + m_amount[i] = 0; + m_name = name; + m_repeat = 0; + m_buttonCode = 0; + m_unicode = 0; + m_holdTime = holdTime; +} + +CAction::CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name): + m_name(name) +{ + m_id = actionID; + m_amount[0] = posX; + m_amount[1] = posY; + m_amount[2] = offsetX; + m_amount[3] = offsetY; + for (unsigned int i = 4; i < max_amounts; i++) + m_amount[i] = 0; + m_repeat = 0; + m_buttonCode = 0; + m_unicode = 0; + m_holdTime = state; +} + +CAction::CAction(int actionID, wchar_t unicode) +{ + m_id = actionID; + for (unsigned int i = 0; i < max_amounts; i++) + m_amount[i] = 0; + m_repeat = 0; + m_buttonCode = 0; + m_unicode = unicode; + m_holdTime = 0; +} + +CAction::CAction(int actionID, const std::string &name, const CKey &key): + m_name(name) +{ + m_id = actionID; + m_amount[0] = 1; // digital button (could change this for repeat acceleration) + for (unsigned int i = 1; i < max_amounts; i++) + m_amount[i] = 0; + m_repeat = key.GetRepeat(); + m_buttonCode = key.GetButtonCode(); + m_unicode = 0; + m_holdTime = key.GetHeld(); + // get the action amounts of the analog buttons + if (key.GetButtonCode() == KEY_BUTTON_LEFT_ANALOG_TRIGGER) + m_amount[0] = (float)key.GetLeftTrigger() / 255.0f; + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_ANALOG_TRIGGER) + m_amount[0] = (float)key.GetRightTrigger() / 255.0f; + else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK) + { + m_amount[0] = key.GetLeftThumbX(); + m_amount[1] = key.GetLeftThumbY(); + } + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK) + { + m_amount[0] = key.GetRightThumbX(); + m_amount[1] = key.GetRightThumbY(); + } + else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_UP) + m_amount[0] = key.GetLeftThumbY(); + else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_DOWN) + m_amount[0] = -key.GetLeftThumbY(); + else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_LEFT) + m_amount[0] = -key.GetLeftThumbX(); + else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_RIGHT) + m_amount[0] = key.GetLeftThumbX(); + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_UP) + m_amount[0] = key.GetRightThumbY(); + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_DOWN) + m_amount[0] = -key.GetRightThumbY(); + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_LEFT) + m_amount[0] = -key.GetRightThumbX(); + else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_RIGHT) + m_amount[0] = key.GetRightThumbX(); +} + +CAction::CAction(int actionID, const std::string &name): + m_name(name) +{ + m_id = actionID; + for (unsigned int i = 0; i < max_amounts; i++) + m_amount[i] = 0; + m_repeat = 0; + m_buttonCode = 0; + m_unicode = 0; + m_holdTime = 0; +} + +CAction& CAction::operator=(const CAction& rhs) +{ + if (this != &rhs) + { + m_id = rhs.m_id; + for (unsigned int i = 0; i < max_amounts; i++) + m_amount[i] = rhs.m_amount[i]; + m_name = rhs.m_name; + m_repeat = rhs.m_repeat; + m_buttonCode = rhs.m_buttonCode; + m_unicode = rhs.m_unicode; + m_holdTime = rhs.m_holdTime; + m_text = rhs.m_text; + } + return *this; +} + +bool CAction::IsMouse() const +{ + return (m_id >= ACTION_MOUSE_START && m_id <= ACTION_MOUSE_END); +} + +bool CAction::IsGesture() const +{ + return (m_id >= ACTION_GESTURE_NOTIFY && m_id <= ACTION_GESTURE_END); +} + +bool CAction::IsAnalog() const +{ + return CButtonTranslator::IsAnalog(m_id); +} diff --git a/xbmc/input/Action.h b/xbmc/input/Action.h new file mode 100644 index 0000000000..e6941652a8 --- /dev/null +++ b/xbmc/input/Action.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include <string> + +#ifndef SWIG + +class CKey; + +/*! + \ingroup actionkeys + \brief class encapsulating information regarding a particular user action to be sent to windows and controls + */ +class CAction +{ +public: + CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const std::string &name = "", unsigned int holdTime = 0); + CAction(int actionID, wchar_t unicode); + CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name = ""); + CAction(int actionID, const std::string &name, const CKey &key); + CAction(int actionID, const std::string &name); + + CAction(const CAction& other) { *this = other; } + CAction& operator=(const CAction& rhs); + + /*! \brief Identifier of the action + \return id of the action + */ + int GetID() const { return m_id; }; + + /*! \brief Is this an action from the mouse + \return true if this is a mouse action, false otherwise + */ + bool IsMouse() const; + + bool IsGesture() const; + + /*! \brief Human-readable name of the action + \return name of the action + */ + const std::string &GetName() const { return m_name; }; + + /*! \brief Text of the action if any + \return text payload of this action. + */ + const std::string &GetText() const { return m_text; }; + + /*! \brief Set the text payload of the action + \param text to be set + */ + void SetText(const std::string &text) { m_text = text; }; + + /*! \brief Get an amount associated with this action + \param zero-based index of amount to retrieve, defaults to 0 + \return an amount associated with this action + */ + float GetAmount(unsigned int index = 0) const { return (index < max_amounts) ? m_amount[index] : 0; }; + + /*! \brief Unicode value associated with this action + \return unicode value associated with this action, for keyboard input. + */ + wchar_t GetUnicode() const { return m_unicode; }; + + /*! \brief Time in ms that the key has been held + \return time that the key has been held down in ms. + */ + unsigned int GetHoldTime() const { return m_holdTime; }; + + /*! \brief Time since last repeat in ms + \return time since last repeat in ms. Returns 0 if unknown. + */ + float GetRepeat() const { return m_repeat; }; + + /*! \brief Button code that triggered this action + \return button code + */ + unsigned int GetButtonCode() const { return m_buttonCode; }; + + bool IsAnalog() const; + +private: + int m_id; + std::string m_name; + + static const unsigned int max_amounts = 4; // Must be at least 4. + float m_amount[max_amounts]; + + float m_repeat; + unsigned int m_holdTime; + unsigned int m_buttonCode; + wchar_t m_unicode; + std::string m_text; +}; + +#endif diff --git a/xbmc/input/ActionIDs.h b/xbmc/input/ActionIDs.h new file mode 100644 index 0000000000..986f275a53 --- /dev/null +++ b/xbmc/input/ActionIDs.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +/** + * \defgroup kodi_key_action_ids Action Id's + * \ingroup python_xbmcgui_window_cb + * \ingroup python_xbmcgui_action + * @{ + * @brief Actions that we have defined. + */ +#define ACTION_NONE 0 +#define ACTION_MOVE_LEFT 1 +#define ACTION_MOVE_RIGHT 2 +#define ACTION_MOVE_UP 3 +#define ACTION_MOVE_DOWN 4 +#define ACTION_PAGE_UP 5 +#define ACTION_PAGE_DOWN 6 +#define ACTION_SELECT_ITEM 7 +#define ACTION_HIGHLIGHT_ITEM 8 +#define ACTION_PARENT_DIR 9 +#define ACTION_PREVIOUS_MENU 10 +#define ACTION_SHOW_INFO 11 + +#define ACTION_PAUSE 12 +#define ACTION_STOP 13 +#define ACTION_NEXT_ITEM 14 +#define ACTION_PREV_ITEM 15 +#define ACTION_FORWARD 16 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_* +#define ACTION_REWIND 17 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_* + +#define ACTION_SHOW_GUI 18 //!< toggle between GUI and movie or GUI and visualisation. +#define ACTION_ASPECT_RATIO 19 //!< toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005 +#define ACTION_STEP_FORWARD 20 //!< seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_STEP_BACK 21 //!< seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_BIG_STEP_FORWARD 22 //!< seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_BIG_STEP_BACK 23 //!< seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_SHOW_OSD 24 //!< show/hide OSD. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_SHOW_SUBTITLES 25 //!< turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_NEXT_SUBTITLE 26 //!< switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_PLAYER_DEBUG 27 //!< show debug info for VideoPlayer +#define ACTION_NEXT_PICTURE 28 //!< show next picture of slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_PREV_PICTURE 29 //!< show previous picture of slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_OUT 30 //!< zoom in picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_IN 31 //!< zoom out picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_TOGGLE_SOURCE_DEST 32 //!< used to toggle between source view and destination view. Can be used in myfiles.xml window id=3 +#define ACTION_SHOW_PLAYLIST 33 //!< used to toggle between current view and playlist view. Can b used in all mymusic xml files +#define ACTION_QUEUE_ITEM 34 //!< used to queue a item to the playlist. Can b used in all mymusic xml files +#define ACTION_REMOVE_ITEM 35 //!< not used anymore +#define ACTION_SHOW_FULLSCREEN 36 //!< not used anymore +#define ACTION_ZOOM_LEVEL_NORMAL 37 //!< zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_1 38 //!< zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_2 39 //!< zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_3 40 //!< zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_4 41 //!< zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_5 42 //!< zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_6 43 //!< zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_7 44 //!< zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_8 45 //!< zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007 +#define ACTION_ZOOM_LEVEL_9 46 //!< zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007 + +#define ACTION_CALIBRATE_SWAP_ARROWS 47 //!< select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11 +#define ACTION_CALIBRATE_RESET 48 //!< reset calibration to defaults. Can b used in: `settingsScreenCalibration.xml` windowid=11/settingsUICalibration.xml windowid=10 +#define ACTION_ANALOG_MOVE 49 //!< analog thumbstick move. Can b used in: `slideshow.xml` windowid=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10 + //!< @note see also ACTION_ANALOG_MOVE_X, ACTION_ANALOG_MOVE_Y +#define ACTION_ROTATE_PICTURE_CW 50 //!< rotate current picture clockwise during slideshow. Can be used in slideshow.xml window id=2007 +#define ACTION_ROTATE_PICTURE_CCW 51 //!< rotate current picture counterclockwise during slideshow. Can be used in slideshow.xml window id=2007 + +#define ACTION_SUBTITLE_DELAY_MIN 52 //!< Decrease subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_SUBTITLE_DELAY_PLUS 53 //!< Increase subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_AUDIO_DELAY_MIN 54 //!< Increase avsync delay. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_AUDIO_DELAY_PLUS 55 //!< Decrease avsync delay. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_AUDIO_NEXT_LANGUAGE 56 //!< Select next language in movie. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_CHANGE_RESOLUTION 57 //!< switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11 + +#define REMOTE_0 58 //!< remote keys 0-9. are used by multiple windows +#define REMOTE_1 59 //!< for example in videoFullScreen.xml window id=2005 you can +#define REMOTE_2 60 //!< enter time (mmss) to jump to particular point in the movie +#define REMOTE_3 61 +#define REMOTE_4 62 //!< with spincontrols you can enter 3digit number to quickly set +#define REMOTE_5 63 //!< spincontrol to desired value +#define REMOTE_6 64 +#define REMOTE_7 65 +#define REMOTE_8 66 +#define REMOTE_9 67 + +#define ACTION_PLAY 68 //!< Unused at the moment +#define ACTION_PLAYER_PROCESS_INFO 69 //!< show player process info (video decoder, pixel format, pvr signal strength and the like +#define ACTION_SMALL_STEP_BACK 76 //!< jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005 + +#define ACTION_PLAYER_FORWARD 77 //!< FF in current file played. global action, can be used anywhere +#define ACTION_PLAYER_REWIND 78 //!< RW in current file played. global action, can be used anywhere +#define ACTION_PLAYER_PLAY 79 //!< Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere + +#define ACTION_DELETE_ITEM 80 //!< delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25 +#define ACTION_COPY_ITEM 81 //!< copy current selected item. Can be used in myfiles.xml window id=3 +#define ACTION_MOVE_ITEM 82 //!< move current selected item. Can be used in myfiles.xml window id=3 +#define ACTION_TAKE_SCREENSHOT 85 //!< take a screenshot +#define ACTION_RENAME_ITEM 87 //!< rename item + +#define ACTION_VOLUME_UP 88 +#define ACTION_VOLUME_DOWN 89 +#define ACTION_VOLAMP 90 +#define ACTION_MUTE 91 +#define ACTION_NAV_BACK 92 +#define ACTION_VOLAMP_UP 93 +#define ACTION_VOLAMP_DOWN 94 + +#define ACTION_CREATE_EPISODE_BOOKMARK 95 //!< Creates an episode bookmark on the currently playing video file containing more than one episode +#define ACTION_CREATE_BOOKMARK 96 //!< Creates a bookmark of the currently playing video file + +#define ACTION_CHAPTER_OR_BIG_STEP_FORWARD 97 //!< Goto the next chapter, if not available perform a big step forward +#define ACTION_CHAPTER_OR_BIG_STEP_BACK 98 //!< Goto the previous chapter, if not available perform a big step back + +#define ACTION_CYCLE_SUBTITLE 99 //!< switch to next subtitle of movie, but will not enable/disable the subtitles. Can be used in videoFullScreen.xml window id=2005 + +#define ACTION_MOUSE_START 100 +#define ACTION_MOUSE_LEFT_CLICK 100 +#define ACTION_MOUSE_RIGHT_CLICK 101 +#define ACTION_MOUSE_MIDDLE_CLICK 102 +#define ACTION_MOUSE_DOUBLE_CLICK 103 +#define ACTION_MOUSE_WHEEL_UP 104 +#define ACTION_MOUSE_WHEEL_DOWN 105 +#define ACTION_MOUSE_DRAG 106 +#define ACTION_MOUSE_MOVE 107 +#define ACTION_MOUSE_LONG_CLICK 108 +#define ACTION_MOUSE_END 109 + +#define ACTION_BACKSPACE 110 +#define ACTION_SCROLL_UP 111 +#define ACTION_SCROLL_DOWN 112 +#define ACTION_ANALOG_FORWARD 113 +#define ACTION_ANALOG_REWIND 114 + +#define ACTION_MOVE_ITEM_UP 115 //!< move item up in playlist +#define ACTION_MOVE_ITEM_DOWN 116 //!< move item down in playlist +#define ACTION_CONTEXT_MENU 117 //!< pops up the context menu + +// stuff for virtual keyboard shortcuts +#define ACTION_SHIFT 118 //!< stuff for virtual keyboard shortcuts +#define ACTION_SYMBOLS 119 //!< stuff for virtual keyboard shortcuts +#define ACTION_CURSOR_LEFT 120 //!< stuff for virtual keyboard shortcuts +#define ACTION_CURSOR_RIGHT 121 //!< stuff for virtual keyboard shortcuts + +#define ACTION_BUILT_IN_FUNCTION 122 + +#define ACTION_SHOW_OSD_TIME 123 //!< displays current time, can be used in videoFullScreen.xml window id=2005 +#define ACTION_ANALOG_SEEK_FORWARD 124 //!< seeks forward, and displays the seek bar. +#define ACTION_ANALOG_SEEK_BACK 125 //!< seeks backward, and displays the seek bar. + +#define ACTION_VIS_PRESET_SHOW 126 +#define ACTION_VIS_PRESET_NEXT 128 +#define ACTION_VIS_PRESET_PREV 129 +#define ACTION_VIS_PRESET_LOCK 130 +#define ACTION_VIS_PRESET_RANDOM 131 +#define ACTION_VIS_RATE_PRESET_PLUS 132 +#define ACTION_VIS_RATE_PRESET_MINUS 133 + +#define ACTION_SHOW_VIDEOMENU 134 +#define ACTION_ENTER 135 + +#define ACTION_INCREASE_RATING 136 +#define ACTION_DECREASE_RATING 137 + +#define ACTION_NEXT_SCENE 138 //!< switch to next scene/cutpoint in movie +#define ACTION_PREV_SCENE 139 //!< switch to previous scene/cutpoint in movie + +#define ACTION_NEXT_LETTER 140 //!< jump through a list or container by letter +#define ACTION_PREV_LETTER 141 + +#define ACTION_JUMP_SMS2 142 //!< jump direct to a particular letter using SMS-style input +#define ACTION_JUMP_SMS3 143 +#define ACTION_JUMP_SMS4 144 +#define ACTION_JUMP_SMS5 145 +#define ACTION_JUMP_SMS6 146 +#define ACTION_JUMP_SMS7 147 +#define ACTION_JUMP_SMS8 148 +#define ACTION_JUMP_SMS9 149 + +#define ACTION_FILTER_CLEAR 150 +#define ACTION_FILTER_SMS2 151 +#define ACTION_FILTER_SMS3 152 +#define ACTION_FILTER_SMS4 153 +#define ACTION_FILTER_SMS5 154 +#define ACTION_FILTER_SMS6 155 +#define ACTION_FILTER_SMS7 156 +#define ACTION_FILTER_SMS8 157 +#define ACTION_FILTER_SMS9 158 + +#define ACTION_FIRST_PAGE 159 +#define ACTION_LAST_PAGE 160 + +#define ACTION_AUDIO_DELAY 161 +#define ACTION_SUBTITLE_DELAY 162 +#define ACTION_MENU 163 + +#define ACTION_SET_RATING 164 + +#define ACTION_RECORD 170 + +#define ACTION_PASTE 180 +#define ACTION_NEXT_CONTROL 181 +#define ACTION_PREV_CONTROL 182 +#define ACTION_CHANNEL_SWITCH 183 +#define ACTION_CHANNEL_UP 184 +#define ACTION_CHANNEL_DOWN 185 +#define ACTION_NEXT_CHANNELGROUP 186 +#define ACTION_PREVIOUS_CHANNELGROUP 187 +#define ACTION_PVR_PLAY 188 +#define ACTION_PVR_PLAY_TV 189 +#define ACTION_PVR_PLAY_RADIO 190 +#define ACTION_PVR_SHOW_TIMER_RULE 191 + +#define ACTION_TOGGLE_FULLSCREEN 199 //!< switch 2 desktop resolution +#define ACTION_TOGGLE_WATCHED 200 //!< Toggle watched status (videos) +#define ACTION_SCAN_ITEM 201 //!< scan item +#define ACTION_TOGGLE_DIGITAL_ANALOG 202 //!< switch digital <-> analog +#define ACTION_RELOAD_KEYMAPS 203 //!< reloads CButtonTranslator's keymaps +#define ACTION_GUIPROFILE_BEGIN 204 //!< start the GUIControlProfiler running + +#define ACTION_TELETEXT_RED 215 //!< Teletext Color button <b>Red</b> to control TopText +#define ACTION_TELETEXT_GREEN 216 //!< Teletext Color button <b>Green</b> to control TopText +#define ACTION_TELETEXT_YELLOW 217 //!< Teletext Color button <b>Yellow</b> to control TopText +#define ACTION_TELETEXT_BLUE 218 //!< Teletext Color button <b>Blue</b> to control TopText + +#define ACTION_INCREASE_PAR 219 +#define ACTION_DECREASE_PAR 220 + +#define ACTION_VSHIFT_UP 227 //!< shift up video image in VideoPlayer +#define ACTION_VSHIFT_DOWN 228 //!< shift down video image in VideoPlayer + +#define ACTION_PLAYER_PLAYPAUSE 229 //!< Play/pause. If playing it pauses, if paused it plays. + +#define ACTION_SUBTITLE_VSHIFT_UP 230 //!< shift up subtitles in VideoPlayer +#define ACTION_SUBTITLE_VSHIFT_DOWN 231 //!< shift down subtitles in VideoPlayer +#define ACTION_SUBTITLE_ALIGN 232 //!< toggle vertical alignment of subtitles + +#define ACTION_FILTER 233 + +#define ACTION_SWITCH_PLAYER 234 + +#define ACTION_STEREOMODE_NEXT 235 +#define ACTION_STEREOMODE_PREVIOUS 236 +#define ACTION_STEREOMODE_TOGGLE 237 //!< turns 3d mode on/off +#define ACTION_STEREOMODE_SELECT 238 +#define ACTION_STEREOMODE_TOMONO 239 +#define ACTION_STEREOMODE_SET 240 + +#define ACTION_SETTINGS_RESET 241 +#define ACTION_SETTINGS_LEVEL_CHANGE 242 + +#define ACTION_TRIGGER_OSD 243 //!< show autoclosing OSD. Can b used in videoFullScreen.xml window id=2005 +#define ACTION_INPUT_TEXT 244 +#define ACTION_VOLUME_SET 245 +#define ACTION_TOGGLE_COMMSKIP 246 + +#define ACTION_TOUCH_TAP 401 //!< touch actions +#define ACTION_TOUCH_TAP_TEN 410 //!< touch actions +#define ACTION_TOUCH_LONGPRESS 411 //!< touch actions +#define ACTION_TOUCH_LONGPRESS_TEN 420 //!< touch actions + +#define ACTION_GESTURE_NOTIFY 500 +#define ACTION_GESTURE_BEGIN 501 +#define ACTION_GESTURE_ZOOM 502 //!< sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0) +#define ACTION_GESTURE_ROTATE 503 +#define ACTION_GESTURE_PAN 504 + +#define ACTION_GESTURE_SWIPE_LEFT 511 +#define ACTION_GESTURE_SWIPE_LEFT_TEN 520 +#define ACTION_GESTURE_SWIPE_RIGHT 521 +#define ACTION_GESTURE_SWIPE_RIGHT_TEN 530 +#define ACTION_GESTURE_SWIPE_UP 531 +#define ACTION_GESTURE_SWIPE_UP_TEN 540 +#define ACTION_GESTURE_SWIPE_DOWN 541 +#define ACTION_GESTURE_SWIPE_DOWN_TEN 550 +// 5xx is reserved for additional gesture actions +#define ACTION_GESTURE_END 599 + +// other, non-gesture actions +#define ACTION_ANALOG_MOVE_X 601 //!< analog thumbstick move, horizontal axis; see ACTION_ANALOG_MOVE +#define ACTION_ANALOG_MOVE_Y 602 //!< analog thumbstick move, vertical axis; see ACTION_ANALOG_MOVE +//@} + +// The NOOP action can be specified to disable an input event. This is +// useful in user keyboard.xml etc to disable actions specified in the +// system mappings. ERROR action is used to play an error sound +#define ACTION_ERROR 998 +#define ACTION_NOOP 999 diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp index cbd7062094..cc628c0316 100644 --- a/xbmc/input/ButtonTranslator.cpp +++ b/xbmc/input/ButtonTranslator.cpp @@ -911,7 +911,7 @@ CAction CButtonTranslator::GetGlobalAction(const CKey &key) return GetAction(-1, key, true); } -bool CButtonTranslator::HasLonpressMapping(int window, const CKey &key) +bool CButtonTranslator::HasLongpressMapping(int window, const CKey &key) { std::map<int, buttonMap>::const_iterator it = m_translatorMap.find(window); if (it != m_translatorMap.end()) @@ -921,7 +921,7 @@ bool CButtonTranslator::HasLonpressMapping(int window, const CKey &key) buttonMap::const_iterator it2 = (*it).second.find(code); if (it2 != (*it).second.end()) - return true; + return it2->second.id != ACTION_NOOP; #ifdef TARGET_POSIX // Some buttoncodes changed in Hardy @@ -940,11 +940,11 @@ bool CButtonTranslator::HasLonpressMapping(int window, const CKey &key) { // first check if we have a fallback for the window int fallbackWindow = GetFallbackWindow(window); - if (fallbackWindow > -1 && HasLonpressMapping(fallbackWindow, key)) + if (fallbackWindow > -1 && HasLongpressMapping(fallbackWindow, key)) return true; // fallback to default section - return HasLonpressMapping(-1, key); + return HasLongpressMapping(-1, key); } return false; diff --git a/xbmc/input/ButtonTranslator.h b/xbmc/input/ButtonTranslator.h index 1cbac59453..0ccd82ebc6 100644 --- a/xbmc/input/ButtonTranslator.h +++ b/xbmc/input/ButtonTranslator.h @@ -79,7 +79,7 @@ public: \param key to search a mapping for \return true if a longpress mapping exists */ - bool HasLonpressMapping(int window, const CKey &key); + bool HasLongpressMapping(int window, const CKey &key); /*! \brief Obtain the action configured for a given window and key \param window the window id diff --git a/xbmc/input/CMakeLists.txt b/xbmc/input/CMakeLists.txt index a961423028..a1fec26d31 100644 --- a/xbmc/input/CMakeLists.txt +++ b/xbmc/input/CMakeLists.txt @@ -1,4 +1,5 @@ -set(SOURCES ButtonTranslator.cpp +set(SOURCES Action.cpp + ButtonTranslator.cpp InertialScrollingHandler.cpp InputCodingTableBaiduPY.cpp InputCodingTableBasePY.cpp @@ -12,7 +13,9 @@ set(SOURCES ButtonTranslator.cpp MouseStat.cpp XBMC_keytable.cpp) -set(HEADERS ButtonTranslator.h +set(HEADERS Action.h + ActionIDs.h + ButtonTranslator.h InertialScrollingHandler.h InputCodingTable.h InputCodingTableBaiduPY.h diff --git a/xbmc/input/InputManager.cpp b/xbmc/input/InputManager.cpp index 4f1663fed9..b24387ec82 100644 --- a/xbmc/input/InputManager.cpp +++ b/xbmc/input/InputManager.cpp @@ -70,7 +70,8 @@ using EVENTSERVER::CEventServer; #endif -using namespace KODI::MESSAGING; +using namespace KODI; +using namespace MESSAGING; using PERIPHERALS::CPeripherals; CInputManager::CInputManager() : @@ -368,7 +369,7 @@ bool CInputManager::OnEvent(XBMC_Event& newEvent) // Do not repeat long presses break; } - if (!CButtonTranslator::GetInstance().HasLonpressMapping(g_windowManager.GetActiveWindowID(), key)) + if (!CButtonTranslator::GetInstance().HasLongpressMapping(g_windowManager.GetActiveWindowID(), key)) { m_LastKey.Reset(); OnKey(key); diff --git a/xbmc/input/InputManager.h b/xbmc/input/InputManager.h index ba31cfcbf3..f161315179 100644 --- a/xbmc/input/InputManager.h +++ b/xbmc/input/InputManager.h @@ -39,6 +39,8 @@ class CKey; +namespace KODI +{ namespace KEYBOARD { class IKeyboardHandler; @@ -50,6 +52,7 @@ namespace MOUSE class IMouseDriverHandler; class IMouseInputHandler; } +} /// \addtogroup input /// \{ @@ -244,13 +247,13 @@ public: * * \param handler The handler to call on keyboard input. */ - void RegisterKeyboardHandler(KEYBOARD::IKeyboardHandler* handler); + void RegisterKeyboardHandler(KODI::KEYBOARD::IKeyboardHandler* handler); /*! \brief Unregisters handler from keyboard input. * * \param[in] handler The handler to unregister from keyboard input. */ - void UnregisterKeyboardHandler(KEYBOARD::IKeyboardHandler* handler); + void UnregisterKeyboardHandler(KODI::KEYBOARD::IKeyboardHandler* handler); /*! \brief Registers a handler to be called on mouse input (e.g a game client). * @@ -258,13 +261,13 @@ public: * \return[in] The controller ID that serves as a context for incoming events. * \sa IMouseButtonMap */ - std::string RegisterMouseHandler(MOUSE::IMouseInputHandler* handler); + std::string RegisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler); /*! \brief Unregisters handler from mouse input. * * \param[in] handler The handler to unregister from mouse input. */ - void UnregisterMouseHandler(MOUSE::IMouseInputHandler* handler); + void UnregisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler); private: @@ -316,18 +319,18 @@ private: std::vector<CAction> m_queuedActions; CCriticalSection m_actionMutex; - std::vector<KEYBOARD::IKeyboardHandler*> m_keyboardHandlers; + std::vector<KODI::KEYBOARD::IKeyboardHandler*> m_keyboardHandlers; struct MouseHandlerHandle { - MOUSE::IMouseInputHandler* inputHandler; - std::unique_ptr<MOUSE::IMouseDriverHandler> driverHandler; + KODI::MOUSE::IMouseInputHandler* inputHandler; + std::unique_ptr<KODI::MOUSE::IMouseDriverHandler> driverHandler; }; std::vector<MouseHandlerHandle> m_mouseHandlers; - std::unique_ptr<MOUSE::IMouseButtonMap> m_mouseButtonMap; + std::unique_ptr<KODI::MOUSE::IMouseButtonMap> m_mouseButtonMap; - std::unique_ptr<KEYBOARD::IKeyboardHandler> m_keyboardEasterEgg; + std::unique_ptr<KODI::KEYBOARD::IKeyboardHandler> m_keyboardEasterEgg; }; /// \} diff --git a/xbmc/input/Key.cpp b/xbmc/input/Key.cpp index a200663332..aa428ecb9e 100644 --- a/xbmc/input/Key.cpp +++ b/xbmc/input/Key.cpp @@ -20,7 +20,6 @@ #include "system.h" #include "input/Key.h" -#include "input/ButtonTranslator.h" CKey::CKey(void) { @@ -171,122 +170,3 @@ void CKey::SetFromService(bool fromService) m_fromService = fromService; } - -CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const std::string &name /* = "" */, unsigned int holdTime /*= 0*/) -{ - m_id = actionID; - m_amount[0] = amount1; - m_amount[1] = amount2; - for (unsigned int i = 2; i < max_amounts; i++) - m_amount[i] = 0; - m_name = name; - m_repeat = 0; - m_buttonCode = 0; - m_unicode = 0; - m_holdTime = holdTime; -} - -CAction::CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name): - m_name(name) -{ - m_id = actionID; - m_amount[0] = posX; - m_amount[1] = posY; - m_amount[2] = offsetX; - m_amount[3] = offsetY; - for (unsigned int i = 4; i < max_amounts; i++) - m_amount[i] = 0; - m_repeat = 0; - m_buttonCode = 0; - m_unicode = 0; - m_holdTime = state; -} - -CAction::CAction(int actionID, wchar_t unicode) -{ - m_id = actionID; - for (unsigned int i = 0; i < max_amounts; i++) - m_amount[i] = 0; - m_repeat = 0; - m_buttonCode = 0; - m_unicode = unicode; - m_holdTime = 0; -} - -CAction::CAction(int actionID, const std::string &name, const CKey &key): - m_name(name) -{ - m_id = actionID; - m_amount[0] = 1; // digital button (could change this for repeat acceleration) - for (unsigned int i = 1; i < max_amounts; i++) - m_amount[i] = 0; - m_repeat = key.GetRepeat(); - m_buttonCode = key.GetButtonCode(); - m_unicode = 0; - m_holdTime = key.GetHeld(); - // get the action amounts of the analog buttons - if (key.GetButtonCode() == KEY_BUTTON_LEFT_ANALOG_TRIGGER) - m_amount[0] = (float)key.GetLeftTrigger() / 255.0f; - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_ANALOG_TRIGGER) - m_amount[0] = (float)key.GetRightTrigger() / 255.0f; - else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK) - { - m_amount[0] = key.GetLeftThumbX(); - m_amount[1] = key.GetLeftThumbY(); - } - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK) - { - m_amount[0] = key.GetRightThumbX(); - m_amount[1] = key.GetRightThumbY(); - } - else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_UP) - m_amount[0] = key.GetLeftThumbY(); - else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_DOWN) - m_amount[0] = -key.GetLeftThumbY(); - else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_LEFT) - m_amount[0] = -key.GetLeftThumbX(); - else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_RIGHT) - m_amount[0] = key.GetLeftThumbX(); - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_UP) - m_amount[0] = key.GetRightThumbY(); - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_DOWN) - m_amount[0] = -key.GetRightThumbY(); - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_LEFT) - m_amount[0] = -key.GetRightThumbX(); - else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_RIGHT) - m_amount[0] = key.GetRightThumbX(); -} - -CAction::CAction(int actionID, const std::string &name): - m_name(name) -{ - m_id = actionID; - for (unsigned int i = 0; i < max_amounts; i++) - m_amount[i] = 0; - m_repeat = 0; - m_buttonCode = 0; - m_unicode = 0; - m_holdTime = 0; -} - -CAction& CAction::operator=(const CAction& rhs) -{ - if (this != &rhs) - { - m_id = rhs.m_id; - for (unsigned int i = 0; i < max_amounts; i++) - m_amount[i] = rhs.m_amount[i]; - m_name = rhs.m_name; - m_repeat = rhs.m_repeat; - m_buttonCode = rhs.m_buttonCode; - m_unicode = rhs.m_unicode; - m_holdTime = rhs.m_holdTime; - m_text = rhs.m_text; - } - return *this; -} - -bool CAction::IsAnalog() const -{ - return CButtonTranslator::IsAnalog(m_id); -} diff --git a/xbmc/input/Key.h b/xbmc/input/Key.h index bdc478cbd5..9836315721 100644 --- a/xbmc/input/Key.h +++ b/xbmc/input/Key.h @@ -24,6 +24,10 @@ * */ +//! @todo Remove dependence on CAction +#include "Action.h" +#include "ActionIDs.h" + #include <string> #include <stdint.h> @@ -135,292 +139,6 @@ #define KEY_INVALID 0xFFFF -// actions that we have defined... -/** - * \defgroup kodi_key_action_ids Action Id's - * \ingroup python_xbmcgui_window_cb - * \ingroup python_xbmcgui_action - * @{ - * @brief Actions that we have defined. - */ -#define ACTION_NONE 0 -#define ACTION_MOVE_LEFT 1 -#define ACTION_MOVE_RIGHT 2 -#define ACTION_MOVE_UP 3 -#define ACTION_MOVE_DOWN 4 -#define ACTION_PAGE_UP 5 -#define ACTION_PAGE_DOWN 6 -#define ACTION_SELECT_ITEM 7 -#define ACTION_HIGHLIGHT_ITEM 8 -#define ACTION_PARENT_DIR 9 -#define ACTION_PREVIOUS_MENU 10 -#define ACTION_SHOW_INFO 11 - -#define ACTION_PAUSE 12 -#define ACTION_STOP 13 -#define ACTION_NEXT_ITEM 14 -#define ACTION_PREV_ITEM 15 -#define ACTION_FORWARD 16 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_* -#define ACTION_REWIND 17 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_* - -#define ACTION_SHOW_GUI 18 //!< toggle between GUI and movie or GUI and visualisation. -#define ACTION_ASPECT_RATIO 19 //!< toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005 -#define ACTION_STEP_FORWARD 20 //!< seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_STEP_BACK 21 //!< seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_BIG_STEP_FORWARD 22 //!< seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_BIG_STEP_BACK 23 //!< seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_SHOW_OSD 24 //!< show/hide OSD. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_SHOW_SUBTITLES 25 //!< turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_NEXT_SUBTITLE 26 //!< switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_PLAYER_DEBUG 27 //!< show debug info for VideoPlayer -#define ACTION_NEXT_PICTURE 28 //!< show next picture of slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_PREV_PICTURE 29 //!< show previous picture of slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_OUT 30 //!< zoom in picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_IN 31 //!< zoom out picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_TOGGLE_SOURCE_DEST 32 //!< used to toggle between source view and destination view. Can be used in myfiles.xml window id=3 -#define ACTION_SHOW_PLAYLIST 33 //!< used to toggle between current view and playlist view. Can b used in all mymusic xml files -#define ACTION_QUEUE_ITEM 34 //!< used to queue a item to the playlist. Can b used in all mymusic xml files -#define ACTION_REMOVE_ITEM 35 //!< not used anymore -#define ACTION_SHOW_FULLSCREEN 36 //!< not used anymore -#define ACTION_ZOOM_LEVEL_NORMAL 37 //!< zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_1 38 //!< zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_2 39 //!< zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_3 40 //!< zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_4 41 //!< zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_5 42 //!< zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_6 43 //!< zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_7 44 //!< zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_8 45 //!< zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007 -#define ACTION_ZOOM_LEVEL_9 46 //!< zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007 - -#define ACTION_CALIBRATE_SWAP_ARROWS 47 //!< select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11 -#define ACTION_CALIBRATE_RESET 48 //!< reset calibration to defaults. Can b used in: `settingsScreenCalibration.xml` windowid=11/settingsUICalibration.xml windowid=10 -#define ACTION_ANALOG_MOVE 49 //!< analog thumbstick move. Can b used in: `slideshow.xml` windowid=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10 - //!< @note see also ACTION_ANALOG_MOVE_X, ACTION_ANALOG_MOVE_Y -#define ACTION_ROTATE_PICTURE_CW 50 //!< rotate current picture clockwise during slideshow. Can be used in slideshow.xml window id=2007 -#define ACTION_ROTATE_PICTURE_CCW 51 //!< rotate current picture counterclockwise during slideshow. Can be used in slideshow.xml window id=2007 - -#define ACTION_SUBTITLE_DELAY_MIN 52 //!< Decrease subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_SUBTITLE_DELAY_PLUS 53 //!< Increase subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_AUDIO_DELAY_MIN 54 //!< Increase avsync delay. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_AUDIO_DELAY_PLUS 55 //!< Decrease avsync delay. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_AUDIO_NEXT_LANGUAGE 56 //!< Select next language in movie. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_CHANGE_RESOLUTION 57 //!< switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11 - -#define REMOTE_0 58 //!< remote keys 0-9. are used by multiple windows -#define REMOTE_1 59 //!< for example in videoFullScreen.xml window id=2005 you can -#define REMOTE_2 60 //!< enter time (mmss) to jump to particular point in the movie -#define REMOTE_3 61 -#define REMOTE_4 62 //!< with spincontrols you can enter 3digit number to quickly set -#define REMOTE_5 63 //!< spincontrol to desired value -#define REMOTE_6 64 -#define REMOTE_7 65 -#define REMOTE_8 66 -#define REMOTE_9 67 - -#define ACTION_PLAY 68 //!< Unused at the moment -#define ACTION_PLAYER_PROCESS_INFO 69 //!< show player process info (video decoder, pixel format, pvr signal strength and the like -#define ACTION_SMALL_STEP_BACK 76 //!< jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005 - -#define ACTION_PLAYER_FORWARD 77 //!< FF in current file played. global action, can be used anywhere -#define ACTION_PLAYER_REWIND 78 //!< RW in current file played. global action, can be used anywhere -#define ACTION_PLAYER_PLAY 79 //!< Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere - -#define ACTION_DELETE_ITEM 80 //!< delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25 -#define ACTION_COPY_ITEM 81 //!< copy current selected item. Can be used in myfiles.xml window id=3 -#define ACTION_MOVE_ITEM 82 //!< move current selected item. Can be used in myfiles.xml window id=3 -#define ACTION_TAKE_SCREENSHOT 85 //!< take a screenshot -#define ACTION_RENAME_ITEM 87 //!< rename item - -#define ACTION_VOLUME_UP 88 -#define ACTION_VOLUME_DOWN 89 -#define ACTION_VOLAMP 90 -#define ACTION_MUTE 91 -#define ACTION_NAV_BACK 92 -#define ACTION_VOLAMP_UP 93 -#define ACTION_VOLAMP_DOWN 94 - -#define ACTION_CREATE_EPISODE_BOOKMARK 95 //!< Creates an episode bookmark on the currently playing video file containing more than one episode -#define ACTION_CREATE_BOOKMARK 96 //!< Creates a bookmark of the currently playing video file - -#define ACTION_CHAPTER_OR_BIG_STEP_FORWARD 97 //!< Goto the next chapter, if not available perform a big step forward -#define ACTION_CHAPTER_OR_BIG_STEP_BACK 98 //!< Goto the previous chapter, if not available perform a big step back - -#define ACTION_CYCLE_SUBTITLE 99 //!< switch to next subtitle of movie, but will not enable/disable the subtitles. Can be used in videoFullScreen.xml window id=2005 - -#define ACTION_MOUSE_START 100 -#define ACTION_MOUSE_LEFT_CLICK 100 -#define ACTION_MOUSE_RIGHT_CLICK 101 -#define ACTION_MOUSE_MIDDLE_CLICK 102 -#define ACTION_MOUSE_DOUBLE_CLICK 103 -#define ACTION_MOUSE_WHEEL_UP 104 -#define ACTION_MOUSE_WHEEL_DOWN 105 -#define ACTION_MOUSE_DRAG 106 -#define ACTION_MOUSE_MOVE 107 -#define ACTION_MOUSE_LONG_CLICK 108 -#define ACTION_MOUSE_END 109 - -#define ACTION_BACKSPACE 110 -#define ACTION_SCROLL_UP 111 -#define ACTION_SCROLL_DOWN 112 -#define ACTION_ANALOG_FORWARD 113 -#define ACTION_ANALOG_REWIND 114 - -#define ACTION_MOVE_ITEM_UP 115 //!< move item up in playlist -#define ACTION_MOVE_ITEM_DOWN 116 //!< move item down in playlist -#define ACTION_CONTEXT_MENU 117 //!< pops up the context menu - -// stuff for virtual keyboard shortcuts -#define ACTION_SHIFT 118 //!< stuff for virtual keyboard shortcuts -#define ACTION_SYMBOLS 119 //!< stuff for virtual keyboard shortcuts -#define ACTION_CURSOR_LEFT 120 //!< stuff for virtual keyboard shortcuts -#define ACTION_CURSOR_RIGHT 121 //!< stuff for virtual keyboard shortcuts - -#define ACTION_BUILT_IN_FUNCTION 122 - -#define ACTION_SHOW_OSD_TIME 123 //!< displays current time, can be used in videoFullScreen.xml window id=2005 -#define ACTION_ANALOG_SEEK_FORWARD 124 //!< seeks forward, and displays the seek bar. -#define ACTION_ANALOG_SEEK_BACK 125 //!< seeks backward, and displays the seek bar. - -#define ACTION_VIS_PRESET_SHOW 126 -#define ACTION_VIS_PRESET_NEXT 128 -#define ACTION_VIS_PRESET_PREV 129 -#define ACTION_VIS_PRESET_LOCK 130 -#define ACTION_VIS_PRESET_RANDOM 131 -#define ACTION_VIS_RATE_PRESET_PLUS 132 -#define ACTION_VIS_RATE_PRESET_MINUS 133 - -#define ACTION_SHOW_VIDEOMENU 134 -#define ACTION_ENTER 135 - -#define ACTION_INCREASE_RATING 136 -#define ACTION_DECREASE_RATING 137 - -#define ACTION_NEXT_SCENE 138 //!< switch to next scene/cutpoint in movie -#define ACTION_PREV_SCENE 139 //!< switch to previous scene/cutpoint in movie - -#define ACTION_NEXT_LETTER 140 //!< jump through a list or container by letter -#define ACTION_PREV_LETTER 141 - -#define ACTION_JUMP_SMS2 142 //!< jump direct to a particular letter using SMS-style input -#define ACTION_JUMP_SMS3 143 -#define ACTION_JUMP_SMS4 144 -#define ACTION_JUMP_SMS5 145 -#define ACTION_JUMP_SMS6 146 -#define ACTION_JUMP_SMS7 147 -#define ACTION_JUMP_SMS8 148 -#define ACTION_JUMP_SMS9 149 - -#define ACTION_FILTER_CLEAR 150 -#define ACTION_FILTER_SMS2 151 -#define ACTION_FILTER_SMS3 152 -#define ACTION_FILTER_SMS4 153 -#define ACTION_FILTER_SMS5 154 -#define ACTION_FILTER_SMS6 155 -#define ACTION_FILTER_SMS7 156 -#define ACTION_FILTER_SMS8 157 -#define ACTION_FILTER_SMS9 158 - -#define ACTION_FIRST_PAGE 159 -#define ACTION_LAST_PAGE 160 - -#define ACTION_AUDIO_DELAY 161 -#define ACTION_SUBTITLE_DELAY 162 -#define ACTION_MENU 163 - -#define ACTION_SET_RATING 164 - -#define ACTION_RECORD 170 - -#define ACTION_PASTE 180 -#define ACTION_NEXT_CONTROL 181 -#define ACTION_PREV_CONTROL 182 -#define ACTION_CHANNEL_SWITCH 183 -#define ACTION_CHANNEL_UP 184 -#define ACTION_CHANNEL_DOWN 185 -#define ACTION_NEXT_CHANNELGROUP 186 -#define ACTION_PREVIOUS_CHANNELGROUP 187 -#define ACTION_PVR_PLAY 188 -#define ACTION_PVR_PLAY_TV 189 -#define ACTION_PVR_PLAY_RADIO 190 -#define ACTION_PVR_SHOW_TIMER_RULE 191 - -#define ACTION_TOGGLE_FULLSCREEN 199 //!< switch 2 desktop resolution -#define ACTION_TOGGLE_WATCHED 200 //!< Toggle watched status (videos) -#define ACTION_SCAN_ITEM 201 //!< scan item -#define ACTION_TOGGLE_DIGITAL_ANALOG 202 //!< switch digital <-> analog -#define ACTION_RELOAD_KEYMAPS 203 //!< reloads CButtonTranslator's keymaps -#define ACTION_GUIPROFILE_BEGIN 204 //!< start the GUIControlProfiler running - -#define ACTION_TELETEXT_RED 215 //!< Teletext Color button <b>Red</b> to control TopText -#define ACTION_TELETEXT_GREEN 216 //!< Teletext Color button <b>Green</b> to control TopText -#define ACTION_TELETEXT_YELLOW 217 //!< Teletext Color button <b>Yellow</b> to control TopText -#define ACTION_TELETEXT_BLUE 218 //!< Teletext Color button <b>Blue</b> to control TopText - -#define ACTION_INCREASE_PAR 219 -#define ACTION_DECREASE_PAR 220 - -#define ACTION_VSHIFT_UP 227 //!< shift up video image in VideoPlayer -#define ACTION_VSHIFT_DOWN 228 //!< shift down video image in VideoPlayer - -#define ACTION_PLAYER_PLAYPAUSE 229 //!< Play/pause. If playing it pauses, if paused it plays. - -#define ACTION_SUBTITLE_VSHIFT_UP 230 //!< shift up subtitles in VideoPlayer -#define ACTION_SUBTITLE_VSHIFT_DOWN 231 //!< shift down subtitles in VideoPlayer -#define ACTION_SUBTITLE_ALIGN 232 //!< toggle vertical alignment of subtitles - -#define ACTION_FILTER 233 - -#define ACTION_SWITCH_PLAYER 234 - -#define ACTION_STEREOMODE_NEXT 235 -#define ACTION_STEREOMODE_PREVIOUS 236 -#define ACTION_STEREOMODE_TOGGLE 237 //!< turns 3d mode on/off -#define ACTION_STEREOMODE_SELECT 238 -#define ACTION_STEREOMODE_TOMONO 239 -#define ACTION_STEREOMODE_SET 240 - -#define ACTION_SETTINGS_RESET 241 -#define ACTION_SETTINGS_LEVEL_CHANGE 242 - -#define ACTION_TRIGGER_OSD 243 //!< show autoclosing OSD. Can b used in videoFullScreen.xml window id=2005 -#define ACTION_INPUT_TEXT 244 -#define ACTION_VOLUME_SET 245 -#define ACTION_TOGGLE_COMMSKIP 246 - -#define ACTION_TOUCH_TAP 401 //!< touch actions -#define ACTION_TOUCH_TAP_TEN 410 //!< touch actions -#define ACTION_TOUCH_LONGPRESS 411 //!< touch actions -#define ACTION_TOUCH_LONGPRESS_TEN 420 //!< touch actions - -#define ACTION_GESTURE_NOTIFY 500 -#define ACTION_GESTURE_BEGIN 501 -#define ACTION_GESTURE_ZOOM 502 //!< sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0) -#define ACTION_GESTURE_ROTATE 503 -#define ACTION_GESTURE_PAN 504 - -#define ACTION_GESTURE_SWIPE_LEFT 511 -#define ACTION_GESTURE_SWIPE_LEFT_TEN 520 -#define ACTION_GESTURE_SWIPE_RIGHT 521 -#define ACTION_GESTURE_SWIPE_RIGHT_TEN 530 -#define ACTION_GESTURE_SWIPE_UP 531 -#define ACTION_GESTURE_SWIPE_UP_TEN 540 -#define ACTION_GESTURE_SWIPE_DOWN 541 -#define ACTION_GESTURE_SWIPE_DOWN_TEN 550 -// 5xx is reserved for additional gesture actions -#define ACTION_GESTURE_END 599 - -// other, non-gesture actions -#define ACTION_ANALOG_MOVE_X 601 //!< analog thumbstick move, horizontal axis; see ACTION_ANALOG_MOVE -#define ACTION_ANALOG_MOVE_Y 602 //!< analog thumbstick move, vertical axis; see ACTION_ANALOG_MOVE -//@} - -// The NOOP action can be specified to disable an input event. This is -// useful in user keyboard.xml etc to disable actions specified in the -// system mappings. ERROR action is used to play an error sound -#define ACTION_ERROR 998 -#define ACTION_NOOP 999 - #define ICON_TYPE_NONE 101 #define ICON_TYPE_PROGRAMS 102 #define ICON_TYPE_MUSIC 103 @@ -432,93 +150,6 @@ #ifndef SWIG -class CKey; - -/*! - \ingroup actionkeys - \brief class encapsulating information regarding a particular user action to be sent to windows and controls - */ -class CAction -{ -public: - CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const std::string &name = "", unsigned int holdTime = 0); - CAction(int actionID, wchar_t unicode); - CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name = ""); - CAction(int actionID, const std::string &name, const CKey &key); - CAction(int actionID, const std::string &name); - - CAction(const CAction& other) { *this = other; } - CAction& operator=(const CAction& rhs); - - /*! \brief Identifier of the action - \return id of the action - */ - int GetID() const { return m_id; }; - - /*! \brief Is this an action from the mouse - \return true if this is a mouse action, false otherwise - */ - bool IsMouse() const { return (m_id >= ACTION_MOUSE_START && m_id <= ACTION_MOUSE_END); }; - - bool IsGesture() const { return (m_id >= ACTION_GESTURE_NOTIFY && m_id <= ACTION_GESTURE_END); }; - - /*! \brief Human-readable name of the action - \return name of the action - */ - const std::string &GetName() const { return m_name; }; - - /*! \brief Text of the action if any - \return text payload of this action. - */ - const std::string &GetText() const { return m_text; }; - - /*! \brief Set the text payload of the action - \param text to be set - */ - void SetText(const std::string &text) { m_text = text; }; - - /*! \brief Get an amount associated with this action - \param zero-based index of amount to retrieve, defaults to 0 - \return an amount associated with this action - */ - float GetAmount(unsigned int index = 0) const { return (index < max_amounts) ? m_amount[index] : 0; }; - - /*! \brief Unicode value associated with this action - \return unicode value associated with this action, for keyboard input. - */ - wchar_t GetUnicode() const { return m_unicode; }; - - /*! \brief Time in ms that the key has been held - \return time that the key has been held down in ms. - */ - unsigned int GetHoldTime() const { return m_holdTime; }; - - /*! \brief Time since last repeat in ms - \return time since last repeat in ms. Returns 0 if unknown. - */ - float GetRepeat() const { return m_repeat; }; - - /*! \brief Button code that triggered this action - \return button code - */ - unsigned int GetButtonCode() const { return m_buttonCode; }; - - bool IsAnalog() const; - -private: - int m_id; - std::string m_name; - - static const unsigned int max_amounts = 4; // Must be at least 4. - float m_amount[max_amounts]; - - float m_repeat; - unsigned int m_holdTime; - unsigned int m_buttonCode; - wchar_t m_unicode; - std::string m_text; -}; - /*! \ingroup actionkeys, mouse \brief Simple class for mouse events diff --git a/xbmc/input/joysticks/DeadzoneFilter.cpp b/xbmc/input/joysticks/DeadzoneFilter.cpp index 8ee33e5942..988c36a539 100644 --- a/xbmc/input/joysticks/DeadzoneFilter.cpp +++ b/xbmc/input/joysticks/DeadzoneFilter.cpp @@ -24,10 +24,14 @@ #include "peripherals/devices/Peripheral.h" #include "utils/log.h" +#include <cmath> #include <vector> +using namespace KODI; using namespace JOYSTICK; +#define AXIS_EPSILON 0.01f // Allowed noise for detecting discrete D-pads (value of 0.007 when centered has been observed) + // Settings for analog sticks #define SETTING_LEFT_STICK_DEADZONE "left_stick_deadzone" #define SETTING_RIGHT_STICK_DEADZONE "right_stick_deadzone" @@ -50,6 +54,10 @@ float CDeadzoneFilter::FilterAxis(unsigned int axisIndex, float axisValue) if (bSuccess) return ApplyDeadzone(axisValue, deadzone); + // Always filter noise about the center + if (std::abs(axisValue) < AXIS_EPSILON) + axisValue = 0.0f; + return axisValue; } diff --git a/xbmc/input/joysticks/DeadzoneFilter.h b/xbmc/input/joysticks/DeadzoneFilter.h index 750ef4ed44..403bffdc59 100644 --- a/xbmc/input/joysticks/DeadzoneFilter.h +++ b/xbmc/input/joysticks/DeadzoneFilter.h @@ -24,6 +24,8 @@ namespace PERIPHERALS class CPeripheral; } +namespace KODI +{ namespace JOYSTICK { class IButtonMap; @@ -85,3 +87,4 @@ namespace JOYSTICK PERIPHERALS::CPeripheral* const m_peripheral; }; } +} diff --git a/xbmc/input/joysticks/DefaultJoystick.cpp b/xbmc/input/joysticks/DefaultJoystick.cpp index d474023850..70ef187c78 100644 --- a/xbmc/input/joysticks/DefaultJoystick.cpp +++ b/xbmc/input/joysticks/DefaultJoystick.cpp @@ -31,6 +31,7 @@ #define ANALOG_DIGITAL_THRESHOLD 0.5f +using namespace KODI; using namespace JOYSTICK; CDefaultJoystick::CDefaultJoystick(void) : diff --git a/xbmc/input/joysticks/DefaultJoystick.h b/xbmc/input/joysticks/DefaultJoystick.h index 0c22e14a2c..77a2720b75 100644 --- a/xbmc/input/joysticks/DefaultJoystick.h +++ b/xbmc/input/joysticks/DefaultJoystick.h @@ -34,6 +34,8 @@ #define DEFAULT_LEFT_STICK_NAME "leftstick" #define DEFAULT_RIGHT_STICK_NAME "rightstick" +namespace KODI +{ namespace JOYSTICK { class IKeymapHandler; @@ -105,3 +107,4 @@ namespace JOYSTICK std::unique_ptr<IButtonSequence> m_easterEgg; }; } +} diff --git a/xbmc/input/joysticks/DriverPrimitive.cpp b/xbmc/input/joysticks/DriverPrimitive.cpp index 8630a40253..9766f3594a 100644 --- a/xbmc/input/joysticks/DriverPrimitive.cpp +++ b/xbmc/input/joysticks/DriverPrimitive.cpp @@ -20,13 +20,16 @@ #include "DriverPrimitive.h" +using namespace KODI; using namespace JOYSTICK; CDriverPrimitive::CDriverPrimitive(void) : m_type(), m_driverIndex(0), m_hatDirection(), - m_semiAxisDirection() + m_center(0), + m_semiAxisDirection(), + m_range(1) { } @@ -34,7 +37,9 @@ CDriverPrimitive::CDriverPrimitive(PRIMITIVE_TYPE type, unsigned int index) : m_type(type), m_driverIndex(index), m_hatDirection(), - m_semiAxisDirection() + m_center(0), + m_semiAxisDirection(), + m_range(1) { } @@ -42,15 +47,19 @@ CDriverPrimitive::CDriverPrimitive(unsigned int hatIndex, HAT_DIRECTION directio : m_type(HAT), m_driverIndex(hatIndex), m_hatDirection(direction), - m_semiAxisDirection() + m_center(0), + m_semiAxisDirection(), + m_range(1) { } -CDriverPrimitive::CDriverPrimitive(unsigned int axisIndex, SEMIAXIS_DIRECTION direction) +CDriverPrimitive::CDriverPrimitive(unsigned int axisIndex, int center, SEMIAXIS_DIRECTION direction, unsigned int range) : m_type(SEMIAXIS), m_driverIndex(axisIndex), m_hatDirection(), - m_semiAxisDirection(direction) + m_center(center), + m_semiAxisDirection(direction), + m_range(range) { } @@ -66,7 +75,10 @@ bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const case HAT: return m_driverIndex == rhs.m_driverIndex && m_hatDirection == rhs.m_hatDirection; case SEMIAXIS: - return m_driverIndex == rhs.m_driverIndex && m_semiAxisDirection == rhs.m_semiAxisDirection; + return m_driverIndex == rhs.m_driverIndex && + m_center == rhs.m_center && + m_semiAxisDirection == rhs.m_semiAxisDirection && + m_range == rhs.m_range; default: return true; } @@ -94,8 +106,14 @@ bool CDriverPrimitive::operator<(const CDriverPrimitive& rhs) const if (m_type == SEMIAXIS) { + if (m_center < rhs.m_center) return true; + if (m_center > rhs.m_center) return false; + if (m_semiAxisDirection < rhs.m_semiAxisDirection) return true; if (m_semiAxisDirection > rhs.m_semiAxisDirection) return false; + + if (m_range < rhs.m_range) return true; + if (m_range > rhs.m_range) return false; } return false; @@ -116,8 +134,36 @@ bool CDriverPrimitive::IsValid(void) const if (m_type == SEMIAXIS) { - return m_semiAxisDirection == SEMIAXIS_DIRECTION::POSITIVE || - m_semiAxisDirection == SEMIAXIS_DIRECTION::NEGATIVE; + unsigned int maxRange = 1; + + switch (m_center) + { + case -1: + { + if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE) + return false; + maxRange = 2; + break; + } + case 0: + { + if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE && + m_semiAxisDirection != SEMIAXIS_DIRECTION::NEGATIVE) + return false; + break; + } + case 1: + { + if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE) + return false; + maxRange = 2; + break; + } + default: + break; + } + + return 1 <= m_range && m_range <= maxRange; } return false; diff --git a/xbmc/input/joysticks/DriverPrimitive.h b/xbmc/input/joysticks/DriverPrimitive.h index 7a0f14a92c..7354853a29 100644 --- a/xbmc/input/joysticks/DriverPrimitive.h +++ b/xbmc/input/joysticks/DriverPrimitive.h @@ -23,6 +23,8 @@ #include <stdint.h> +namespace KODI +{ namespace JOYSTICK { /*! @@ -54,7 +56,9 @@ namespace JOYSTICK * * Semiaxis: * - driver index + * - center (-1, 0 or 1) * - semiaxis direction (positive/negative) + * - range (1 or 2) * * Motor: * - driver index @@ -85,7 +89,7 @@ namespace JOYSTICK * \brief Construct a driver primitive representing the positive or negative * half of an axis */ - CDriverPrimitive(unsigned int axisIndex, SEMIAXIS_DIRECTION direction); + CDriverPrimitive(unsigned int axisIndex, int center, SEMIAXIS_DIRECTION direction, unsigned int range); bool operator==(const CDriverPrimitive& rhs) const; bool operator<(const CDriverPrimitive& rhs) const; @@ -111,11 +115,21 @@ namespace JOYSTICK HAT_DIRECTION HatDirection(void) const { return m_hatDirection; } /*! + * \brief The location of the zero point of the semiaxis + */ + int Center() const { return m_center; } + + /*! * \brief The semiaxis direction (valid for semiaxes) */ SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; } /*! + * \brief The distance between the center and the farthest valid value (valid for semiaxes) + */ + unsigned int Range() const { return m_range; } + + /*! * \brief Test if an driver primitive is valid * * A driver primitive is valid if it has a known type and: @@ -129,6 +143,9 @@ namespace JOYSTICK PRIMITIVE_TYPE m_type; unsigned int m_driverIndex; HAT_DIRECTION m_hatDirection; + int m_center; SEMIAXIS_DIRECTION m_semiAxisDirection; + unsigned int m_range; }; } +} diff --git a/xbmc/input/joysticks/IActionMap.h b/xbmc/input/joysticks/IActionMap.h index 788da323ee..3c9ceb77ec 100644 --- a/xbmc/input/joysticks/IActionMap.h +++ b/xbmc/input/joysticks/IActionMap.h @@ -22,6 +22,8 @@ #include "JoystickTypes.h" #include "input/Key.h" +namespace KODI +{ namespace JOYSTICK { class CDriverPrimitive; @@ -50,8 +52,9 @@ namespace JOYSTICK * \param feature The feature to look up * * \return The action ID from Key.h, or ACTION_NONE if no action is mapped - * to the specified key + * to the specified feature */ virtual int GetActionID(const FeatureName& feature) = 0; }; } +} diff --git a/xbmc/input/joysticks/IButtonMap.h b/xbmc/input/joysticks/IButtonMap.h index 9964b32154..5e3d4157de 100644 --- a/xbmc/input/joysticks/IButtonMap.h +++ b/xbmc/input/joysticks/IButtonMap.h @@ -25,6 +25,8 @@ #include <string> #include <vector> +namespace KODI +{ namespace JOYSTICK { /*! @@ -226,6 +228,17 @@ namespace JOYSTICK virtual bool IsIgnored(const CDriverPrimitive& primitive) = 0; /*! + * \brief Get the properties of an axis + * + * \param axisIndex The index of the axis to check + * \param center[out] The center, if known + * \param range[out] The range, if known + * + * \return True if the properties are known, false otherwise + */ + virtual bool GetAxisProperties(unsigned int axisIndex, int& center, unsigned int& range) = 0; + + /*! * \brief Save the button map */ virtual void SaveButtonMap() = 0; @@ -237,3 +250,4 @@ namespace JOYSTICK virtual void RevertButtonMap() = 0; }; } +} diff --git a/xbmc/input/joysticks/IButtonMapCallback.h b/xbmc/input/joysticks/IButtonMapCallback.h index 4d22f91ba4..c71c99281d 100644 --- a/xbmc/input/joysticks/IButtonMapCallback.h +++ b/xbmc/input/joysticks/IButtonMapCallback.h @@ -19,6 +19,8 @@ */ #pragma once +namespace KODI +{ namespace JOYSTICK { /*! @@ -53,3 +55,4 @@ namespace JOYSTICK virtual void RevertButtonMap() = 0; }; } +} diff --git a/xbmc/input/joysticks/IButtonMapper.h b/xbmc/input/joysticks/IButtonMapper.h index 9cbd199224..855f76b108 100644 --- a/xbmc/input/joysticks/IButtonMapper.h +++ b/xbmc/input/joysticks/IButtonMapper.h @@ -22,6 +22,8 @@ #include <map> #include <string> +namespace KODI +{ namespace JOYSTICK { class CDriverPrimitive; @@ -109,6 +111,17 @@ namespace JOYSTICK */ virtual void OnEventFrame(const IButtonMap* buttonMap, bool bMotion) = 0; + /*! + * \brief Called when an axis has been detected after mapping began + * + * \param axisIndex The index of the axis being discovered + * + * Some joystick drivers don't report an initial value for analog axes. + * + * Called in the same thread as \ref IButtonMapper::MapPrimitive. + */ + virtual void OnLateAxis(const IButtonMap* buttonMap, unsigned int axisIndex) = 0; + // Button map callback interface void SetButtonMapCallback(const std::string& deviceName, IButtonMapCallback* callback) { m_callbacks[deviceName] = callback; } void ResetButtonMapCallbacks(void) { m_callbacks.clear(); } @@ -118,3 +131,4 @@ namespace JOYSTICK std::map<std::string, IButtonMapCallback*> m_callbacks; }; } +} diff --git a/xbmc/input/joysticks/IButtonSequence.h b/xbmc/input/joysticks/IButtonSequence.h index d2646582e4..31b64c4e5b 100644 --- a/xbmc/input/joysticks/IButtonSequence.h +++ b/xbmc/input/joysticks/IButtonSequence.h @@ -21,6 +21,8 @@ #include "JoystickTypes.h" +namespace KODI +{ namespace JOYSTICK { class IButtonSequence @@ -31,3 +33,4 @@ namespace JOYSTICK virtual bool OnButtonPress(const FeatureName& feature) = 0; }; } +} diff --git a/xbmc/input/joysticks/IDriverHandler.h b/xbmc/input/joysticks/IDriverHandler.h index 45e05eb87a..5843b868d6 100644 --- a/xbmc/input/joysticks/IDriverHandler.h +++ b/xbmc/input/joysticks/IDriverHandler.h @@ -21,6 +21,8 @@ #include "JoystickTypes.h" +namespace KODI +{ namespace JOYSTICK { /*! @@ -60,10 +62,12 @@ namespace JOYSTICK * * \param axisIndex The index of the axis as reported by the driver * \param position The position of the axis in the closed interval [-1.0, 1.0] + * \param center The center point of the axis (either -1, 0 or 1) + * \param range The maximum distance the axis can move (either 1 or 2) * * \return True if the motion was handled, false otherwise */ - virtual bool OnAxisMotion(unsigned int axisIndex, float position) = 0; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) = 0; /*! * \brief Handle buffered axis positions for features that require multiple axes @@ -78,3 +82,4 @@ namespace JOYSTICK virtual void ProcessAxisMotions(void) = 0; }; } +} diff --git a/xbmc/input/joysticks/IDriverReceiver.h b/xbmc/input/joysticks/IDriverReceiver.h index df181ea838..0255a7b752 100644 --- a/xbmc/input/joysticks/IDriverReceiver.h +++ b/xbmc/input/joysticks/IDriverReceiver.h @@ -19,6 +19,8 @@ */ #pragma once +namespace KODI +{ namespace JOYSTICK { /*! @@ -41,3 +43,4 @@ namespace JOYSTICK virtual bool SetMotorState(unsigned int motorIndex, float magnitude) = 0; }; } +} diff --git a/xbmc/input/joysticks/IInputHandler.h b/xbmc/input/joysticks/IInputHandler.h index 44629f5c52..9b6795f921 100644 --- a/xbmc/input/joysticks/IInputHandler.h +++ b/xbmc/input/joysticks/IInputHandler.h @@ -23,6 +23,8 @@ #include <string> +namespace KODI +{ namespace JOYSTICK { class IInputReceiver; @@ -133,3 +135,4 @@ namespace JOYSTICK IInputReceiver* m_receiver; }; } +} diff --git a/xbmc/input/joysticks/IInputReceiver.h b/xbmc/input/joysticks/IInputReceiver.h index 182e27ab0b..2292ce87a2 100644 --- a/xbmc/input/joysticks/IInputReceiver.h +++ b/xbmc/input/joysticks/IInputReceiver.h @@ -21,6 +21,8 @@ #include "JoystickTypes.h" +namespace KODI +{ namespace JOYSTICK { /*! @@ -43,3 +45,4 @@ namespace JOYSTICK virtual bool SetRumbleState(const FeatureName& feature, float magnitude) = 0; }; } +} diff --git a/xbmc/input/joysticks/IKeymapHandler.h b/xbmc/input/joysticks/IKeymapHandler.h index 83e21c6666..efdbdb367f 100644 --- a/xbmc/input/joysticks/IKeymapHandler.h +++ b/xbmc/input/joysticks/IKeymapHandler.h @@ -21,6 +21,8 @@ #include "JoystickTypes.h" +namespace KODI +{ namespace JOYSTICK { /*! @@ -75,3 +77,4 @@ namespace JOYSTICK virtual void OnAnalogKey(unsigned int buttonKeyId, float magnitude) = 0; }; } +} diff --git a/xbmc/input/joysticks/JoystickEasterEgg.cpp b/xbmc/input/joysticks/JoystickEasterEgg.cpp index d50b79edab..aea96fc390 100644 --- a/xbmc/input/joysticks/JoystickEasterEgg.cpp +++ b/xbmc/input/joysticks/JoystickEasterEgg.cpp @@ -24,6 +24,7 @@ #include "guilib/WindowIDs.h" #include "settings/Settings.h" +using namespace KODI; using namespace JOYSTICK; std::vector<FeatureName> CJoystickEasterEgg::m_sequence = { diff --git a/xbmc/input/joysticks/JoystickEasterEgg.h b/xbmc/input/joysticks/JoystickEasterEgg.h index fe239fcec7..78e1fe978e 100644 --- a/xbmc/input/joysticks/JoystickEasterEgg.h +++ b/xbmc/input/joysticks/JoystickEasterEgg.h @@ -23,6 +23,8 @@ #include <vector> +namespace KODI +{ namespace JOYSTICK { /*! @@ -45,3 +47,4 @@ namespace JOYSTICK unsigned int m_state; }; } +} diff --git a/xbmc/input/joysticks/JoystickMonitor.cpp b/xbmc/input/joysticks/JoystickMonitor.cpp index 6de84abf43..3aef3c8442 100644 --- a/xbmc/input/joysticks/JoystickMonitor.cpp +++ b/xbmc/input/joysticks/JoystickMonitor.cpp @@ -22,6 +22,7 @@ #include "Application.h" #include "input/InputManager.h" +using namespace KODI; using namespace JOYSTICK; bool CJoystickMonitor::OnButtonMotion(unsigned int buttonIndex, bool bPressed) @@ -46,7 +47,7 @@ bool CJoystickMonitor::OnHatMotion(unsigned int hatIndex, HAT_STATE state) return false; } -bool CJoystickMonitor::OnAxisMotion(unsigned int axisIndex, float position) +bool CJoystickMonitor::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) { if (position) { diff --git a/xbmc/input/joysticks/JoystickMonitor.h b/xbmc/input/joysticks/JoystickMonitor.h index 1bcc096427..912d2039a0 100644 --- a/xbmc/input/joysticks/JoystickMonitor.h +++ b/xbmc/input/joysticks/JoystickMonitor.h @@ -21,6 +21,8 @@ #include "IDriverHandler.h" +namespace KODI +{ namespace JOYSTICK { /*! @@ -34,7 +36,7 @@ namespace JOYSTICK // implementation of IDriverHandler virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; virtual bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override; virtual void ProcessAxisMotions(void) override { } private: @@ -45,3 +47,4 @@ namespace JOYSTICK bool ResetTimers(void); }; } +} diff --git a/xbmc/input/joysticks/JoystickTranslator.cpp b/xbmc/input/joysticks/JoystickTranslator.cpp index e1f76a9f26..80e932efbc 100644 --- a/xbmc/input/joysticks/JoystickTranslator.cpp +++ b/xbmc/input/joysticks/JoystickTranslator.cpp @@ -19,7 +19,11 @@ */ #include "JoystickTranslator.h" +#include "guilib/LocalizeStrings.h" +#include "input/joysticks/DriverPrimitive.h" +#include "utils/StringUtils.h" +using namespace KODI; using namespace JOYSTICK; const char* CJoystickTranslator::HatStateToString(HAT_STATE state) @@ -59,3 +63,21 @@ ANALOG_STICK_DIRECTION CJoystickTranslator::VectorToAnalogStickDirection(float x return ANALOG_STICK_DIRECTION::UNKNOWN; } + +std::string CJoystickTranslator::GetPrimitiveName(const CDriverPrimitive& primitive) +{ + std::string primitiveTemplate; + + switch (primitive.Type()) + { + case PRIMITIVE_TYPE::BUTTON: + primitiveTemplate = g_localizeStrings.Get(35015); // "Button %d" + break; + case PRIMITIVE_TYPE::SEMIAXIS: + primitiveTemplate = g_localizeStrings.Get(35016); // "Axis %d" + break; + default: break; + } + + return StringUtils::Format(primitiveTemplate.c_str(), primitive.Index()); +} diff --git a/xbmc/input/joysticks/JoystickTranslator.h b/xbmc/input/joysticks/JoystickTranslator.h index 2c26e54416..e6a5f0ce44 100644 --- a/xbmc/input/joysticks/JoystickTranslator.h +++ b/xbmc/input/joysticks/JoystickTranslator.h @@ -21,8 +21,12 @@ #include "JoystickTypes.h" +namespace KODI +{ namespace JOYSTICK { + class CDriverPrimitive; + /*! * \brief Joystick translation utilities */ @@ -60,5 +64,15 @@ namespace JOYSTICK * ANALOG_STICK_DIRECTION::UNKNOWN if x and y are both 0 */ static ANALOG_STICK_DIRECTION VectorToAnalogStickDirection(float x, float y); + + /*! + * \brief Get the localized name of the primitive + * + * \param primitive The primitive, currently only buttons and axes are supported + * + * \return A title for the primitive, e.g. "Button 0" or "Axis 1" + */ + static std::string GetPrimitiveName(const CDriverPrimitive& primitive); }; } +} diff --git a/xbmc/input/joysticks/JoystickTypes.h b/xbmc/input/joysticks/JoystickTypes.h index f30ddcb1fa..7a56bae039 100644 --- a/xbmc/input/joysticks/JoystickTypes.h +++ b/xbmc/input/joysticks/JoystickTypes.h @@ -26,6 +26,8 @@ #include <string> +namespace KODI +{ namespace JOYSTICK { /*! @@ -59,6 +61,20 @@ namespace JOYSTICK }; /*! + * \brief Categories of features used in the joystick library + */ + enum class FEATURE_CATEGORY + { + UNKNOWN, + FACE, + SHOULDER, + TRIGGER, + ANALOG_STICK, + ACCELEROMETER, + HAPTICS, + }; + + /*! * \brief Direction arrows on the hat (directional pad) */ enum class HAT_DIRECTION @@ -123,3 +139,4 @@ namespace JOYSTICK MOTOR, // a rumble motor }; } +} diff --git a/xbmc/input/joysticks/JoystickUtils.h b/xbmc/input/joysticks/JoystickUtils.h index 88bf9e4f4d..665e75673e 100644 --- a/xbmc/input/joysticks/JoystickUtils.h +++ b/xbmc/input/joysticks/JoystickUtils.h @@ -24,29 +24,37 @@ /// \ingroup joystick /// \{ -inline JOYSTICK::HAT_DIRECTION& operator|=(JOYSTICK::HAT_DIRECTION& lhs, JOYSTICK::HAT_DIRECTION rhs) +namespace KODI { - return lhs = static_cast<JOYSTICK::HAT_DIRECTION>(static_cast<int>(lhs) | static_cast<int>(rhs)); +namespace JOYSTICK +{ + +inline HAT_DIRECTION& operator|=(HAT_DIRECTION& lhs, HAT_DIRECTION rhs) +{ + return lhs = static_cast<HAT_DIRECTION>(static_cast<int>(lhs) | static_cast<int>(rhs)); } -inline JOYSTICK::HAT_STATE& operator|=(JOYSTICK::HAT_STATE& lhs, JOYSTICK::HAT_STATE rhs) +inline HAT_STATE& operator|=(HAT_STATE& lhs, HAT_STATE rhs) { - return lhs = static_cast<JOYSTICK::HAT_STATE>(static_cast<int>(lhs) | static_cast<int>(rhs)); + return lhs = static_cast<HAT_STATE>(static_cast<int>(lhs) | static_cast<int>(rhs)); } -inline bool operator&(JOYSTICK::HAT_STATE lhs, JOYSTICK::HAT_DIRECTION rhs) +inline bool operator&(HAT_STATE lhs, HAT_DIRECTION rhs) { return (static_cast<int>(lhs) & static_cast<int>(rhs)) ? true : false; } -inline JOYSTICK::SEMIAXIS_DIRECTION operator*(JOYSTICK::SEMIAXIS_DIRECTION lhs, int rhs) +inline SEMIAXIS_DIRECTION operator*(SEMIAXIS_DIRECTION lhs, int rhs) { - return static_cast<JOYSTICK::SEMIAXIS_DIRECTION>(static_cast<int>(lhs) * rhs); + return static_cast<SEMIAXIS_DIRECTION>(static_cast<int>(lhs) * rhs); } -inline float operator*(float lhs, JOYSTICK::SEMIAXIS_DIRECTION rhs) +inline float operator*(float lhs, SEMIAXIS_DIRECTION rhs) { return lhs * static_cast<int>(rhs); } +} +} + /// \} diff --git a/xbmc/input/joysticks/KeymapHandler.cpp b/xbmc/input/joysticks/KeymapHandler.cpp index 7d2f459893..b0fb082774 100644 --- a/xbmc/input/joysticks/KeymapHandler.cpp +++ b/xbmc/input/joysticks/KeymapHandler.cpp @@ -28,13 +28,11 @@ #include <algorithm> using namespace KODI; -using namespace MESSAGING; +using namespace JOYSTICK; #define HOLD_TIMEOUT_MS 500 #define REPEAT_TIMEOUT_MS 50 -using namespace JOYSTICK; - CKeymapHandler::CKeymapHandler(void) : m_lastButtonPress(0), m_lastDigitalActionMs(0) @@ -139,6 +137,25 @@ bool CKeymapHandler::SendDigitalAction(unsigned int keyId, unsigned int holdTime CAction action(CButtonTranslator::GetInstance().GetAction(g_windowManager.GetActiveWindowID(), CKey(keyId, holdTimeMs))); if (action.GetID() > 0) { + //! @todo Add "holdtime" parameter to joystick.xml. For now we MUST only + // send held actions for basic navigation commands! + if (holdTimeMs > 0) + { + switch (action.GetID()) + { + case ACTION_MOVE_LEFT: + case ACTION_MOVE_RIGHT: + case ACTION_MOVE_UP: + case ACTION_MOVE_DOWN: + case ACTION_PAGE_UP: + case ACTION_PAGE_DOWN: + break; + + default: + return true; + } + } + CInputManager::GetInstance().QueueAction(action); return true; } diff --git a/xbmc/input/joysticks/KeymapHandler.h b/xbmc/input/joysticks/KeymapHandler.h index 39dbbf14db..13dd940743 100644 --- a/xbmc/input/joysticks/KeymapHandler.h +++ b/xbmc/input/joysticks/KeymapHandler.h @@ -23,6 +23,8 @@ #include <vector> +namespace KODI +{ namespace JOYSTICK { /*! @@ -61,3 +63,4 @@ namespace JOYSTICK std::vector<unsigned int> m_pressedButtons; }; } +} diff --git a/xbmc/input/joysticks/RumbleGenerator.cpp b/xbmc/input/joysticks/RumbleGenerator.cpp index 71ae32f7e4..894d056f3f 100644 --- a/xbmc/input/joysticks/RumbleGenerator.cpp +++ b/xbmc/input/joysticks/RumbleGenerator.cpp @@ -19,10 +19,13 @@ */ #include "RumbleGenerator.h" -#include "addons/AddonManager.h" #include "games/controllers/Controller.h" #include "games/controllers/ControllerFeature.h" +#include "games/GameServices.h" #include "input/joysticks/IInputReceiver.h" +#include "ServiceBroker.h" + +#include <algorithm> #define RUMBLE_TEST_DURATION_MS 1000 // Per motor #define RUMBLE_NOTIFICATION_DURATION_MS 300 @@ -30,6 +33,7 @@ // From game.controller.default profile #define WEAK_MOTOR_NAME "rightmotor" +using namespace KODI; using namespace JOYSTICK; CRumbleGenerator::CRumbleGenerator(const std::string& controllerId) : @@ -117,22 +121,18 @@ void CRumbleGenerator::Process(void) std::vector<std::string> CRumbleGenerator::GetMotors(const std::string& controllerId) { - using namespace ADDON; using namespace GAME; std::vector<std::string> motors; - AddonPtr addon; - if (CAddonMgr::GetInstance().GetAddon(controllerId, addon, ADDON_GAME_CONTROLLER)) + CGameServices& gameServices = CServiceBroker::GetGameServices(); + ControllerPtr controller = gameServices.GetController(controllerId); + if (controller) { - ControllerPtr controller = std::static_pointer_cast<CController>(addon); - if (controller->LoadLayout()) + for (const CControllerFeature& feature : controller->Layout().Features()) { - for (const CControllerFeature& feature : controller->Layout().Features()) - { - if (feature.Type() == JOYSTICK::FEATURE_TYPE::MOTOR) - motors.push_back(feature.Name()); - } + if (feature.Type() == FEATURE_TYPE::MOTOR) + motors.push_back(feature.Name()); } } diff --git a/xbmc/input/joysticks/RumbleGenerator.h b/xbmc/input/joysticks/RumbleGenerator.h index c3431bd0eb..26474c4cf7 100644 --- a/xbmc/input/joysticks/RumbleGenerator.h +++ b/xbmc/input/joysticks/RumbleGenerator.h @@ -21,6 +21,8 @@ #include "threads/Thread.h" +namespace KODI +{ namespace JOYSTICK { class IInputReceiver; @@ -59,3 +61,4 @@ namespace JOYSTICK RUMBLE_TYPE m_type; }; } +} diff --git a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp index 6223eb3c5e..d0b42d9dae 100644 --- a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp +++ b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp @@ -25,6 +25,7 @@ #include "messaging/helpers/DialogHelper.h" #include "settings/Settings.h" +using namespace KODI; using namespace JOYSTICK; CGUIDialogNewJoystick::CGUIDialogNewJoystick() : @@ -49,7 +50,7 @@ void CGUIDialogNewJoystick::ShowAsync() void CGUIDialogNewJoystick::Process() { - using namespace KODI::MESSAGING::HELPERS; + using namespace MESSAGING::HELPERS; // "New controller detected" // "A new controller has been detected. Configuration can be done at any time in "Settings -> System Settings -> Input". Would you like to configure it now?" diff --git a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h index b44ba37dfb..71bff72aec 100644 --- a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h +++ b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h @@ -21,6 +21,8 @@ #include "threads/Thread.h" +namespace KODI +{ namespace JOYSTICK { class CGUIDialogNewJoystick : protected CThread @@ -36,3 +38,4 @@ namespace JOYSTICK virtual void Process() override; }; } +} diff --git a/xbmc/input/joysticks/generic/ButtonMapping.cpp b/xbmc/input/joysticks/generic/ButtonMapping.cpp index 2bd016339c..9b74ff52c0 100644 --- a/xbmc/input/joysticks/generic/ButtonMapping.cpp +++ b/xbmc/input/joysticks/generic/ButtonMapping.cpp @@ -19,113 +19,297 @@ */ #include "ButtonMapping.h" +#include "games/GameServices.h" +#include "games/controllers/Controller.h" +#include "games/controllers/ControllerFeature.h" #include "input/joysticks/DriverPrimitive.h" +#include "input/joysticks/IActionMap.h" #include "input/joysticks/IButtonMap.h" #include "input/joysticks/IButtonMapper.h" #include "input/joysticks/JoystickTranslator.h" -#include "input/joysticks/JoystickUtils.h" +#include "input/Key.h" #include "threads/SystemClock.h" #include "utils/log.h" +#include "ServiceBroker.h" #include <algorithm> #include <assert.h> #include <cmath> +using namespace KODI; using namespace JOYSTICK; using namespace XbmcThreads; #define MAPPING_COOLDOWN_MS 50 // Guard against repeated input #define AXIS_THRESHOLD 0.75f // Axis must exceed this value to be mapped +#define TRIGGER_DELAY_MS 200 // Delay trigger detection to handle anomalous triggers with non-zero center -CButtonMapping::CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMap, IActionMap* actionMap) - : m_buttonMapper(buttonMapper), - m_buttonMap(buttonMap), - m_actionMap(actionMap), - m_lastAction(0) +// --- CButtonDetector --------------------------------------------------------- + +CButtonDetector::CButtonDetector(CButtonMapping* buttonMapping, unsigned int buttonIndex) : + m_buttonMapping(buttonMapping), + m_buttonIndex(buttonIndex) { - assert(m_buttonMapper != NULL); - assert(m_buttonMap != NULL); } -bool CButtonMapping::OnButtonMotion(unsigned int buttonIndex, bool bPressed) +bool CButtonDetector::OnMotion(bool bPressed) { if (bPressed) { - CDriverPrimitive buttonPrimitive(PRIMITIVE_TYPE::BUTTON, buttonIndex); + CDriverPrimitive buttonPrimitive(PRIMITIVE_TYPE::BUTTON, m_buttonIndex); if (buttonPrimitive.IsValid()) { - return MapPrimitive(buttonPrimitive); + return m_buttonMapping->MapPrimitive(buttonPrimitive); } } return false; } -bool CButtonMapping::OnHatMotion(unsigned int hatIndex, HAT_STATE state) +// --- CHatDetector ------------------------------------------------------------ + +CHatDetector::CHatDetector(CButtonMapping* buttonMapping, unsigned int hatIndex) : + m_buttonMapping(buttonMapping), + m_hatIndex(hatIndex) +{ +} + +bool CHatDetector::OnMotion(HAT_STATE state) { - CDriverPrimitive hatPrimitive(hatIndex, static_cast<HAT_DIRECTION>(state)); + CDriverPrimitive hatPrimitive(m_hatIndex, static_cast<HAT_DIRECTION>(state)); if (hatPrimitive.IsValid()) { - MapPrimitive(hatPrimitive); + m_buttonMapping->MapPrimitive(hatPrimitive); return true; } return false; } -bool CButtonMapping::OnAxisMotion(unsigned int axisIndex, float position) +// --- CAxisDetector ----------------------------------------------------------- + +CAxisDetector::CAxisDetector(CButtonMapping* buttonMapping, unsigned int axisIndex, const AxisConfiguration& config) : + m_buttonMapping(buttonMapping), + m_axisIndex(axisIndex), + m_config(config), + m_state(AXIS_STATE::INACTIVE), + m_type(AXIS_TYPE::UNKNOWN), + m_initialPositionKnown(false), + m_initialPosition(0.0f), + m_initialPositionChanged(false), + m_activationTimeMs(0) +{ +} + +bool CAxisDetector::OnMotion(float position) { - const bool bInMotion = (position != 0.0f); - const bool bIsActive = (std::abs(position) >= AXIS_THRESHOLD); + DetectType(position); - if (!bInMotion) + if (m_type != AXIS_TYPE::UNKNOWN) { - CDriverPrimitive axis(axisIndex, SEMIAXIS_DIRECTION::POSITIVE); - CDriverPrimitive oppositeAxis(axisIndex, SEMIAXIS_DIRECTION::NEGATIVE); + // Update position if this axis is an anomalous trigger + if (m_type == AXIS_TYPE::OFFSET) + position = (position - m_config.center) / m_config.range; + + // Reset state if position crosses zero + if (m_state == AXIS_STATE::MAPPED) + { + SEMIAXIS_DIRECTION activatedDir = m_activatedPrimitive.SemiAxisDirection(); + SEMIAXIS_DIRECTION newDir = CJoystickTranslator::PositionToSemiAxisDirection(position); - OnMotionless(axis); - OnMotionless(oppositeAxis); + if (activatedDir != newDir) + m_state = AXIS_STATE::INACTIVE; + } - Deactivate(axis); - Deactivate(oppositeAxis); + // Check if axis has become activated + if (m_state == AXIS_STATE::INACTIVE) + { + if (std::abs(position) >= AXIS_THRESHOLD) + m_state = AXIS_STATE::ACTIVATED; + + if (m_state == AXIS_STATE::ACTIVATED) + { + // Range is set later for anomalous triggers + m_activatedPrimitive = CDriverPrimitive(m_axisIndex, m_config.center, CJoystickTranslator::PositionToSemiAxisDirection(position), 1); + m_activationTimeMs = SystemClockMillis(); + } + } } - else + + return true; +} + +void CAxisDetector::ProcessMotion() +{ + // Process newly-activated axis + if (m_state == AXIS_STATE::ACTIVATED) { - SEMIAXIS_DIRECTION dir = CJoystickTranslator::PositionToSemiAxisDirection(position); + // Ignore anomalous triggers for a bit so we can detect the full range + bool bIgnore = false; + if (m_type == AXIS_TYPE::OFFSET) + { + unsigned int elapsedMs = SystemClockMillis() - m_activationTimeMs; + if (elapsedMs < TRIGGER_DELAY_MS) + bIgnore = true; + } + + if (!bIgnore) + { + // Update driver primitive's range if we're mapping an anomalous trigger + if (m_type == AXIS_TYPE::OFFSET) + { + m_activatedPrimitive = CDriverPrimitive(m_activatedPrimitive.Index(), + m_activatedPrimitive.Center(), + m_activatedPrimitive.SemiAxisDirection(), + m_config.range); + } + + // Map primitive + if (!m_buttonMapping->MapPrimitive(m_activatedPrimitive)) + { + if (m_type == AXIS_TYPE::OFFSET) + CLog::Log(LOGDEBUG, "Mapping offset axis %u failed", m_axisIndex); + else + CLog::Log(LOGDEBUG, "Mapping normal axis %u failed", m_axisIndex); + } + + m_state = AXIS_STATE::MAPPED; + } + } +} + +void CAxisDetector::SetEmitted(const CDriverPrimitive& activePrimitive) +{ + m_state = AXIS_STATE::MAPPED; + m_activatedPrimitive = activePrimitive; +} + +void CAxisDetector::DetectType(float position) +{ + // Some platforms don't report a value until the axis is first changed. + // Detection relies on an initial value, so this axis will be disabled until + // the user begins button mapping again. + if (m_config.bLateDiscovery) + return; - CDriverPrimitive axis(axisIndex, dir); - CDriverPrimitive oppositeAxis(axisIndex, dir * -1); + // Update range if a range of > 1 is observed + if (std::abs(position - m_config.center) > 1.0f) + m_config.range = 2; - // OnMotion() occurs within ProcessAxisMotions() - OnMotionless(oppositeAxis); + if (m_type != AXIS_TYPE::UNKNOWN) + return; - if (bIsActive) - Activate(axis); + if (m_config.bKnown) + { + if (m_config.center == 0) + m_type = AXIS_TYPE::NORMAL; else - Deactivate(axis); - Deactivate(oppositeAxis); + m_type = AXIS_TYPE::OFFSET; } - return true; + if (m_type != AXIS_TYPE::UNKNOWN) + return; + + if (!m_initialPositionKnown) + { + m_initialPositionKnown = true; + m_initialPosition = position; + } + + if (position != m_initialPosition) + m_initialPositionChanged = true; + + if (m_initialPositionChanged) + { + // Calculate center based on initial position. + if (m_initialPosition < -0.5f) + { + m_config.center = -1; + m_type = AXIS_TYPE::OFFSET; + CLog::Log(LOGDEBUG, "Anomalous trigger detected on axis %u with center %d", m_axisIndex, m_config.center); + } + else if (m_initialPosition > 0.5f) + { + m_config.center = 1; + m_type = AXIS_TYPE::OFFSET; + CLog::Log(LOGDEBUG, "Anomalous trigger detected on axis %u with center %d", m_axisIndex, m_config.center); + } + else + { + m_type = AXIS_TYPE::NORMAL; + CLog::Log(LOGDEBUG, "Normal axis detected on axis %u", m_axisIndex); + } + } } -void CButtonMapping::ProcessAxisMotions(void) +// --- CButtonMapping ---------------------------------------------------------- + +CButtonMapping::CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMap, IActionMap* actionMap) : + m_buttonMapper(buttonMapper), + m_buttonMap(buttonMap), + m_actionMap(actionMap), + m_lastAction(0), + m_frameCount(0) { - // Process newly-activated axes - for (std::vector<ActivatedAxis>::iterator it = m_activatedAxes.begin(); it != m_activatedAxes.end(); ++it) + assert(m_buttonMapper != nullptr); + assert(m_buttonMap != nullptr); + + // Make sure axes mapped to Select are centered before they can be mapped. + // This ensures that they are not immediately mapped to the first button. + if (m_actionMap && m_actionMap->ControllerID() == m_buttonMap->ControllerID()) { - ActivatedAxis& semiaxis = *it; + using namespace GAME; + + CGameServices& gameServices = CServiceBroker::GetGameServices(); + ControllerPtr controller = gameServices.GetController(m_actionMap->ControllerID()); - // Only emit once - if (!semiaxis.bEmitted) + const auto& features = controller->Layout().Features(); + for (const auto& feature : features) { - semiaxis.bEmitted = true; - if (MapPrimitive(semiaxis.driverPrimitive)) - OnMotion(semiaxis.driverPrimitive); + if (m_actionMap->GetActionID(feature.Name()) != ACTION_SELECT_ITEM) + continue; + + CDriverPrimitive primitive; + if (!m_buttonMap->GetScalar(feature.Name(), primitive)) + continue; + + if (primitive.Type() != PRIMITIVE_TYPE::SEMIAXIS) + continue; + + // Set initial config, as detection will fail because axis is already activated + AxisConfiguration axisConfig; + axisConfig.bKnown = true; + axisConfig.center = primitive.Center(); + axisConfig.range = primitive.Range(); + + GetAxis(primitive.Index(), primitive.Center(), axisConfig).SetEmitted(primitive); } } +} + +bool CButtonMapping::OnButtonMotion(unsigned int buttonIndex, bool bPressed) +{ + return GetButton(buttonIndex).OnMotion(bPressed); +} + +bool CButtonMapping::OnHatMotion(unsigned int hatIndex, HAT_STATE state) +{ + return GetHat(hatIndex).OnMotion(state); +} - m_buttonMapper->OnEventFrame(m_buttonMap, IsMoving()); +bool CButtonMapping::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) +{ + return GetAxis(axisIndex, position).OnMotion(position); +} + +void CButtonMapping::ProcessAxisMotions(void) +{ + for (auto& axis : m_axes) + axis.second.ProcessMotion(); + + m_buttonMapper->OnEventFrame(m_buttonMap, IsMapping()); + + m_frameCount++; } void CButtonMapping::SaveButtonMap() @@ -177,42 +361,71 @@ bool CButtonMapping::MapPrimitive(const CDriverPrimitive& primitive) return bHandled; } -void CButtonMapping::OnMotion(const CDriverPrimitive& semiaxis) +bool CButtonMapping::IsMapping() const { - if (std::find(m_movingAxes.begin(), m_movingAxes.end(), semiaxis) == m_movingAxes.end()) - m_movingAxes.push_back(semiaxis); -} + for (auto itAxis : m_axes) + { + if (itAxis.second.IsMapping()) + return true; + } -void CButtonMapping::OnMotionless(const CDriverPrimitive& semiaxis) -{ - m_movingAxes.erase(std::remove(m_movingAxes.begin(), m_movingAxes.end(), semiaxis), m_movingAxes.end()); + return false; } -bool CButtonMapping::IsMoving() const +CButtonDetector& CButtonMapping::GetButton(unsigned int buttonIndex) { - return !m_movingAxes.empty(); + auto itButton = m_buttons.find(buttonIndex); + + if (itButton == m_buttons.end()) + { + m_buttons.insert(std::make_pair(buttonIndex, CButtonDetector(this, buttonIndex))); + itButton = m_buttons.find(buttonIndex); + } + + return itButton->second; } -void CButtonMapping::Activate(const CDriverPrimitive& semiaxis) +CHatDetector& CButtonMapping::GetHat(unsigned int hatIndex) { - if (!IsActive(semiaxis)) - m_activatedAxes.push_back(ActivatedAxis{semiaxis}); + auto itHat = m_hats.find(hatIndex); + + if (itHat == m_hats.end()) + { + m_hats.insert(std::make_pair(hatIndex, CHatDetector(this, hatIndex))); + itHat = m_hats.find(hatIndex); + } + + return itHat->second; } -void CButtonMapping::Deactivate(const CDriverPrimitive& semiaxis) +CAxisDetector& CButtonMapping::GetAxis(unsigned int axisIndex, + float position, + const AxisConfiguration& initialConfig /* = AxisConfiguration() */) { - m_activatedAxes.erase(std::remove_if(m_activatedAxes.begin(), m_activatedAxes.end(), - [&semiaxis](const ActivatedAxis& axis) + auto itAxis = m_axes.find(axisIndex); + + if (itAxis == m_axes.end()) + { + AxisConfiguration config(initialConfig); + + if (m_frameCount >= 2) { - return semiaxis == axis.driverPrimitive; - }), m_activatedAxes.end()); + config.bLateDiscovery = true; + OnLateDiscovery(axisIndex); + } + + // Report axis + CLog::Log(LOGDEBUG, "Axis %u discovered at position %.04f after %lu frames", + axisIndex, position, static_cast<unsigned long>(m_frameCount)); + + m_axes.insert(std::make_pair(axisIndex, CAxisDetector(this, axisIndex, config))); + itAxis = m_axes.find(axisIndex); + } + + return itAxis->second; } -bool CButtonMapping::IsActive(const CDriverPrimitive& semiaxis) const +void CButtonMapping::OnLateDiscovery(unsigned int axisIndex) { - return std::find_if(m_activatedAxes.begin(), m_activatedAxes.end(), - [&semiaxis](const ActivatedAxis& axis) - { - return semiaxis == axis.driverPrimitive; - }) != m_activatedAxes.end(); + m_buttonMapper->OnLateAxis(m_buttonMap, axisIndex); } diff --git a/xbmc/input/joysticks/generic/ButtonMapping.h b/xbmc/input/joysticks/generic/ButtonMapping.h index 33d22bcb5c..5961483977 100644 --- a/xbmc/input/joysticks/generic/ButtonMapping.h +++ b/xbmc/input/joysticks/generic/ButtonMapping.h @@ -23,10 +23,171 @@ #include "input/joysticks/IButtonMapCallback.h" #include "input/joysticks/IDriverHandler.h" -#include <vector> +#include <map> +#include <stdint.h> +namespace KODI +{ namespace JOYSTICK { + class CButtonMapping; + + class CButtonDetector + { + public: + CButtonDetector(CButtonMapping* buttonMapping, unsigned int buttonIndex); + + /*! + * \brief Button state has been updated + * + * \param bPressed The new state + * + * \return True if this press was absorbed, false if it should fall through + * to the next driver handler + */ + bool OnMotion(bool bPressed); + + private: + // Construction parameters + CButtonMapping* const m_buttonMapping; + const unsigned int m_buttonIndex; + }; + + class CHatDetector + { + public: + CHatDetector(CButtonMapping* buttonMapping, unsigned int hatIndex); + + /*! + * \brief Hat state has been updated + * + * \param state The new state + * + * \return True if state is a cardinal direction, false otherwise + */ + bool OnMotion(HAT_STATE state); + + private: + // Construction parameters + CButtonMapping* const m_buttonMapping; + const unsigned int m_hatIndex; + }; + + struct AxisConfiguration + { + bool bKnown = false; + int center = 0; + unsigned int range = 1; + bool bLateDiscovery = false; + }; + + class CAxisDetector + { + public: + CAxisDetector(CButtonMapping* buttonMapping, unsigned int axisIndex, const AxisConfiguration& config); + + /*! + * \brief Axis state has been updated + * + * \param position The new state + * + * \return Always true - axis motion events are always absorbed while button mapping + */ + bool OnMotion(float position); + + /*! + * \brief Called once per frame + * + * If an axis was activated, the button mapping command will be emitted + * here. + */ + void ProcessMotion(); + + /*! + * \brief Check if the axis was mapped and is still in motion + * + * \return True between when the axis is mapped and when it crosses zero + */ + bool IsMapping() const { return m_state == AXIS_STATE::MAPPED; } + + /*! + * \brief Set the state such that this axis has generated a mapping event + * + * If an axis is mapped to the Select action, it may be pressed when button + * mapping begins. This function is used to indicate that the axis shouldn't + * be mapped until after it crosses zero again. + */ + void SetEmitted(const CDriverPrimitive& activePrimitive); + + private: + enum class AXIS_STATE + { + /*! + * \brief Axis is inactive (position is less than threshold) + */ + INACTIVE, + + /*! + * \brief Axis is activated (position has exceeded threshold) + */ + ACTIVATED, + + /*! + * \brief Axis has generated a mapping event, but has not been centered yet + */ + MAPPED, + }; + + enum class AXIS_TYPE + { + /*! + * \brief Axis type is initially unknown + */ + UNKNOWN, + + /*! + * \brief Axis is centered about 0 + * + * - If the axis is an analog stick, it can travel to -1 or +1. + * - If the axis is a pressure-sensitive button or a normal trigger, + * it can travel to +1. + * - If the axis is a DirectInput trigger, then it is possible that two + * triggers can be on the same axis in opposite directions. + * - Normally, D-pads appear as a hat or four buttons. However, some + * D-pads are reported as two axes that can have the discrete values + * -1, 0 or 1. This is called a "discrete D-pad". + */ + NORMAL, + + /*! + * \brief Axis is centered about -1 or 1 + * + * - On OSX, with the cocoa driver, triggers are centered about -1 and + * travel to +1. In this case, the range is 2 and the direction is + * positive. + * - The author of SDL has observed triggers centered at +1 and travel + * to 0. In this case, the range is 1 and the direction is negative. + */ + OFFSET, + }; + + void DetectType(float position); + + // Construction parameters + CButtonMapping* const m_buttonMapping; + const unsigned int m_axisIndex; + AxisConfiguration m_config; // mutable + + // State variables + AXIS_STATE m_state; + CDriverPrimitive m_activatedPrimitive; + AXIS_TYPE m_type; + bool m_initialPositionKnown; // set to true on first motion + float m_initialPosition; // set to position of first motion + bool m_initialPositionChanged; // set to true when position differs from the initial position + unsigned int m_activationTimeMs; // only used to delay anomalous trigger mapping to detect full range + }; + class IActionMap; class IButtonMap; class IButtonMapper; @@ -39,7 +200,8 @@ namespace JOYSTICK * Button mapping commands are invoked instantly for buttons and hats. * * Button mapping commands are deferred for a short while after an axis is - * activated, and only one command will be invoked per activation. + * activated, and only one button mapping command will be invoked per + * activation. */ class CButtonMapping : public IDriverHandler, public IButtonMapCallback @@ -58,7 +220,7 @@ namespace JOYSTICK // implementation of IDriverHandler virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; virtual bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override; virtual void ProcessAxisMotions(void) override; // implementation of IButtonMapCallback @@ -66,7 +228,6 @@ namespace JOYSTICK virtual void ResetIgnoredPrimitives() override; virtual void RevertButtonMap() override; - private: /*! * \brief Process the primitive mapping command * @@ -80,29 +241,25 @@ namespace JOYSTICK */ bool MapPrimitive(const CDriverPrimitive& primitive); - // Motion functions - void OnMotion(const CDriverPrimitive& semiaxis); - void OnMotionless(const CDriverPrimitive& semiaxis); - bool IsMoving() const; + private: + bool IsMapping() const; + + void OnLateDiscovery(unsigned int axisIndex); - // Action functions - void Activate(const CDriverPrimitive& semiaxis); - void Deactivate(const CDriverPrimitive& semiaxis); - bool IsActive(const CDriverPrimitive& semiaxis) const; + CButtonDetector& GetButton(unsigned int buttonIndex); + CHatDetector& GetHat(unsigned int hatIndex); + CAxisDetector& GetAxis(unsigned int axisIndex, float position, const AxisConfiguration& initialConfig = AxisConfiguration()); // Construction parameters IButtonMapper* const m_buttonMapper; IButtonMap* const m_buttonMap; IActionMap* const m_actionMap; - struct ActivatedAxis - { - CDriverPrimitive driverPrimitive; - bool bEmitted; // true if this axis has emited a button-mapping command - }; - - std::vector<CDriverPrimitive> m_movingAxes; - std::vector<ActivatedAxis> m_activatedAxes; - unsigned int m_lastAction; + std::map<unsigned int, CButtonDetector> m_buttons; + std::map<unsigned int, CHatDetector> m_hats; + std::map<unsigned int, CAxisDetector> m_axes; + unsigned int m_lastAction; + uint64_t m_frameCount; }; } +} diff --git a/xbmc/input/joysticks/generic/DriverReceiving.cpp b/xbmc/input/joysticks/generic/DriverReceiving.cpp index d44eabd1c0..beb6bb9ea6 100644 --- a/xbmc/input/joysticks/generic/DriverReceiving.cpp +++ b/xbmc/input/joysticks/generic/DriverReceiving.cpp @@ -23,6 +23,7 @@ #include "input/joysticks/IButtonMap.h" #include "input/joysticks/IDriverReceiver.h" +using namespace KODI; using namespace JOYSTICK; CDriverReceiving::CDriverReceiving(IDriverReceiver* receiver, IButtonMap* buttonMap) diff --git a/xbmc/input/joysticks/generic/DriverReceiving.h b/xbmc/input/joysticks/generic/DriverReceiving.h index b35cfc442e..bfadfa5397 100644 --- a/xbmc/input/joysticks/generic/DriverReceiving.h +++ b/xbmc/input/joysticks/generic/DriverReceiving.h @@ -24,6 +24,8 @@ #include <map> +namespace KODI +{ namespace JOYSTICK { class IDriverReceiver; @@ -52,3 +54,4 @@ namespace JOYSTICK IButtonMap* const m_buttonMap; }; } +} diff --git a/xbmc/input/joysticks/generic/FeatureHandling.cpp b/xbmc/input/joysticks/generic/FeatureHandling.cpp index 850dd871ea..24a4b35d67 100644 --- a/xbmc/input/joysticks/generic/FeatureHandling.cpp +++ b/xbmc/input/joysticks/generic/FeatureHandling.cpp @@ -27,6 +27,7 @@ #include <vector> +using namespace KODI; using namespace JOYSTICK; #define ANALOG_DIGITAL_THRESHOLD 0.5f diff --git a/xbmc/input/joysticks/generic/FeatureHandling.h b/xbmc/input/joysticks/generic/FeatureHandling.h index 52d992be01..3d276771c0 100644 --- a/xbmc/input/joysticks/generic/FeatureHandling.h +++ b/xbmc/input/joysticks/generic/FeatureHandling.h @@ -23,6 +23,8 @@ #include <memory> +namespace KODI +{ namespace JOYSTICK { class CDriverPrimitive; @@ -225,3 +227,4 @@ namespace JOYSTICK float m_zAxisState; }; } +} diff --git a/xbmc/input/joysticks/generic/InputHandling.cpp b/xbmc/input/joysticks/generic/InputHandling.cpp index 6f42c1d81e..98ec01f3a5 100644 --- a/xbmc/input/joysticks/generic/InputHandling.cpp +++ b/xbmc/input/joysticks/generic/InputHandling.cpp @@ -25,6 +25,10 @@ #include "input/joysticks/JoystickUtils.h" #include "utils/log.h" +#include <array> +#include <cmath> + +using namespace KODI; using namespace JOYSTICK; CGUIDialogNewJoystick* const CInputHandling::m_dialog = new CGUIDialogNewJoystick; @@ -56,15 +60,33 @@ bool CInputHandling::OnHatMotion(unsigned int hatIndex, HAT_STATE state) return bHandled; } -bool CInputHandling::OnAxisMotion(unsigned int axisIndex, float position) +bool CInputHandling::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) { bool bHandled = false; - CDriverPrimitive positiveSemiaxis(axisIndex, SEMIAXIS_DIRECTION::POSITIVE); - CDriverPrimitive negativeSemiaxis(axisIndex, SEMIAXIS_DIRECTION::NEGATIVE); + if (center != 0) + { + float translatedPostion = std::min((position - center) / range, 1.0f); + + // Calculate the direction the trigger travels from the center point + SEMIAXIS_DIRECTION dir; + if (center > 0) + dir = SEMIAXIS_DIRECTION::NEGATIVE; + else + dir = SEMIAXIS_DIRECTION::POSITIVE; + + CDriverPrimitive offsetSemiaxis(axisIndex, center, dir, range); - bHandled |= OnAnalogMotion(positiveSemiaxis, position > 0.0f ? position : 0.0f); - bHandled |= OnAnalogMotion(negativeSemiaxis, position < 0.0f ? -position : 0.0f); + bHandled = OnAnalogMotion(offsetSemiaxis, translatedPostion); + } + else + { + CDriverPrimitive positiveSemiaxis(axisIndex, 0, SEMIAXIS_DIRECTION::POSITIVE, 1); + CDriverPrimitive negativeSemiaxis(axisIndex, 0, SEMIAXIS_DIRECTION::NEGATIVE, 1); + + bHandled |= OnAnalogMotion(positiveSemiaxis, position > 0.0f ? position : 0.0f); + bHandled |= OnAnalogMotion(negativeSemiaxis, position < 0.0f ? -position : 0.0f); + } return bHandled; } diff --git a/xbmc/input/joysticks/generic/InputHandling.h b/xbmc/input/joysticks/generic/InputHandling.h index e5588b19de..2a0f2453f0 100644 --- a/xbmc/input/joysticks/generic/InputHandling.h +++ b/xbmc/input/joysticks/generic/InputHandling.h @@ -25,6 +25,8 @@ #include <map> +namespace KODI +{ namespace JOYSTICK { class CDriverPrimitive; @@ -55,7 +57,7 @@ namespace JOYSTICK // implementation of IDriverHandler virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; virtual bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override; virtual void ProcessAxisMotions(void) override; private: @@ -72,3 +74,4 @@ namespace JOYSTICK static CGUIDialogNewJoystick* const m_dialog; }; } +} diff --git a/xbmc/input/keyboard/CMakeLists.txt b/xbmc/input/keyboard/CMakeLists.txt index ed121ac30a..69d84b8d3a 100644 --- a/xbmc/input/keyboard/CMakeLists.txt +++ b/xbmc/input/keyboard/CMakeLists.txt @@ -1,6 +1,11 @@ -set(SOURCES KeyboardEasterEgg.cpp) +set(SOURCES KeyboardEasterEgg.cpp + KeymapActionMap.cpp +) -set(HEADERS IKeyboardHandler.h - KeyboardEasterEgg.h) +set(HEADERS IActionMap.h + IKeyboardHandler.h + KeyboardEasterEgg.h + KeymapActionMap.h +) core_add_library(input_keyboard) diff --git a/xbmc/input/keyboard/IActionMap.h b/xbmc/input/keyboard/IActionMap.h new file mode 100644 index 0000000000..ae89742d41 --- /dev/null +++ b/xbmc/input/keyboard/IActionMap.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +class CKey; + +namespace KODI +{ +namespace KEYBOARD +{ + /*! + * \brief Interface for translating keys to action IDs + */ + class IActionMap + { + public: + virtual ~IActionMap() = default; + + /*! + * \brief Get the action ID mapped to the specified key + * + * \param key The key to look up + * + * \return The action ID from Action.h, or ACTION_NONE if no action is + * mapped to the specified key + */ + virtual unsigned int GetActionID(const CKey& key) = 0; + }; +} +} diff --git a/xbmc/input/keyboard/IKeyboardHandler.h b/xbmc/input/keyboard/IKeyboardHandler.h index 5958aac650..b19712bbc1 100644 --- a/xbmc/input/keyboard/IKeyboardHandler.h +++ b/xbmc/input/keyboard/IKeyboardHandler.h @@ -21,6 +21,8 @@ class CKey; +namespace KODI +{ namespace KEYBOARD { /*! @@ -49,3 +51,4 @@ namespace KEYBOARD virtual void OnKeyRelease(const CKey& key) = 0; }; } +} diff --git a/xbmc/input/keyboard/KeyboardEasterEgg.cpp b/xbmc/input/keyboard/KeyboardEasterEgg.cpp index a2f089256c..c9fd7179b9 100644 --- a/xbmc/input/keyboard/KeyboardEasterEgg.cpp +++ b/xbmc/input/keyboard/KeyboardEasterEgg.cpp @@ -22,6 +22,7 @@ #include "input/joysticks/JoystickEasterEgg.h" #include "input/Key.h" +using namespace KODI; using namespace KEYBOARD; std::vector<XBMCVKey> CKeyboardEasterEgg::m_sequence = { diff --git a/xbmc/input/keyboard/KeyboardEasterEgg.h b/xbmc/input/keyboard/KeyboardEasterEgg.h index 7d3888644c..e98187be26 100644 --- a/xbmc/input/keyboard/KeyboardEasterEgg.h +++ b/xbmc/input/keyboard/KeyboardEasterEgg.h @@ -24,6 +24,8 @@ #include <vector> +namespace KODI +{ namespace KEYBOARD { /*! @@ -45,3 +47,4 @@ namespace KEYBOARD unsigned int m_state; }; } +} diff --git a/xbmc/input/keyboard/KeymapActionMap.cpp b/xbmc/input/keyboard/KeymapActionMap.cpp new file mode 100644 index 0000000000..41fe927186 --- /dev/null +++ b/xbmc/input/keyboard/KeymapActionMap.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "KeymapActionMap.h" +#include "guilib/GUIWindowManager.h" +#include "input/Action.h" +#include "input/ButtonTranslator.h" +#include "input/Key.h" + +using namespace KODI; +using namespace KEYBOARD; + +unsigned int CKeymapActionMap::GetActionID(const CKey& key) +{ + CAction action = CButtonTranslator::GetInstance().GetAction(g_windowManager.GetActiveWindowID(), key); + return action.GetID(); +} diff --git a/xbmc/input/keyboard/KeymapActionMap.h b/xbmc/input/keyboard/KeymapActionMap.h new file mode 100644 index 0000000000..8f67cc8686 --- /dev/null +++ b/xbmc/input/keyboard/KeymapActionMap.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "input/keyboard/IActionMap.h" + +namespace KODI +{ +namespace KEYBOARD +{ + class CKeymapActionMap : public IActionMap + { + public: + CKeymapActionMap(void) = default; + + virtual ~CKeymapActionMap(void) = default; + + // implementation of IActionMap + virtual unsigned int GetActionID(const CKey& key) override; + }; +} +} diff --git a/xbmc/input/keyboard/generic/JoystickEmulation.cpp b/xbmc/input/keyboard/generic/JoystickEmulation.cpp index de4ce1850f..f292b2b5fd 100644 --- a/xbmc/input/keyboard/generic/JoystickEmulation.cpp +++ b/xbmc/input/keyboard/generic/JoystickEmulation.cpp @@ -27,6 +27,7 @@ #define BUTTON_INDEX_MASK 0x01ff +using namespace KODI; using namespace KEYBOARD; CJoystickEmulation::CJoystickEmulation(JOYSTICK::IDriverHandler* handler) : diff --git a/xbmc/input/keyboard/generic/JoystickEmulation.h b/xbmc/input/keyboard/generic/JoystickEmulation.h index 1bab9b7434..12bc40301a 100644 --- a/xbmc/input/keyboard/generic/JoystickEmulation.h +++ b/xbmc/input/keyboard/generic/JoystickEmulation.h @@ -23,6 +23,8 @@ #include <vector> +namespace KODI +{ namespace JOYSTICK { class IDriverHandler; @@ -63,3 +65,4 @@ namespace KEYBOARD std::vector<KeyEvent> m_pressedKeys; }; } +} diff --git a/xbmc/input/mouse/IMouseButtonMap.h b/xbmc/input/mouse/IMouseButtonMap.h index 80d812da4f..2f24161056 100644 --- a/xbmc/input/mouse/IMouseButtonMap.h +++ b/xbmc/input/mouse/IMouseButtonMap.h @@ -21,6 +21,8 @@ #include <string> +namespace KODI +{ namespace MOUSE { /*! @@ -73,3 +75,4 @@ namespace MOUSE virtual bool GetButtonIndex(const std::string& feature, unsigned int& buttonIndex) = 0; }; } +} diff --git a/xbmc/input/mouse/IMouseDriverHandler.h b/xbmc/input/mouse/IMouseDriverHandler.h index 9da004a4a4..b3d674016c 100644 --- a/xbmc/input/mouse/IMouseDriverHandler.h +++ b/xbmc/input/mouse/IMouseDriverHandler.h @@ -19,6 +19,8 @@ */ #pragma once +namespace KODI +{ namespace MOUSE { /*! @@ -57,3 +59,4 @@ namespace MOUSE virtual void OnButtonRelease(unsigned int button) = 0; }; } +} diff --git a/xbmc/input/mouse/IMouseInputHandler.h b/xbmc/input/mouse/IMouseInputHandler.h index 6eda79b954..c388229181 100644 --- a/xbmc/input/mouse/IMouseInputHandler.h +++ b/xbmc/input/mouse/IMouseInputHandler.h @@ -21,6 +21,8 @@ #include <string> +namespace KODI +{ namespace MOUSE { /*! @@ -67,3 +69,4 @@ namespace MOUSE virtual void OnButtonRelease(const std::string& button) = 0; }; } +} diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.cpp b/xbmc/input/mouse/MouseWindowingButtonMap.cpp index e2da4ae005..11442c596a 100644 --- a/xbmc/input/mouse/MouseWindowingButtonMap.cpp +++ b/xbmc/input/mouse/MouseWindowingButtonMap.cpp @@ -23,6 +23,7 @@ #include <algorithm> +using namespace KODI; using namespace MOUSE; #define CONTROLLER_PROFILE "game.controller.mouse" diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.h b/xbmc/input/mouse/MouseWindowingButtonMap.h index a728257178..f3c7c43d23 100644 --- a/xbmc/input/mouse/MouseWindowingButtonMap.h +++ b/xbmc/input/mouse/MouseWindowingButtonMap.h @@ -25,6 +25,8 @@ #include <utility> #include <vector> +namespace KODI +{ namespace MOUSE { /*! @@ -47,3 +49,4 @@ namespace MOUSE static std::string m_pointerName; }; } +} diff --git a/xbmc/input/mouse/generic/MouseInputHandling.cpp b/xbmc/input/mouse/generic/MouseInputHandling.cpp index 641dd48ecb..9459b4bb4c 100644 --- a/xbmc/input/mouse/generic/MouseInputHandling.cpp +++ b/xbmc/input/mouse/generic/MouseInputHandling.cpp @@ -22,6 +22,7 @@ #include "input/mouse/IMouseButtonMap.h" #include "input/mouse/IMouseInputHandler.h" +using namespace KODI; using namespace MOUSE; CMouseInputHandling::CMouseInputHandling(IMouseInputHandler* handler, IMouseButtonMap* buttonMap) : diff --git a/xbmc/input/mouse/generic/MouseInputHandling.h b/xbmc/input/mouse/generic/MouseInputHandling.h index be1f7a94b6..291e1da9fd 100644 --- a/xbmc/input/mouse/generic/MouseInputHandling.h +++ b/xbmc/input/mouse/generic/MouseInputHandling.h @@ -21,6 +21,8 @@ #include "input/mouse/IMouseDriverHandler.h" +namespace KODI +{ namespace MOUSE { class IMouseInputHandler; @@ -53,3 +55,4 @@ namespace MOUSE int m_y; }; } +} diff --git a/xbmc/interfaces/json-rpc/FileOperations.cpp b/xbmc/interfaces/json-rpc/FileOperations.cpp index ab0ed83a67..1797e4a5db 100644 --- a/xbmc/interfaces/json-rpc/FileOperations.cpp +++ b/xbmc/interfaces/json-rpc/FileOperations.cpp @@ -100,7 +100,7 @@ JSONRPC_STATUS CFileOperations::GetDirectory(const std::string &method, ITranspo else if (media == "pictures") { regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps; - extensions = g_advancedSettings.m_pictureExtensions; + extensions = g_advancedSettings.GetPictureExtensions(); } if (CDirectory::GetDirectory(strPath, items, extensions)) @@ -362,7 +362,7 @@ bool CFileOperations::FillFileItemList(const CVariant ¶meterObject, CFileIte else if (media == "pictures") { regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps; - extensions = g_advancedSettings.m_pictureExtensions; + extensions = g_advancedSettings.GetPictureExtensions(); } CDirectory directory; diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp index 6fbd6e2be7..9d7cde95c1 100644 --- a/xbmc/interfaces/json-rpc/PVROperations.cpp +++ b/xbmc/interfaces/json-rpc/PVROperations.cpp @@ -180,20 +180,12 @@ JSONRPC_STATUS CPVROperations::GetBroadcastDetails(const std::string &method, IT if (!g_PVRManager.IsStarted()) return FailedToExecute; - EpgSearchFilter filter; - filter.Reset(); - filter.m_iUniqueBroadcastId = parameterObject["broadcastid"].asUnsignedInteger(); - - CFileItemList broadcasts; - int resultSize = g_EpgContainer.GetEPGSearch(broadcasts, filter); + const CEpgInfoTagPtr epgTag = g_EpgContainer.GetTagById(CPVRChannelPtr(), parameterObject["broadcastid"].asUnsignedInteger()); - if (resultSize <= 0) + if (!epgTag) return InvalidParams; - else if (resultSize > 1) - return InternalError; - CFileItemPtr broadcast = broadcasts.Get(0); - HandleFileItem("broadcastid", false, "broadcastdetails", broadcast, parameterObject, parameterObject["properties"], result, false); + HandleFileItem("broadcastid", false, "broadcastdetails", CFileItemPtr(new CFileItem(epgTag)), parameterObject, parameterObject["properties"], result, false); return OK; } @@ -403,6 +395,9 @@ JSONRPC_STATUS CPVROperations::ToggleTimer(const std::string &method, ITransport else { timer = CPVRTimerInfoTag::CreateFromEpg(epgTag, timerrule); + if (!timer) + return InvalidParams; + sentOkay = g_PVRTimers->AddTimer(timer); } diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp index e192b54d0b..f325ee0df2 100644 --- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp +++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp @@ -1156,7 +1156,7 @@ JSONRPC_STATUS CPlayerOperations::StartSlideshow(const std::string& path, bool r g_application.WakeUpScreenSaverAndDPMS(); CGUIMessage msg(GUI_MSG_START_SLIDESHOW, 0, 0, flags); msg.SetStringParams(params); - CApplicationMessenger::GetInstance().SendGUIMessage(msg, WINDOW_SLIDESHOW, true); + CApplicationMessenger::GetInstance().SendGUIMessage(msg, WINDOW_SLIDESHOW); return ACK; } diff --git a/xbmc/interfaces/legacy/LanguageHook.cpp b/xbmc/interfaces/legacy/LanguageHook.cpp index 3ffab45bb5..70c5700570 100644 --- a/xbmc/interfaces/legacy/LanguageHook.cpp +++ b/xbmc/interfaces/legacy/LanguageHook.cpp @@ -28,8 +28,8 @@ namespace XBMCAddon LanguageHook::~LanguageHook() {} static XbmcThreads::ThreadLocal<LanguageHook> addonLanguageHookTls; - static bool threadLocalInitilialized = false; - static xbmcutil::InitFlag initer(threadLocalInitilialized); + static bool threadLocalInitialized = false; + static xbmcutil::InitFlag initer(threadLocalInitialized); void LanguageHook::SetLanguageHook(LanguageHook* languageHook) { @@ -40,7 +40,7 @@ namespace XBMCAddon LanguageHook* LanguageHook::GetLanguageHook() { - return threadLocalInitilialized ? addonLanguageHookTls.get() : NULL; + return threadLocalInitialized ? addonLanguageHookTls.get() : NULL; } void LanguageHook::ClearLanguageHook() diff --git a/xbmc/interfaces/legacy/ListItem.cpp b/xbmc/interfaces/legacy/ListItem.cpp index c82be42828..99ec1853eb 100644 --- a/xbmc/interfaces/legacy/ListItem.cpp +++ b/xbmc/interfaces/legacy/ListItem.cpp @@ -139,36 +139,44 @@ namespace XBMCAddon if (!item) return; { LOCKGUIIF(m_offscreen); - for (Properties::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) + for (const auto& it: dictionary) { - std::string artName = it->first; + std::string artName = it.first; StringUtils::ToLower(artName); if (artName == "icon") - item->SetIconImage(it->second); + item->SetIconImage(it.second); else - item->SetArt(artName, it->second); + item->SetArt(artName, it.second); } } } - void ListItem::setUniqueIDs(const Properties& dictionary) + void ListItem::setUniqueIDs(const Properties& dictionary, const String& defaultrating /* = "" */) { if (!item) return; - LOCKGUI; + LOCKGUIIF(m_offscreen); CVideoInfoTag& vtag = *item->GetVideoInfoTag(); - for (Properties::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) - vtag.SetUniqueID(it->second, it->first); + for (const auto& it : dictionary) + vtag.SetUniqueID(it.second, it.first, it.first == defaultrating); } void ListItem::setRating(std::string type, float rating, int votes /* = 0 */, bool defaultt /* = false */) { if (!item) return; - LOCKGUI; + LOCKGUIIF(m_offscreen); item->GetVideoInfoTag()->SetRating(rating, votes, type, defaultt); } + void ListItem::addSeason(int number, std::string name /* = "" */) + { + if (!item) return; + + LOCKGUIIF(m_offscreen); + item->GetVideoInfoTag()->m_namedSeasons[number] = name; + } + void ListItem::select(bool selected) { if (!item) return; @@ -209,13 +217,13 @@ namespace XBMCAddon else if (lowerKey == "totaltime") { CBookmark resumePoint(item->GetVideoInfoTag()->GetResumePoint()); - resumePoint.totalTimeInSeconds = (float)atof(value.c_str()); + resumePoint.totalTimeInSeconds = static_cast<float>(atof(value.c_str())); item->GetVideoInfoTag()->SetResumePoint(resumePoint); } else if (lowerKey == "resumetime") { CBookmark resumePoint(item->GetVideoInfoTag()->GetResumePoint()); - resumePoint.timeInSeconds = (float)atof(value.c_str()); + resumePoint.timeInSeconds = static_cast<float>(atof(value.c_str())); item->GetVideoInfoTag()->SetResumePoint(resumePoint); } else if (lowerKey == "specialsort") @@ -262,19 +270,19 @@ namespace XBMCAddon String ListItem::getUniqueID(const char* key) { - LOCKGUI; + LOCKGUIIF(m_offscreen); return item->GetVideoInfoTag()->GetUniqueID(key); } float ListItem::getRating(const char* key) { - LOCKGUI; + LOCKGUIIF(m_offscreen); return item->GetVideoInfoTag()->GetRating(key).rating; } int ListItem::getVotes(const char* key) { - LOCKGUI; + LOCKGUIIF(m_offscreen); return item->GetVideoInfoTag()->GetRating(key).votes; } @@ -326,7 +334,7 @@ namespace XBMCAddon String ListItem::getPath() { - LOCKGUI; + LOCKGUIIF(m_offscreen); return item->GetPath(); } @@ -336,64 +344,72 @@ namespace XBMCAddon if (strcmpi(type, "video") == 0) { - for (InfoLabelDict::const_iterator it = infoLabels.begin(); it != infoLabels.end(); ++it) + auto& videotag = *item->GetVideoInfoTag(); + for (const auto& it: infoLabels) { - String key = it->first; + String key = it.first; StringUtils::ToLower(key); - const InfoLabelValue& alt = it->second; + const InfoLabelValue& alt = it.second; const String value(alt.which() == first ? alt.former() : emptyString); if (key == "dbid") - item->GetVideoInfoTag()->m_iDbId = strtol(value.c_str(), NULL, 10); + videotag.m_iDbId = strtol(value.c_str(), nullptr, 10); else if (key == "year") - item->GetVideoInfoTag()->SetYear(strtol(value.c_str(), NULL, 10)); + videotag.SetYear(strtol(value.c_str(), nullptr, 10)); else if (key == "episode") - item->GetVideoInfoTag()->m_iEpisode = strtol(value.c_str(), NULL, 10); + videotag.m_iEpisode = strtol(value.c_str(), nullptr, 10); else if (key == "season") - item->GetVideoInfoTag()->m_iSeason = strtol(value.c_str(), NULL, 10); + videotag.m_iSeason = strtol(value.c_str(), nullptr, 10); + else if (key == "sortepisode") + videotag.m_iSpecialSortEpisode = strtol(value.c_str(), nullptr, 10); + else if (key == "sortseason") + videotag.m_iSpecialSortSeason = strtol(value.c_str(), nullptr, 10); + else if (key == "episodeguide") + videotag.SetEpisodeGuide(value); + else if (key == "showlink") + videotag.SetShowLink(getStringArray(alt, key, value)); else if (key == "top250") - item->GetVideoInfoTag()->m_iTop250 = strtol(value.c_str(), NULL, 10); + videotag.m_iTop250 = strtol(value.c_str(), nullptr, 10); else if (key == "setid") - item->GetVideoInfoTag()->m_iSetId = strtol(value.c_str(), NULL, 10); + videotag.m_iSetId = strtol(value.c_str(), nullptr, 10); else if (key == "tracknumber") - item->GetVideoInfoTag()->m_iTrack = strtol(value.c_str(), NULL, 10); + videotag.m_iTrack = strtol(value.c_str(), nullptr, 10); else if (key == "count") - item->m_iprogramCount = strtol(value.c_str(), NULL, 10); + item->m_iprogramCount = strtol(value.c_str(), nullptr, 10); else if (key == "rating") - item->GetVideoInfoTag()->SetRating((float)strtod(value.c_str(), NULL)); + videotag.SetRating(static_cast<float>(strtod(value.c_str(), nullptr))); else if (key == "userrating") - item->GetVideoInfoTag()->m_iUserRating = strtol(value.c_str(), NULL, 10); + videotag.m_iUserRating = strtol(value.c_str(), nullptr, 10); else if (key == "size") - item->m_dwSize = (int64_t)strtoll(value.c_str(), NULL, 10); + item->m_dwSize = (int64_t)strtoll(value.c_str(), nullptr, 10); else if (key == "watched") // backward compat - do we need it? - item->GetVideoInfoTag()->SetPlayCount(strtol(value.c_str(), NULL, 10)); + videotag.SetPlayCount(strtol(value.c_str(), nullptr, 10)); else if (key == "playcount") - item->GetVideoInfoTag()->SetPlayCount(strtol(value.c_str(), NULL, 10)); + videotag.SetPlayCount(strtol(value.c_str(), nullptr, 10)); else if (key == "overlay") { - long overlay = strtol(value.c_str(), NULL, 10); + long overlay = strtol(value.c_str(), nullptr, 10); if (overlay >= 0 && overlay <= 8) - item->SetOverlayImage((CGUIListItem::GUIIconOverlay)overlay); + item->SetOverlayImage(static_cast<CGUIListItem::GUIIconOverlay>(overlay)); } else if (key == "cast" || key == "castandrole") { if (alt.which() != second) throw WrongTypeException("When using \"cast\" or \"castandrole\" you need to supply a list of tuples for the value in the dictionary"); - item->GetVideoInfoTag()->m_cast.clear(); + videotag.m_cast.clear(); const std::vector<InfoLabelStringOrTuple>& listValue = alt.later(); - for (std::vector<InfoLabelStringOrTuple>::const_iterator viter = listValue.begin(); viter != listValue.end(); ++viter) + for (const auto& castEntry: alt.later()) { - const InfoLabelStringOrTuple& castEntry = *viter; // castEntry can be a string meaning it's the actor or it can be a tuple meaning it's the // actor and the role. const String& actor = castEntry.which() == first ? castEntry.former() : castEntry.later().first(); SActorInfo info; info.strName = actor; if (castEntry.which() == second) - info.strRole = (const String&)(castEntry.later().second()); - item->GetVideoInfoTag()->m_cast.push_back(info); + info.strRole = static_cast<const String&>(castEntry.later().second()); + videotag.m_cast.push_back(info); } } else if (key == "artist") @@ -401,73 +417,73 @@ namespace XBMCAddon if (alt.which() != second) throw WrongTypeException("When using \"artist\" you need to supply a list of strings for the value in the dictionary"); - item->GetVideoInfoTag()->m_artist.clear(); + videotag.m_artist.clear(); const std::vector<InfoLabelStringOrTuple>& listValue = alt.later(); - for (std::vector<InfoLabelStringOrTuple>::const_iterator viter = listValue.begin(); viter != listValue.end(); ++viter) + for (const auto& castEntry: alt.later()) { - - const InfoLabelStringOrTuple& castEntry = *viter; const String& actor = castEntry.which() == first ? castEntry.former() : castEntry.later().first(); - item->GetVideoInfoTag()->m_artist.push_back(actor); + videotag.m_artist.push_back(actor); } } else if (key == "genre") - item->GetVideoInfoTag()->m_genre = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.SetGenre(getStringArray(alt, key, value)); else if (key == "country") - item->GetVideoInfoTag()->m_country = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.SetCountry(getStringArray(alt, key, value)); else if (key == "director") - item->GetVideoInfoTag()->m_director = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.SetDirector(getStringArray(alt, key, value)); else if (key == "mpaa") - item->GetVideoInfoTag()->m_strMPAARating = value; + videotag.SetMPAARating(value); else if (key == "plot") - item->GetVideoInfoTag()->m_strPlot = value; + videotag.SetPlot(value); else if (key == "plotoutline") - item->GetVideoInfoTag()->m_strPlotOutline = value; + videotag.SetPlotOutline(value); else if (key == "title") - item->GetVideoInfoTag()->m_strTitle = value; + videotag.SetTitle(value); else if (key == "originaltitle") - item->GetVideoInfoTag()->m_strOriginalTitle = value; + videotag.SetOriginalTitle(value); else if (key == "sorttitle") - item->GetVideoInfoTag()->m_strSortTitle = value; + videotag.SetSortTitle(value); else if (key == "duration") - item->GetVideoInfoTag()->SetDuration(strtol(value.c_str(), NULL, 10)); + videotag.SetDuration(strtol(value.c_str(), nullptr, 10)); else if (key == "studio") - item->GetVideoInfoTag()->m_studio = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.SetStudio(getStringArray(alt, key, value)); else if (key == "tagline") - item->GetVideoInfoTag()->m_strTagLine = value; - else if (key == "writer") - item->GetVideoInfoTag()->m_writingCredits = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.SetTagLine(value); + else if (key == "writer" || key == "credits") + videotag.SetWritingCredits(getStringArray(alt, key, value)); else if (key == "tvshowtitle") - item->GetVideoInfoTag()->m_strShowTitle = value; + videotag.SetShowTitle(value); else if (key == "premiered") { CDateTime premiered; premiered.SetFromDateString(value); - item->GetVideoInfoTag()->SetPremiered(premiered); + videotag.SetPremiered(premiered); } else if (key == "status") - item->GetVideoInfoTag()->m_strStatus = value; + videotag.SetStatus(value); else if (key == "set") - item->GetVideoInfoTag()->m_strSet = value; + videotag.SetSet(value); + else if (key == "setoverview") + videotag.SetSetOverview(value); + else if (key == "tag") + videotag.SetTags(getStringArray(alt, key, value)); else if (key == "imdbnumber") - item->GetVideoInfoTag()->SetUniqueID(value); + videotag.SetUniqueID(value); else if (key == "code") - item->GetVideoInfoTag()->m_strProductionCode = value; + videotag.SetProductionCode(value); else if (key == "aired") - item->GetVideoInfoTag()->m_firstAired.SetFromDateString(value); - else if (key == "credits") - item->GetVideoInfoTag()->m_writingCredits = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + videotag.m_firstAired.SetFromDateString(value); else if (key == "lastplayed") - item->GetVideoInfoTag()->m_lastPlayed.SetFromDBDateTime(value); + videotag.m_lastPlayed.SetFromDBDateTime(value); else if (key == "album") - item->GetVideoInfoTag()->m_strAlbum = value; + videotag.SetAlbum(value); else if (key == "votes") - item->GetVideoInfoTag()->SetVotes(StringUtils::ReturnDigits(value)); + videotag.SetVotes(StringUtils::ReturnDigits(value)); else if (key == "trailer") - item->GetVideoInfoTag()->m_strTrailer = value; + videotag.SetTrailer(value); else if (key == "path") - item->GetVideoInfoTag()->m_strPath = value; + videotag.SetPath(value); else if (key == "date") { if (value.length() == 10) @@ -481,11 +497,11 @@ namespace XBMCAddon CLog::Log(LOGERROR,"NEWADDON Invalid Date Format \"%s\"",value.c_str()); } else if (key == "dateadded") - item->GetVideoInfoTag()->m_dateAdded.SetFromDBDateTime(value.c_str()); + videotag.m_dateAdded.SetFromDBDateTime(value.c_str()); else if (key == "mediatype") { if (CMediaTypes::IsValidMediaType(value)) - item->GetVideoInfoTag()->m_type = value; + videotag.m_type = value; else CLog::Log(LOGWARNING, "Invalid media type \"%s\"", value.c_str()); } @@ -514,59 +530,60 @@ namespace XBMCAddon CLog::Log(LOGWARNING, "Invalid media type \"%s\"", value.c_str()); } } - for (InfoLabelDict::const_iterator it = infoLabels.begin(); it != infoLabels.end(); ++it) + auto& musictag = *item->GetMusicInfoTag(); + for (const auto& it : infoLabels) { - String key = it->first; + String key = it.first; StringUtils::ToLower(key); - const InfoLabelValue& alt = it->second; + const InfoLabelValue& alt = it.second; const String value(alt.which() == first ? alt.former() : emptyString); //! @todo add the rest of the infolabels if (key == "dbid" && !type.empty()) - item->GetMusicInfoTag()->SetDatabaseId(strtol(value.c_str(), NULL, 10), type); + musictag.SetDatabaseId(strtol(value.c_str(), NULL, 10), type); else if (key == "tracknumber") - item->GetMusicInfoTag()->SetTrackNumber(strtol(value.c_str(), NULL, 10)); + musictag.SetTrackNumber(strtol(value.c_str(), NULL, 10)); else if (key == "discnumber") - item->GetMusicInfoTag()->SetDiscNumber(strtol(value.c_str(), NULL, 10)); + musictag.SetDiscNumber(strtol(value.c_str(), nullptr, 10)); else if (key == "count") - item->m_iprogramCount = strtol(value.c_str(), NULL, 10); + item->m_iprogramCount = strtol(value.c_str(), nullptr, 10); else if (key == "size") - item->m_dwSize = (int64_t)strtoll(value.c_str(), NULL, 10); + item->m_dwSize = static_cast<int64_t>(strtoll(value.c_str(), nullptr, 10)); else if (key == "duration") - item->GetMusicInfoTag()->SetDuration(strtol(value.c_str(), NULL, 10)); + musictag.SetDuration(strtol(value.c_str(), nullptr, 10)); else if (key == "year") - item->GetMusicInfoTag()->SetYear(strtol(value.c_str(), NULL, 10)); + musictag.SetYear(strtol(value.c_str(), nullptr, 10)); else if (key == "listeners") - item->GetMusicInfoTag()->SetListeners(strtol(value.c_str(), NULL, 10)); + musictag.SetListeners(strtol(value.c_str(), nullptr, 10)); else if (key == "playcount") - item->GetMusicInfoTag()->SetPlayCount(strtol(value.c_str(), NULL, 10)); + musictag.SetPlayCount(strtol(value.c_str(), nullptr, 10)); else if (key == "genre") - item->GetMusicInfoTag()->SetGenre(value); + musictag.SetGenre(value); else if (key == "album") - item->GetMusicInfoTag()->SetAlbum(value); + musictag.SetAlbum(value); else if (key == "artist") - item->GetMusicInfoTag()->SetArtist(value); + musictag.SetArtist(value); else if (key == "title") - item->GetMusicInfoTag()->SetTitle(value); + musictag.SetTitle(value); else if (key == "rating") - item->GetMusicInfoTag()->SetRating((float)strtod(value.c_str(), NULL)); + musictag.SetRating(static_cast<float>(strtod(value.c_str(), nullptr))); else if (key == "userrating") - item->GetMusicInfoTag()->SetUserrating(strtol(value.c_str(), NULL, 10)); + musictag.SetUserrating(strtol(value.c_str(), nullptr, 10)); else if (key == "lyrics") - item->GetMusicInfoTag()->SetLyrics(value); + musictag.SetLyrics(value); else if (key == "lastplayed") - item->GetMusicInfoTag()->SetLastPlayed(value); + musictag.SetLastPlayed(value); else if (key == "musicbrainztrackid") - item->GetMusicInfoTag()->SetMusicBrainzTrackID(value); + musictag.SetMusicBrainzTrackID(value); else if (key == "musicbrainzartistid") - item->GetMusicInfoTag()->SetMusicBrainzArtistID(StringUtils::Split(value, g_advancedSettings.m_musicItemSeparator)); + musictag.SetMusicBrainzArtistID(StringUtils::Split(value, g_advancedSettings.m_musicItemSeparator)); else if (key == "musicbrainzalbumid") - item->GetMusicInfoTag()->SetMusicBrainzAlbumID(value); + musictag.SetMusicBrainzAlbumID(value); else if (key == "musicbrainzalbumartistid") - item->GetMusicInfoTag()->SetMusicBrainzAlbumArtistID(StringUtils::Split(value, g_advancedSettings.m_musicItemSeparator)); + musictag.SetMusicBrainzAlbumArtistID(StringUtils::Split(value, g_advancedSettings.m_musicItemSeparator)); else if (key == "comment") - item->GetMusicInfoTag()->SetComment(value); + musictag.SetComment(value); else if (key == "date") { if (strlen(value.c_str()) == 10) @@ -582,23 +599,23 @@ namespace XBMCAddon // This should probably be set outside of the loop but since the original // implementation set it inside of the loop, I'll leave it that way. - Jim C. - item->GetMusicInfoTag()->SetLoaded(true); + musictag.SetLoaded(true); } } else if (strcmpi(type,"pictures") == 0) { - for (InfoLabelDict::const_iterator it = infoLabels.begin(); it != infoLabels.end(); ++it) + for (const auto& it: infoLabels) { - String key = it->first; + String key = it.first; StringUtils::ToLower(key); - const InfoLabelValue& alt = it->second; + const InfoLabelValue& alt = it.second; const String value(alt.which() == first ? alt.former() : emptyString); if (key == "count") - item->m_iprogramCount = strtol(value.c_str(), NULL, 10); + item->m_iprogramCount = strtol(value.c_str(), nullptr, 10); else if (key == "size") - item->m_dwSize = (int64_t)strtoll(value.c_str(), NULL, 10); + item->m_dwSize = static_cast<int64_t>(strtoll(value.c_str(), nullptr, 10)); else if (key == "title") item->m_strTitle = value; else if (key == "picturepath") @@ -624,21 +641,22 @@ namespace XBMCAddon } else if (StringUtils::EqualsNoCase(type, "game")) { - for (InfoLabelDict::const_iterator it = infoLabels.begin(); it != infoLabels.end(); it++) + auto& gametag = *item->GetGameInfoTag(); + for (const auto& it: infoLabels) { - String key = it->first; + String key = it.first; StringUtils::ToLower(key); - const InfoLabelValue& alt = it->second; + const InfoLabelValue& alt = it.second; const String value(alt.which() == first ? alt.former() : emptyString); if (key == "title") { item->m_strTitle = value; - item->GetGameInfoTag()->SetTitle(value); + gametag.SetTitle(value); } else if (key == "platform") - item->GetGameInfoTag()->SetPlatform(value); + gametag.SetPlatform(value); else if (key == "genres") { if (alt.which() != second) @@ -646,34 +664,31 @@ namespace XBMCAddon std::vector<std::string> genres; - const std::vector<InfoLabelStringOrTuple>& listValue = alt.later(); - for (std::vector<InfoLabelStringOrTuple>::const_iterator viter = listValue.begin(); viter != listValue.end(); ++viter) + for (const auto& genreEntry: alt.later()) { - - const InfoLabelStringOrTuple& genreEntry = *viter; const String& genre = genreEntry.which() == first ? genreEntry.former() : genreEntry.later().first(); genres.emplace_back(std::move(genre)); } - item->GetGameInfoTag()->SetGenres(genres); + gametag.SetGenres(genres); } else if (key == "publisher") - item->GetGameInfoTag()->SetPublisher(value); + gametag.SetPublisher(value); else if (key == "developer") - item->GetGameInfoTag()->SetDeveloper(value); + gametag.SetDeveloper(value); else if (key == "overview") - item->GetGameInfoTag()->SetOverview(value); + gametag.SetOverview(value); else if (key == "year") - item->GetGameInfoTag()->SetYear(strtol(value.c_str(), NULL, 10)); + gametag.SetYear(strtol(value.c_str(), nullptr, 10)); else if (key == "gameclient") - item->GetGameInfoTag()->SetGameClient(value); + gametag.SetGameClient(value); } } } // end ListItem::setInfo void ListItem::setCast(const std::vector<Properties>& actors) { - LOCKGUI; + LOCKGUIIF(m_offscreen); item->GetVideoInfoTag()->m_cast.clear(); for (const auto& dictionary: actors) { @@ -689,12 +704,43 @@ namespace XBMCAddon else if (key == "thumbnail") info.thumbUrl = value; else if (key == "order") - info.order = strtol(value.c_str(), NULL, 10); + info.order = strtol(value.c_str(), nullptr, 10); } item->GetVideoInfoTag()->m_cast.push_back(std::move(info)); } } + void ListItem::setAvailableFanart(const std::vector<Properties>& images) + { + LOCKGUIIF(m_offscreen); + item->GetVideoInfoTag()->m_fanart.Clear(); + for (const auto& dictionary : images) + { + std::string image; + std::string preview; + std::string colors; + for (const auto& it: dictionary) + { + const String& key = it.first; + const String& value = it.second; + if (key == "image") + image = value; + else if (key == "preview") + preview = value; + else if (key == "colors") + colors = value; + } + item->GetVideoInfoTag()->m_fanart.AddFanart(image, preview, colors); + } + item->GetVideoInfoTag()->m_fanart.Pack(); + } + + void ListItem::addAvailableThumb(std::string url, std::string aspect, std::string referrer, std::string cache, bool post, bool isgz, int season) + { + LOCKGUIIF(m_offscreen); + item->GetVideoInfoTag()->m_strPictureURL.AddElement(url, aspect, referrer, cache, post, isgz, season); + } + void ListItem::addStreamInfo(const char* cType, const Properties& dictionary) { LOCKGUIIF(m_offscreen); @@ -702,21 +748,21 @@ namespace XBMCAddon if (strcmpi(cType, "video") == 0) { CStreamDetailVideo* video = new CStreamDetailVideo; - for (Properties::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) + for (const auto& it: dictionary) { - const String& key = it->first; - const String value(it->second.c_str()); + const String& key = it.first; + const String value(it.second.c_str()); if (key == "codec") video->m_strCodec = value; else if (key == "aspect") - video->m_fAspect = (float)atof(value.c_str()); + video->m_fAspect = static_cast<float>(atof(value.c_str())); else if (key == "width") - video->m_iWidth = strtol(value.c_str(), NULL, 10); + video->m_iWidth = strtol(value.c_str(), nullptr, 10); else if (key == "height") - video->m_iHeight = strtol(value.c_str(), NULL, 10); + video->m_iHeight = strtol(value.c_str(), nullptr, 10); else if (key == "duration") - video->m_iDuration = strtol(value.c_str(), NULL, 10); + video->m_iDuration = strtol(value.c_str(), nullptr, 10); else if (key == "stereomode") video->m_strStereoMode = value; else if (key == "language") @@ -727,27 +773,27 @@ namespace XBMCAddon else if (strcmpi(cType, "audio") == 0) { CStreamDetailAudio* audio = new CStreamDetailAudio; - for (Properties::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) + for (const auto& it: dictionary) { - const String& key = it->first; - const String& value = it->second; + const String& key = it.first; + const String& value = it.second; if (key == "codec") audio->m_strCodec = value; else if (key == "language") audio->m_strLanguage = value; else if (key == "channels") - audio->m_iChannels = strtol(value.c_str(), NULL, 10); + audio->m_iChannels = strtol(value.c_str(), nullptr, 10); } item->GetVideoInfoTag()->m_streamDetails.AddStream(audio); } else if (strcmpi(cType, "subtitle") == 0) { CStreamDetailSubtitle* subtitle = new CStreamDetailSubtitle; - for (Properties::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) + for (const auto& it: dictionary) { - const String& key = it->first; - const String& value = it->second; + const String& key = it.first; + const String& value = it.second; if (key == "language") subtitle->m_strLanguage = value; @@ -775,10 +821,10 @@ namespace XBMCAddon { LOCKGUIIF(m_offscreen); unsigned int i = 1; - for (std::vector<String>::const_iterator it = paths.begin(); it != paths.end(); ++it, i++) + for (const auto& it: paths) { String property = StringUtils::Format("subtitle:%u", i); - item->SetProperty(property, *it); + item->SetProperty(property, it); } } @@ -797,5 +843,24 @@ namespace XBMCAddon return new xbmc::InfoTagMusic(*item->GetMusicInfoTag()); return new xbmc::InfoTagMusic(); } + + std::vector<std::string> ListItem::getStringArray(const InfoLabelValue& alt, const std::string& tag, std::string value) + { + if (alt.which() == first) + { + if (value.empty()) + value = alt.former(); + return StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); + } + + std::vector<std::string> els; + for (const auto& el : alt.later()) + { + if (el.which() == second) + throw WrongTypeException("When using \"%s\" you need to supply a string or list of strings for the value in the dictionary", tag.c_str()); + els.emplace_back(el.former()); + } + return els; + } } } diff --git a/xbmc/interfaces/legacy/ListItem.h b/xbmc/interfaces/legacy/ListItem.h index 85e4a70134..197373bb5d 100644 --- a/xbmc/interfaces/legacy/ListItem.h +++ b/xbmc/interfaces/legacy/ListItem.h @@ -272,11 +272,13 @@ namespace XBMCAddon #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_xbmcgui_listitem - /// @brief \python_func{ setUniqueIDs(values) } + /// @brief \python_func{ setUniqueIDs(values, defaultrating) } ///----------------------------------------------------------------------- /// Sets the listitem's uniqueID /// /// @param values dictionary - pairs of `{ label: value }`. + /// @param defaultrating [opt] string - the name of default rating. + /// /// - Some example values (any string possible): /// | Label | Type | /// |:-------------:|:--------------------------------------------------| @@ -292,14 +294,14 @@ namespace XBMCAddon /// **Example:** /// ~~~~~~~~~~~~~{.py} /// ... - /// # setUniqueIDs(values) - /// listitem.setUniqueIDs({ 'imdb': 'tt8938399', 'tmdb' : '9837493' }) + /// # setUniqueIDs(values, defaultrating) + /// listitem.setUniqueIDs({ 'imdb': 'tt8938399', 'tmdb' : '9837493' }, "imdb") /// ... /// ~~~~~~~~~~~~~ /// setUniqueIDs(...); #else - void setUniqueIDs(const Properties& dictionary); + void setUniqueIDs(const Properties& dictionary, const String& defaultrating = ""); #endif #ifdef DOXYGEN_SHOULD_USE_THIS @@ -341,6 +343,33 @@ namespace XBMCAddon #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_xbmcgui_listitem + /// @brief \python_func{ addSeason(number, name = "") } + ///----------------------------------------------------------------------- + /// Add a season with name to a listitem. It needs at least the season number + /// + /// @param number int - the number of the season. + /// @param name string - the name of the season. Default "". + /// + ///----------------------------------------------------------------------- + /// + /// @python_v18 New function added. + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.py} + /// ... + /// # addSeason(number, name)) + /// listitem.addSeason(1, "Murder House") + /// ... + /// ~~~~~~~~~~~~~ + /// + addSeason(...); +#else + void addSeason(int number, std::string name = ""); +#endif + +#ifdef DOXYGEN_SHOULD_USE_THIS + /// + /// \ingroup python_xbmcgui_listitem /// @brief \python_func{ getArt(key) } ///----------------------------------------------------------------------- /// Returns a listitem art path as a string, similar to an infolabel.\n @@ -557,11 +586,15 @@ namespace XBMCAddon /// __Video Values__: /// | Info label | Description | /// |--------------:|:---------------------------------------------------| - /// | genre | string (Comedy) - /// | country | string (Germany) + /// | genre | string (Comedy) or list of strings (["Comedy", "Animation", "Drama"]) + /// | country | string (Germany) or list of strings (["Germany", "Italy", "France"]) /// | year | integer (2009) /// | episode | integer (4) /// | season | integer (1) + /// | sortepisode | integer (4) + /// | sortseason | integer (1) + /// | episodeguide | string (Episode guide) + /// | showlink | string (Battlestar Galactica) or list of strings (["Battlestar Galactica", "Caprica"]) /// | top250 | integer (192) /// | setid | integer (14) /// | tracknumber | integer (3) @@ -572,7 +605,7 @@ namespace XBMCAddon /// | overlay | integer (2) - range is `0..7`. See \ref kodi_guilib_listitem_iconoverlay "Overlay icon types" for values /// | cast | list (["Michal C. Hall","Jennifer Carpenter"]) - if provided a list of tuples cast will be interpreted as castandrole /// | castandrole | list of tuples ([("Michael C. Hall","Dexter"),("Jennifer Carpenter","Debra")]) - /// | director | string (Dagur Kari) + /// | director | string (Dagur Kari) or list of strings (["Dagur Kari", "Quentin Tarantino", "Chrstopher Nolan"]) /// | mpaa | string (PG-13) /// | plot | string (Long Description) /// | plotoutline | string (Short Description) @@ -580,17 +613,19 @@ namespace XBMCAddon /// | originaltitle | string (Big Fan) /// | sorttitle | string (Big Fan) /// | duration | integer (245) - duration in seconds - /// | studio | string (Warner Bros.) + /// | studio | string (Warner Bros.) or list of strings (["Warner Bros.", "Disney", "Paramount"]) /// | tagline | string (An awesome movie) - short description of movie - /// | writer | string (Robert D. Siegel) + /// | writer | string (Robert D. Siegel) or list of strings (["Robert D. Siegel", "Jonathan Nolan", "J.K. Rowling"]) /// | tvshowtitle | string (Heroes) /// | premiered | string (2005-03-04) /// | status | string (Continuing) - status of a TVshow /// | set | string (Batman Collection) - name of the collection + /// | setoverview | string (All Batman movies) - overview of the collection + /// | tag | string (cult) or list of strings (["cult", "documentary", "best movies"]) - movie tag /// | imdbnumber | string (tt0110293) - IMDb code /// | code | string (101) - Production code /// | aired | string (2008-12-07) - /// | credits | string (Andy Kaufman) - writing credits + /// | credits | string (Andy Kaufman) or list of strings (["Dagur Kari", "Quentin Tarantino", "Chrstopher Nolan"]) - writing credits /// | lastplayed | string (%Y-%m-%d %h:%m:%s = 2009-04-05 23:16:04) /// | album | string (The Joshua Tree) /// | artist | list (['U2']) @@ -654,6 +689,8 @@ namespace XBMCAddon /// Added labels **setid**, **set**, **imdbnumber**, **code**, **dbid**, **path** and **userrating**. /// Expanded the possible infoLabels for the option **mediatype**. /// @python_v18 Added new **game** type and associated infolabels. + /// Added labels **setoverview**, **tag**, **sortepisode**, **sortseason**, **episodeguide**, **showlink**. + /// Extended labels **genre**, **country**, **director**, **studio**, **writer**, **tag**, **credits** to also use a list of strings. /// /// **Example:** /// ~~~~~~~~~~~~~{.py} @@ -704,6 +741,69 @@ namespace XBMCAddon #ifdef DOXYGEN_SHOULD_USE_THIS /// /// \ingroup python_xbmcgui_listitem + /// @brief \python_func{ setAvailableFanart(images) } + ///----------------------------------------------------------------------- + /// @brief Set available images (needed for scrapers) + /// + /// @param images list of dictionaries (see below for relevant keys) + /// + /// - Keys: + /// | Label | Description | + /// |--------------:|:------------------------------------------------| + /// | image | string (http://www.someurl.com/someimage.png) + /// | preview | [opt] string (http://www.someurl.com/somepreviewimage.png) + /// | colors | [opt] string (either comma separated Kodi hex values ("FFFFFFFF,DDDDDDDD") or TVDB RGB Int Triplets ("|68,69,59|69,70,58|78,78,68|")) + /// + /// + ///----------------------------------------------------------------------- + /// @python_v18 New function added. + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.py} + /// ... + /// fanart = [{"image": path_to_image_1, "preview": path_to_preview_1}, {"image": path_to_image_2, "preview": path_to_preview_2}] + /// listitem.setAvailableFanart(fanart) + /// ... + /// ~~~~~~~~~~~~~ + /// + setAvailableFanart(...); +#else + void setAvailableFanart(const std::vector<Properties>& images); +#endif + +#ifdef DOXYGEN_SHOULD_USE_THIS + /// + /// \ingroup python_xbmcgui_listitem + /// @brief \python_func{ addAvailableThumb(images) } + ///----------------------------------------------------------------------- + /// @brief Add a thumb to available thumbs (needed for scrapers) + /// + /// @param url string (image path url) + /// @param aspect [opt] string (image type) + /// @param referrer [opt] string (referr url) + /// @param cache [opt] string (filename in cache) + /// @param post [opt] bool (use post to retrieve the image, default false) + /// @param isgz [opt] bool (use gzip to retrieve the image, default false) + /// @param season [opt] integer (number of season in case of season thumb) + /// + ///----------------------------------------------------------------------- + /// @python_v18 New function added. + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.py} + /// ... + /// listitem.addAvailableThumb(path_to_image_1, "1.77") + /// ... + /// ~~~~~~~~~~~~~ + /// + addAvailableThumb(...); +#else + void addAvailableThumb(std::string url, std::string aspect = "", std::string referrer = "", std::string cache = "", bool post = false, bool isgz = false, int season = -1); +#endif + +#ifdef DOXYGEN_SHOULD_USE_THIS + /// + /// \ingroup python_xbmcgui_listitem /// @brief \python_func{ addStreamInfo(type, values) } ///----------------------------------------------------------------------- /// @brief Add a stream with details. @@ -1029,6 +1129,9 @@ namespace XBMCAddon /// Function completely removed and replaced with context menu add-ons. /// #endif + +private: + std::vector<std::string> getStringArray(const InfoLabelValue& alt, const std::string& tag, std::string value = ""); }; #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/xbmc/interfaces/legacy/ModuleXbmc.cpp b/xbmc/interfaces/legacy/ModuleXbmc.cpp index a9c6d06b6f..1032adb81f 100644 --- a/xbmc/interfaces/legacy/ModuleXbmc.cpp +++ b/xbmc/interfaces/legacy/ModuleXbmc.cpp @@ -461,7 +461,7 @@ namespace XBMCAddon else if (strcmpi(mediaType, "music") == 0) result = g_advancedSettings.GetMusicExtensions(); else if (strcmpi(mediaType, "picture") == 0) - result = g_advancedSettings.m_pictureExtensions; + result = g_advancedSettings.GetPictureExtensions(); //! @todo implement // else diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp index fa9f4f0fa5..533cee0537 100644 --- a/xbmc/linux/OMXCore.cpp +++ b/xbmc/linux/OMXCore.cpp @@ -459,10 +459,10 @@ OMX_BUFFERHEADERTYPE *COMXCoreComponent::GetInputBuffer(long timeout /*=200*/) { if (m_resource_error) break; - if(!m_omx_input_avaliable.empty()) + if(!m_omx_input_available.empty()) { - omx_input_buffer = m_omx_input_avaliable.front(); - m_omx_input_avaliable.pop(); + omx_input_buffer = m_omx_input_available.front(); + m_omx_input_available.pop(); break; } @@ -519,7 +519,7 @@ OMX_ERRORTYPE COMXCoreComponent::WaitForInputDone(long timeout /*=200*/) struct timespec endtime; clock_gettime(CLOCK_REALTIME, &endtime); add_timespecs(endtime, timeout); - while (m_input_buffer_count != m_omx_input_avaliable.size()) + while (m_input_buffer_count != m_omx_input_available.size()) { if (m_resource_error) break; @@ -612,7 +612,7 @@ OMX_ERRORTYPE COMXCoreComponent::AllocInputBuffers() buffer->nOffset = 0; buffer->pAppPrivate = (void*)i; m_omx_input_buffers.push_back(buffer); - m_omx_input_avaliable.push(buffer); + m_omx_input_available.push(buffer); } omx_err = WaitForCommand(OMX_CommandPortEnable, m_input_port); @@ -729,12 +729,12 @@ OMX_ERRORTYPE COMXCoreComponent::FreeInputBuffers() WaitForInputDone(1000); pthread_mutex_lock(&m_omx_input_mutex); - assert(m_omx_input_buffers.size() == m_omx_input_avaliable.size()); + assert(m_omx_input_buffers.size() == m_omx_input_available.size()); m_omx_input_buffers.clear(); - while (!m_omx_input_avaliable.empty()) - m_omx_input_avaliable.pop(); + while (!m_omx_input_available.empty()) + m_omx_input_available.pop(); m_input_alignment = 0; m_input_buffer_size = 0; @@ -1476,10 +1476,10 @@ OMX_ERRORTYPE COMXCoreComponent::DecoderEmptyBufferDone(OMX_HANDLETYPE hComponen return OMX_ErrorNone; #if defined(OMX_DEBUG_EVENTHANDLER) - CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderEmptyBufferDone component(%s) %p %d/%d\n", m_componentName.c_str(), pBuffer, m_omx_input_avaliable.size(), m_input_buffer_count); + CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderEmptyBufferDone component(%s) %p %d/%d\n", m_componentName.c_str(), pBuffer, m_omx_input_available.size(), m_input_buffer_count); #endif pthread_mutex_lock(&m_omx_input_mutex); - m_omx_input_avaliable.push(pBuffer); + m_omx_input_available.push(pBuffer); // this allows (all) blocked tasks to be awoken pthread_cond_broadcast(&m_input_buffer_cond); diff --git a/xbmc/linux/OMXCore.h b/xbmc/linux/OMXCore.h index d826845d31..6fb8258004 100644 --- a/xbmc/linux/OMXCore.h +++ b/xbmc/linux/OMXCore.h @@ -137,7 +137,7 @@ public: unsigned int GetInputBufferSize() const { return m_input_buffer_count * m_input_buffer_size; } unsigned int GetOutputBufferSize() const { return m_output_buffer_count * m_output_buffer_size; } - unsigned int GetInputBufferSpace() const { return m_omx_input_avaliable.size() * m_input_buffer_size; } + unsigned int GetInputBufferSpace() const { return m_omx_input_available.size() * m_input_buffer_size; } unsigned int GetOutputBufferSpace() const { return m_omx_output_available.size() * m_output_buffer_size; } void FlushAll(); @@ -175,7 +175,7 @@ private: // OMXCore input buffers (demuxer packets) pthread_mutex_t m_omx_input_mutex; - std::queue<OMX_BUFFERHEADERTYPE*> m_omx_input_avaliable; + std::queue<OMX_BUFFERHEADERTYPE*> m_omx_input_available; std::vector<OMX_BUFFERHEADERTYPE*> m_omx_input_buffers; unsigned int m_input_alignment; unsigned int m_input_buffer_size; diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp index 356d64b0b1..053c10deaf 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp @@ -103,7 +103,7 @@ bool CRBP::Initialize() return true; } -void CRBP::LogFirmwareVerison() +void CRBP::LogFirmwareVersion() { char response[1024]; m_DllBcmHost->vc_gencmd(response, sizeof response, "version"); diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h index eff631d24c..10f5776fd4 100644 --- a/xbmc/linux/RBP.h +++ b/xbmc/linux/RBP.h @@ -61,12 +61,12 @@ public: ~CRBP(); bool Initialize(); - void LogFirmwareVerison(); + void LogFirmwareVersion(); void Deinitialize(); int GetArmMem() { return m_arm_mem; } int GetGpuMem() { return m_gpu_mem; } bool GetCodecMpg2() { return m_codec_mpg2_enabled; } - int RasberryPiVersion() { return g_cpuInfo.getCPUCount() == 1 ? 1 : 2; }; + int RaspberryPiVersion() { return g_cpuInfo.getCPUCount() == 1 ? 1 : 2; }; bool GetCodecWvc1() { return m_codec_wvc1_enabled; } void GetDisplaySize(int &width, int &height); DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device); diff --git a/xbmc/messaging/ApplicationMessenger.h b/xbmc/messaging/ApplicationMessenger.h index b54b1c88f9..f3ad2aabde 100644 --- a/xbmc/messaging/ApplicationMessenger.h +++ b/xbmc/messaging/ApplicationMessenger.h @@ -164,6 +164,79 @@ struct ThreadMessageCallback class IMessageTarget; +/*! + * \class CApplicationMessenger ApplicationMessenger.h "messaging/ApplicationMessenger.h" + * \brief This implements a simple message dispatcher/router for Kodi + * + * For most users that wants to send message go to the documentation for these + * \sa CApplicationMessenger::SendMsg + * \sa CApplicationMessenger::PostMsg + * + * For anyone wanting to implement a message receiver, go to the documentation for + * \sa IMessageTarget + * + * IMPLEMENTATION SPECIFIC NOTES - DOCUMENTED HERE FOR THE SOLE PURPOSE OF IMPLEMENTERS OF THIS CLASS + * On a high level this implements two methods for dispatching messages, SendMsg and PostMsg. + * These are roughly modeled on the implementation of SendMessage and PostMessage in Windows. + * + * PostMsg is the preferred method to use as it's non-blocking and does not wait for any response before + * returning to the caller. Messages will be stored in a queue and processed in order. + * + * SendMsg is a blocking version and has a bit more subtleties to it regarding how inter-process + * dispatching is handled. + * + * Calling SendMsg with a message type that doesn't require marshalling will bypass the message queue + * and call the receiver directly + * + * Calling SendMsg with a message type that require marshalling to a specific thread when not on that thread + * will add a message to the queue with a an event, it will then block the calling thread waiting on this event + * to be signaled. + * The message will be processed by the correct thread in it's message pump and the event will be signaled, unblocking + * the calling thread + * + * Calling SendMsg with a message type that require marshalling to a specific thread when already on that thread + * will behave as scenario one, it will bypass the queue and call the receiver directly. + * + * Currently there is a hack implemented in the message dispatcher that releases the graphicslock before dispatching + * a message. This was here before the redesign and removing it will require careful inspection of every call site. + * TODO: add logging if the graphicslock is held during message dispatch + * + * Current design has three different message types + * 1. Normal messages that can be processed on any thread + * 2. GUI messages that require marshalling to the UI thread + * 3. A thread message that will spin up a background thread and wait a specified amount of time before posting the message + * This should probably be removed, it's left for compatibility + * + * Heavy emphasis on current design, the idea is that we can easily add more message types to route messages + * to more threads or other scenarios. + * + * \sa CApplicationMessenger::ProcessMessages() + * handles regular messages that require no marshalling, this can be called from any thread to drive the message + * pump + * + * \sa CApplicationMessenger::ProcessWindowMessages() + * handles GUI messages and currently should only be called on the UI thread + * + * If/When this is expanded upon ProcessMessage() and ProcessWindowMessages() should be combined into a single method + * taking an enum or similar to indicate which message it's interested in. + * + * The above methods are backed by two messages queues, one for each type of message. If more types are added + * this might need to be redesigned to simplify the lookup of the correct message queue but currently they're implemented + * as two member variables + * + * The design is meant to be very encapsulated and easy to extend without altering the public interface. + * e.g. If GUI messages should be handled on another thread, call \sa CApplicationMessenger::ProcessWindowMessage() on that + * thread and nothing else has to change. The callers have no knowledge of how this is implemented. + * + * The design is also meant to be very dependency free to work as a bridge between lower layer functionality without + * having to have knowledge of the GUI or having a dependency on the GUI in any way. This is not the reality currently as + * this depends on \sa CApplication and the graphicslock but should be fixed soon enough. + * + * To keep things simple the current implementation routes messages based on a mask that the receiver provides. + * Any message fitting that mask will be routed to that specific receiver. + * This will likely need to change if many different receivers are added but it should be possible to do it without + * any of the callers being changed. + */ class CApplicationMessenger { public: @@ -175,27 +248,156 @@ public: void Cleanup(); // if a message has to be send to the gui, use MSG_TYPE_WINDOW instead + /*! + * \brief Send a blocking message and wait for a response + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * Under no circumestances shall the caller hold a lock when calling SendMsg as there's + * no guarantee what the receiver will do to answer the request. + * + * \param [in] messageId defined further up in this file + * \return meaning of the return varies based on the message + */ int SendMsg(uint32_t messageId); + + /*! + * \brief Send a blocking message and wait for a response + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * Under no circumestances shall the caller hold a lock when calling SendMsg as there's + * no guarantee what the receiver will do to answer the request. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent, defaults to -1 + * \param [in] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + * \return meaning of the return varies based on the message + */ int SendMsg(uint32_t messageId, int param1, int param2 = -1, void* payload = nullptr); + + /*! + * \brief Send a blocking message and wait for a response + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * Under no circumestances shall the caller hold a lock when calling SendMsg as there's + * no guarantee what the receiver will do to answer the request. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent + * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + * \param [in] strParam value depends on the message being sent, remains for backward compat + * \return meaning of the return varies based on the message + */ int SendMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam); + + /*! + * \brief Send a blocking message and wait for a response + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * Under no circumestances shall the caller hold a lock when calling SendMsg as there's + * no guarantee what the receiver will do to answer the request. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent + * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + * \param [in] strParam value depends on the message being sent, remains for backward compat + * \param [in] params value depends on the message being sent, kept for backward compatiblity + * \return meaning of the return varies based on the message + */ int SendMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam, std::vector<std::string> params); + /*! + * \brief Send a non-blocking message and return immediately + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * \param [in] messageId defined further up in this file + */ void PostMsg(uint32_t messageId); + + /*! + * \brief Send a non-blocking message and return immediately + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent + * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + */ void PostMsg(uint32_t messageId, int param1, int param2 = -1, void* payload = nullptr); + + /*! + * \brief Send a non-blocking message and return immediately + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent + * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + * \param [in] strParam value depends on the message being sent, remains for backward compat + */ void PostMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam); + /*! + * \brief Send a non-blocking message and return immediately + * + * If and what the response is depends entirely on the message being sent and + * should be documented on the message. + * + * \param [in] messageId defined further up in this file + * \param [in] param1 value depends on the message being sent + * \param [in] param2 value depends on the message being sent + * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver + * what to send depends on the message + * \param [in] strParam value depends on the message being sent, remains for backward compat + * \param [in] params value depends on the message being sent, kept for backward compatiblity + */ void PostMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam, std::vector<std::string> params); - void ProcessMessages(); // only call from main thread. + /*! + * \brief Called from any thread to dispatch messages + */ + void ProcessMessages(); + + /*! + * \brief Called from the UI thread to dispatch UI messages + * This is only of value to implementers of the message pump, do not rely on a specific thread + * being used other than that it's appropriate for UI messages + */ void ProcessWindowMessages(); /*! \brief Send a GUIMessage, optionally waiting before it's processed to return. - Should be used to send messages to the GUI from other threads. - \param msg the GUIMessage to send. - \param windowID optional window to send the message to (defaults to no specified window). - \param waitResult whether to wait for the result (defaults to false). + * This is kept for backward compat and is just a convenience wrapper for for SendMsg and PostMsg + * specifically for UI messages + * \param msg the GUIMessage to send. + * \param windowID optional window to send the message to (defaults to no specified window). + * \param waitResult whether to wait for the result (defaults to false). */ void SendGUIMessage(const CGUIMessage &msg, int windowID = WINDOW_INVALID, bool waitResult=false); + /*! + * \brief This should be called any class implementing \sa IMessageTarget before it + * can receive any messages + */ void RegisterReceiver(IMessageTarget* target); private: @@ -208,9 +410,9 @@ private: int SendMsg(ThreadMessage&& msg, bool wait); void ProcessMessage(ThreadMessage *pMsg); - std::queue<ThreadMessage*> m_vecMessages; - std::queue<ThreadMessage*> m_vecWindowMessages; - std::map<int, IMessageTarget*> m_mapTargets; + std::queue<ThreadMessage*> m_vecMessages; /*!< queue for regular messages */ + std::queue<ThreadMessage*> m_vecWindowMessages; /*!< queue for UI messages */ + std::map<int, IMessageTarget*> m_mapTargets; /*!< a map of registered receivers indexed on the message mask*/ CCriticalSection m_critSection; }; } diff --git a/xbmc/messaging/IMessageTarget.h b/xbmc/messaging/IMessageTarget.h index b59f150b54..a67d9adf9f 100644 --- a/xbmc/messaging/IMessageTarget.h +++ b/xbmc/messaging/IMessageTarget.h @@ -25,11 +25,43 @@ namespace MESSAGING { class ThreadMessage; +/*! + * \class IMessageTarget IMessageTarget.h "messaging/IMessageTarget.h" + * \brief A class wishing to receive messages should implement this + * and call \sa CApplicationMessenger::RegisterReceiver + * to start receiving messages + */ class IMessageTarget { public: virtual ~IMessageTarget() { } + /*! + * \brief Should return the message mask that it wishes to receive + * messages for + * + * The message mask is defined in "messaging/ApplicationMessenger.h" + * pick the next one available when creating a new + */ virtual int GetMessageMask() = 0; + + /*! + * \brief This gets called whenever a message matching the registered + * message mask is processed. + * + * There are no ordering guarantees here so implementations should never + * rely on a certain ordering of messages. + * + * Cleaning up any pointers stored in the message payload is not specified + * and is decided by the implementer of the message. + * In general prefer to delete any data in this method to keep the callsites cleaner + * and simpler but if data is to be passed back it's perfectly valid to handle it any way + * that fits the situation as long as it's documented along with the message. + * + * To return a simple value the result parameter of \sa ThreadMessage can be used + * as it will be used as the return value for \sa CApplicationMessenger::SendMsg. + * It is up to the implementer to decide if this is to be used and it should be documented + * along with any new message implemented. + */ virtual void OnApplicationMessage(ThreadMessage* msg) = 0; }; } diff --git a/xbmc/messaging/ThreadMessage.h b/xbmc/messaging/ThreadMessage.h index 86fd4d4741..6471f2ffdc 100644 --- a/xbmc/messaging/ThreadMessage.h +++ b/xbmc/messaging/ThreadMessage.h @@ -125,7 +125,12 @@ public: std::string strParam; std::vector<std::string> params; - void SetResult(int res) + /*! + * \brief set the message return value, will only be returned when + * the message is sent using SendMsg + * \param [in] res the return value or a result status code that is returned to the caller + */ + void SetResult(int res) const { //On posted messages result will be zero, since they can't //retrieve the response we silently ignore this to let message diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index decafb21d4..c1af80eaa6 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -192,6 +192,10 @@ void CMusicDatabase::CreateTables() CLog::Log(LOGINFO, "create cue table"); m_pDS->exec("CREATE TABLE cue (idPath integer, strFileName text, strCuesheet text)"); + + CLog::Log(LOGINFO, "create versiontagscan table"); + m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)"); + m_pDS->exec(PrepareSQL("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(%i, 0)", GetSchemaVersion())); } void CMusicDatabase::CreateAnalytics() @@ -1535,7 +1539,7 @@ bool CMusicDatabase::GetRolesByArtist(int idArtist, CFileItem* item) try { std::string strSQL = PrepareSQL("SELECT DISTINCT song_artist.idRole, Role.strRole FROM song_artist JOIN role ON " - " song_artist.idRole = Role.idRole WHERE idArtist = %i ORDER BY song_artist.idRole ASC", idArtist); + " song_artist.idRole = role.idRole WHERE idArtist = %i ORDER BY song_artist.idRole ASC", idArtist); if (!m_pDS->query(strSQL)) return false; if (m_pDS->num_rows() == 0) @@ -1759,7 +1763,7 @@ bool CMusicDatabase::GetGenresByArtist(int idArtist, CFileItem* item) { try { - std::string strSQL = PrepareSQL("SELECT DISTINCT song_genre.idGenre, Genre.strGenre FROM " + std::string strSQL = PrepareSQL("SELECT DISTINCT song_genre.idGenre, genre.strGenre FROM " "song_artist JOIN song ON song_artist.idSong = song.idSong JOIN " "song_genre ON song.idSong = song_genre.idSong JOIN " "genre ON song_genre.idGenre = genre.idGenre " @@ -4662,8 +4666,6 @@ void CMusicDatabase::UpdateTables(int version) if (version < 53) { m_pDS->exec("ALTER TABLE song ADD dateAdded text"); - CMediaSettings::GetInstance().SetMusicNeedsUpdate(53); - CServiceBroker::GetSettings().Save(); } if (version < 54) { @@ -4958,17 +4960,78 @@ void CMusicDatabase::UpdateTables(int version) //Remove temp indices, full analytics for database created later m_pDS->exec("DROP INDEX idxSongArtist1 ON song_artist"); m_pDS->exec("DROP INDEX idxAlbumArtist1 ON album_artist"); - - // Prompt for rescan of library to read tags that were not processed by previous versions - // and accomodate changes to the way some tags are processed - CMediaSettings::GetInstance().SetMusicNeedsUpdate(60); - CServiceBroker::GetSettings().Save(); } + if (version < 61) + { + // Create versiontagscan table + m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)"); + m_pDS->exec("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(0, 0)"); + } + + // Set the version of tag scanning required. + // Not every schema change requires the tags to be rescanned, set to the highest schema version + // that needs this. Forced rescanning (of music files that have not changed since they were + // previously scanned) also accommodates any changes to the way tags are processed + // e.g. read tags that were not processed by previous versions. + // The original db version when the tags were scanned, and the minimal db version needed are + // later used to determine if a forced rescan should be prompted + + // The last schema change needing forced rescanning was 60. + // Mostly because of the new tags processed by v17 rather than a schema change. + SetMusicNeedsTagScan(60); + + // After all updates, store the original db version. + // This indicates the version of tag processing that was used to populate db + SetMusicTagScanVersion(version); } int CMusicDatabase::GetSchemaVersion() const { - return 60; + return 61; +} + +int CMusicDatabase::GetMusicNeedsTagScan() +{ + try + { + if (NULL == m_pDB.get()) return -1; + if (NULL == m_pDS.get()) return -1; + + std::string sql = "SELECT * FROM versiontagscan"; + if (!m_pDS->query(sql)) return -1; + + if (m_pDS->num_rows() != 1) + { + m_pDS->close(); + return -1; + } + + int idVersion = m_pDS->fv("idVersion").get_asInt(); + int iNeedsScan = m_pDS->fv("iNeedsScan").get_asInt(); + m_pDS->close(); + if (idVersion < iNeedsScan) + return idVersion; + else + return 0; + } + catch (...) + { + CLog::Log(LOGERROR, "%s failed", __FUNCTION__); + } + return -1; +} + +void CMusicDatabase::SetMusicNeedsTagScan(int version) +{ + m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET iNeedsScan=%i", version)); +} + +void CMusicDatabase::SetMusicTagScanVersion(int version /* = 0 */) +{ + if (version == 0) + m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", GetSchemaVersion())); + else + m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", version)); } unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, std::vector<std::pair<int,int> > &songIDs) diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index f51a981a2d..3bc2caa15b 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -497,6 +497,26 @@ public: */ std::string GetArtistArtForItem(int mediaId, const std::string &mediaType, const std::string &artType); + ///////////////////////////////////////////////// + // Tag Scan Version + ///////////////////////////////////////////////// + /*! \brief Check if music files need all tags rescanning regardless of file being unchanged + because the tag processing has changed (which may happen without db version changes) since they + where last scanned. + \return -1 if an error occured, 0 if no scan is needed, or the version number of tags if not the same as current. + */ + virtual int GetMusicNeedsTagScan(); + + /*! \brief Set minimum version number of db needed when tag data scanned from music files + \param version the version number of db + */ + void SetMusicNeedsTagScan(int version); + + /*! \brief Set the version number of tag data + \param version the version number of db when tags last scanned, 0 (default) means current db version + */ + void SetMusicTagScanVersion(int version = 0); + protected: std::map<std::string, int> m_artistCache; std::map<std::string, int> m_genreCache; diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index 6bf6628b21..41e248f154 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -416,7 +416,7 @@ bool CMusicInfoScanner::IsScanning() void CMusicInfoScanner::Stop(bool wait /* = false*/) { if (m_bCanInterrupt) - m_musicDatabase.Interupt(); + m_musicDatabase.Interrupt(); StopThread(wait); } diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp index f2147160d8..6cc1c68039 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.cpp +++ b/xbmc/music/windows/GUIWindowMusicBase.cpp @@ -669,7 +669,7 @@ void CGUIWindowMusicBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItem return; } } - if (pItem->m_bIsFolder || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) + if (pItem->m_bIsFolder) { // Check if we add a locked share if ( pItem->m_bIsShareOrDrive ) @@ -996,7 +996,7 @@ void CGUIWindowMusicBase::PlayItem(int iItem) #endif // if its a folder, build a playlist - if ((pItem->m_bIsFolder && !pItem->IsPlugin()) || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) + if (pItem->m_bIsFolder && !pItem->IsPlugin()) { // make a copy so that we can alter the queue state CFileItemPtr item(new CFileItem(*m_vecItems->Get(iItem))); @@ -1308,7 +1308,7 @@ void CGUIWindowMusicBase::OnInitWindow() CGUIMediaWindow::OnInitWindow(); // Prompt for rescan of library to read music file tags that were not processed by previous versions // and accomodate any changes to the way some tags are processed - if (CMediaSettings::GetInstance().GetMusicNeedsUpdate() != 0) + if (m_musicdatabase.GetMusicNeedsTagScan() != 0) { if (g_infoManager.GetLibraryBool(LIBRARY_HAS_MUSIC) && !g_application.IsMusicScanning()) { @@ -1324,15 +1324,13 @@ void CGUIWindowMusicBase::OnInitWindow() if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE)) flags |= CMusicInfoScanner::SCAN_BACKGROUND; g_application.StartMusicScan("", true, flags); - CMediaSettings::GetInstance().SetMusicNeedsUpdate(0); // once is enough (user may interrupt, but that's up to them) - CServiceBroker::GetSettings().Save(); + m_musicdatabase.SetMusicTagScanVersion(); // once is enough (user may interrupt, but that's up to them) } } else { // no need to force a rescan if there's no music in the library or if a library scan is already active - CMediaSettings::GetInstance().SetMusicNeedsUpdate(0); - CServiceBroker::GetSettings().Save(); + m_musicdatabase.SetMusicTagScanVersion(); } } } diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp index 466468539f..2f9e0f796b 100644 --- a/xbmc/network/AirTunesServer.cpp +++ b/xbmc/network/AirTunesServer.cpp @@ -365,7 +365,7 @@ void* CAirTunesServer::AudioOutputFunctions::audio_init(void *cls, int bits, int XFILE::CPipeFile *pipe=(XFILE::CPipeFile *)cls; const CURL pathToUrl(XFILE::PipesManager::GetInstance().GetUniquePipeName()); pipe->OpenForWrite(pathToUrl); - pipe->SetOpenThreashold(300); + pipe->SetOpenThreshold(300); Demux_BXA_FmtHeader header; strncpy(header.fourcc, "BXA ", 4); diff --git a/xbmc/network/WakeOnAccess.cpp b/xbmc/network/WakeOnAccess.cpp index 5c1b2f56e9..788ec5ffdd 100644 --- a/xbmc/network/WakeOnAccess.cpp +++ b/xbmc/network/WakeOnAccess.cpp @@ -92,11 +92,11 @@ public: virtual bool DoWork(); - const std::string& GetMAC() const { return m_macAddres; } + const std::string& GetMAC() const { return m_macAddress; } const std::string& GetHost() const { return m_host; } private: - std::string m_macAddres; + std::string m_macAddress; std::string m_host; }; @@ -113,7 +113,7 @@ bool CMACDiscoveryJob::DoWork() std::vector<CNetworkInterface*>& ifaces = g_application.getNetwork().GetInterfaceList(); for (std::vector<CNetworkInterface*>::const_iterator it = ifaces.begin(); it != ifaces.end(); ++it) { - if ((*it)->GetHostMacAddress(ipAddress, m_macAddres)) + if ((*it)->GetHostMacAddress(ipAddress, m_macAddress)) return true; } diff --git a/xbmc/network/cddb.cpp b/xbmc/network/cddb.cpp index eb45f9bd66..0cf1caa34b 100644 --- a/xbmc/network/cddb.cpp +++ b/xbmc/network/cddb.cpp @@ -49,7 +49,7 @@ Xcddb::Xcddb() #else : m_cddb_socket(close, -1) #endif - , m_cddb_ip_adress(g_advancedSettings.m_cddbAddress) + , m_cddb_ip_address(g_advancedSettings.m_cddbAddress) { m_lastError = 0; } @@ -76,10 +76,10 @@ bool Xcddb::openSocket() hints.ai_protocol = IPPROTO_TCP; sprintf(service, "%d", CDDB_PORT); - res = getaddrinfo(m_cddb_ip_adress.c_str(), service, &hints, &result); + res = getaddrinfo(m_cddb_ip_address.c_str(), service, &hints, &result); if(res) { - CLog::Log(LOGERROR, "Xcddb::openSocket - failed to lookup %s with error %s", m_cddb_ip_adress.c_str(), gai_strerror(res)); + CLog::Log(LOGERROR, "Xcddb::openSocket - failed to lookup %s with error %s", m_cddb_ip_address.c_str(), gai_strerror(res)); res = getaddrinfo("130.179.31.49", service, &hints, &result); if(res) return false; @@ -730,9 +730,9 @@ void Xcddb::addInexactListLine(int line_cnt, const char *line, int len) } //------------------------------------------------------------------------------------------------------------------- -void Xcddb::setCDDBIpAdress(const std::string& ip_adress) +void Xcddb::setCDDBIpAddress(const std::string& ip_address) { - m_cddb_ip_adress = ip_adress; + m_cddb_ip_address = ip_address; } //------------------------------------------------------------------------------------------------------------------- diff --git a/xbmc/network/cddb.h b/xbmc/network/cddb.h index 3606c5bc28..de8da75eca 100644 --- a/xbmc/network/cddb.h +++ b/xbmc/network/cddb.h @@ -67,7 +67,7 @@ class Xcddb public: Xcddb(); virtual ~Xcddb(); - void setCDDBIpAdress(const std::string& ip_adress); + void setCDDBIpAddress(const std::string& ip_address); void setCacheDir(const std::string& pCacheDir ); // int queryCDinfo(int real_track_count, toc cdtoc[]); @@ -134,7 +134,7 @@ protected: */ std::string TrimToUTF8(const std::string &untrimmed); - std::string m_cddb_ip_adress; + std::string m_cddb_ip_address; std::string cCacheDir; }; } diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp index a2e1f9c869..10d3e9fc29 100644 --- a/xbmc/network/upnp/UPnPServer.cpp +++ b/xbmc/network/upnp/UPnPServer.cpp @@ -677,7 +677,7 @@ CUPnPServer::OnBrowseDirectChildren(PLT_ActionReference& action, // this is the only way to hide unplayable items in the 'files' // view as we cannot tell what context (eg music vs video) the // request came from - std::string supported = g_advancedSettings.m_pictureExtensions + "|" + std::string supported = g_advancedSettings.GetPictureExtensions() + "|" + g_advancedSettings.m_videoExtensions + "|" + g_advancedSettings.GetMusicExtensions() + "|" + g_advancedSettings.m_discStubExtensions; diff --git a/xbmc/network/websocket/WebSocket.h b/xbmc/network/websocket/WebSocket.h index 6e2c4ae954..769156c94c 100644 --- a/xbmc/network/websocket/WebSocket.h +++ b/xbmc/network/websocket/WebSocket.h @@ -69,7 +69,7 @@ public: virtual int8_t GetExtension() const { return m_extension; } virtual WebSocketFrameOpcode GetOpcode() const { return m_opcode; } virtual bool IsControlFrame() const { return (m_valid && (m_opcode & 0x8) == 0x8); } - virtual bool IsMasekd() const { return m_masked; } + virtual bool IsMasked() const { return m_masked; } virtual uint64_t GetLength() const { return m_length; } virtual int32_t GetMask() const { return m_mask; } virtual const char* GetFrameData() const { return m_data; } diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp index a92ce3c4e3..7d1bbfeb75 100644 --- a/xbmc/peripherals/Peripherals.cpp +++ b/xbmc/peripherals/Peripherals.cpp @@ -69,7 +69,7 @@ #include "bus/virtual/PeripheralBusCEC.h" #endif - +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; using namespace XFILE; @@ -132,7 +132,7 @@ void CPeripherals::Initialise() m_eventScanner.Start(); m_bInitialised = true; - KODI::MESSAGING::CApplicationMessenger::GetInstance().RegisterReceiver(this); + MESSAGING::CApplicationMessenger::GetInstance().RegisterReceiver(this); } void CPeripherals::Clear() @@ -964,7 +964,7 @@ void CPeripherals::OnSettingAction(const CSetting *setting) TestFeature(FEATURE_RUMBLE); } -void CPeripherals::OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) +void CPeripherals::OnApplicationMessage(MESSAGING::ThreadMessage* pMsg) { switch (pMsg->dwMessage) { diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h index 6495b5ecba..63d4e91da7 100644 --- a/xbmc/peripherals/Peripherals.h +++ b/xbmc/peripherals/Peripherals.h @@ -39,10 +39,13 @@ class TiXmlElement; class CAction; class CKey; +namespace KODI +{ namespace JOYSTICK { class IButtonMapper; } +} namespace PERIPHERALS { @@ -277,13 +280,13 @@ namespace PERIPHERALS * \ref CPeripheral::RegisterJoystickButtonMapper for what is done to the * mapper after being given to the peripheral. */ - void RegisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper); + void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); /*! * \brief Unregister a button mapper interface * \param mapper The button mapper */ - void UnregisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper); + void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); virtual void OnSettingChanged(const CSetting *setting) override; virtual void OnSettingAction(const CSetting *setting) override; diff --git a/xbmc/peripherals/addons/AddonButtonMap.cpp b/xbmc/peripherals/addons/AddonButtonMap.cpp index edba1c02bc..5beb76b80a 100644 --- a/xbmc/peripherals/addons/AddonButtonMap.cpp +++ b/xbmc/peripherals/addons/AddonButtonMap.cpp @@ -28,6 +28,7 @@ #include <assert.h> #include <vector> +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; @@ -268,6 +269,28 @@ bool CAddonButtonMap::IsIgnored(const JOYSTICK::CDriverPrimitive& primitive) return std::find(m_ignoredPrimitives.begin(), m_ignoredPrimitives.end(), primitive) != m_ignoredPrimitives.end(); } +bool CAddonButtonMap::GetAxisProperties(unsigned int axisIndex, int& center, unsigned int& range) +{ + CSingleLock lock(m_mutex); + + for (auto it : m_driverMap) + { + const CDriverPrimitive& primitive = it.first; + + if (primitive.Type() != PRIMITIVE_TYPE::SEMIAXIS) + continue; + + if (primitive.Index() != axisIndex) + continue; + + center = primitive.Center(); + range = primitive.Range(); + return true; + } + + return false; +} + void CAddonButtonMap::SaveButtonMap() { if (auto addon = m_addon.lock()) @@ -326,12 +349,12 @@ CAddonButtonMap::DriverMap CAddonButtonMap::CreateLookupTable(const FeatureMap& driverMap[translatedPrimitive] = it->first; // Map opposite semiaxis - CDriverPrimitive oppositePrimitive = CDriverPrimitive(translatedPrimitive.Index(), translatedPrimitive.SemiAxisDirection() * -1); + CDriverPrimitive oppositePrimitive = CDriverPrimitive(translatedPrimitive.Index(), 0, translatedPrimitive.SemiAxisDirection() * -1, 1); driverMap[oppositePrimitive] = it->first; } break; } - + default: break; } diff --git a/xbmc/peripherals/addons/AddonButtonMap.h b/xbmc/peripherals/addons/AddonButtonMap.h index b8bec15db7..eddbaca2cf 100644 --- a/xbmc/peripherals/addons/AddonButtonMap.h +++ b/xbmc/peripherals/addons/AddonButtonMap.h @@ -31,7 +31,7 @@ namespace PERIPHERALS { class CPeripheral; - class CAddonButtonMap : public JOYSTICK::IButtonMap + class CAddonButtonMap : public KODI::JOYSTICK::IButtonMap { public: CAddonButtonMap(CPeripheral* device, const std::weak_ptr<CPeripheralAddon>& addon, const std::string& strControllerId); @@ -50,66 +50,68 @@ namespace PERIPHERALS virtual bool IsEmpty(void) const override; virtual bool GetFeature( - const JOYSTICK::CDriverPrimitive& primitive, - JOYSTICK::FeatureName& feature + const KODI::JOYSTICK::CDriverPrimitive& primitive, + KODI::JOYSTICK::FeatureName& feature ) override; - virtual JOYSTICK::FEATURE_TYPE GetFeatureType( - const JOYSTICK::FeatureName& feature + virtual KODI::JOYSTICK::FEATURE_TYPE GetFeatureType( + const KODI::JOYSTICK::FeatureName& feature ) override; virtual bool GetScalar( - const JOYSTICK::FeatureName& feature, - JOYSTICK::CDriverPrimitive& primitive + const KODI::JOYSTICK::FeatureName& feature, + KODI::JOYSTICK::CDriverPrimitive& primitive ) override; virtual void AddScalar( - const JOYSTICK::FeatureName& feature, - const JOYSTICK::CDriverPrimitive& primitive + const KODI::JOYSTICK::FeatureName& feature, + const KODI::JOYSTICK::CDriverPrimitive& primitive ) override; virtual bool GetAnalogStick( - const JOYSTICK::FeatureName& feature, - JOYSTICK::ANALOG_STICK_DIRECTION direction, - JOYSTICK::CDriverPrimitive& primitive + const KODI::JOYSTICK::FeatureName& feature, + KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction, + KODI::JOYSTICK::CDriverPrimitive& primitive ) override; virtual void AddAnalogStick( - const JOYSTICK::FeatureName& feature, - JOYSTICK::ANALOG_STICK_DIRECTION direction, - const JOYSTICK::CDriverPrimitive& primitive + const KODI::JOYSTICK::FeatureName& feature, + KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction, + const KODI::JOYSTICK::CDriverPrimitive& primitive ) override; virtual bool GetAccelerometer( - const JOYSTICK::FeatureName& feature, - JOYSTICK::CDriverPrimitive& positiveX, - JOYSTICK::CDriverPrimitive& positiveY, - JOYSTICK::CDriverPrimitive& positiveZ + const KODI::JOYSTICK::FeatureName& feature, + KODI::JOYSTICK::CDriverPrimitive& positiveX, + KODI::JOYSTICK::CDriverPrimitive& positiveY, + KODI::JOYSTICK::CDriverPrimitive& positiveZ ) override; virtual void AddAccelerometer( - const JOYSTICK::FeatureName& feature, - const JOYSTICK::CDriverPrimitive& positiveX, - const JOYSTICK::CDriverPrimitive& positiveY, - const JOYSTICK::CDriverPrimitive& positiveZ + const KODI::JOYSTICK::FeatureName& feature, + const KODI::JOYSTICK::CDriverPrimitive& positiveX, + const KODI::JOYSTICK::CDriverPrimitive& positiveY, + const KODI::JOYSTICK::CDriverPrimitive& positiveZ ) override; - virtual void SetIgnoredPrimitives(const std::vector<JOYSTICK::CDriverPrimitive>& primitives) override; + virtual void SetIgnoredPrimitives(const std::vector<KODI::JOYSTICK::CDriverPrimitive>& primitives) override; - virtual bool IsIgnored(const JOYSTICK::CDriverPrimitive& primitive) override; + virtual bool IsIgnored(const KODI::JOYSTICK::CDriverPrimitive& primitive) override; + + virtual bool GetAxisProperties(unsigned int axisIndex, int& center, unsigned int& range) override; virtual void SaveButtonMap() override; virtual void RevertButtonMap() override; private: - typedef std::map<JOYSTICK::CDriverPrimitive, JOYSTICK::FeatureName> DriverMap; - typedef std::vector<JOYSTICK::CDriverPrimitive> JoystickPrimitiveVector; + typedef std::map<KODI::JOYSTICK::CDriverPrimitive, KODI::JOYSTICK::FeatureName> DriverMap; + typedef std::vector<KODI::JOYSTICK::CDriverPrimitive> JoystickPrimitiveVector; // Utility functions static DriverMap CreateLookupTable(const FeatureMap& features); - static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(JOYSTICK::ANALOG_STICK_DIRECTION dir); + static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(KODI::JOYSTICK::ANALOG_STICK_DIRECTION dir); CPeripheral* const m_device; std::weak_ptr<CPeripheralAddon> m_addon; diff --git a/xbmc/peripherals/addons/AddonButtonMapping.cpp b/xbmc/peripherals/addons/AddonButtonMapping.cpp index 9037fbf677..8717033c87 100644 --- a/xbmc/peripherals/addons/AddonButtonMapping.cpp +++ b/xbmc/peripherals/addons/AddonButtonMapping.cpp @@ -25,6 +25,7 @@ #include "peripherals/Peripherals.h" #include "utils/log.h" +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; @@ -73,10 +74,10 @@ bool CAddonButtonMapping::OnHatMotion(unsigned int hatIndex, HAT_STATE state) return false; } -bool CAddonButtonMapping::OnAxisMotion(unsigned int axisIndex, float position) +bool CAddonButtonMapping::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) { if (m_buttonMapping) - return m_buttonMapping->OnAxisMotion(axisIndex, position); + return m_buttonMapping->OnAxisMotion(axisIndex, position, center, range); return false; } diff --git a/xbmc/peripherals/addons/AddonButtonMapping.h b/xbmc/peripherals/addons/AddonButtonMapping.h index 5b16e338e9..1474ef2a1a 100644 --- a/xbmc/peripherals/addons/AddonButtonMapping.h +++ b/xbmc/peripherals/addons/AddonButtonMapping.h @@ -24,29 +24,32 @@ #include <memory> +namespace KODI +{ namespace JOYSTICK { class CButtonMapping; class IButtonMap; class IButtonMapper; } +} namespace PERIPHERALS { class CPeripheral; - class CAddonButtonMapping : public JOYSTICK::IDriverHandler, - public JOYSTICK::IButtonMapCallback + class CAddonButtonMapping : public KODI::JOYSTICK::IDriverHandler, + public KODI::JOYSTICK::IButtonMapCallback { public: - CAddonButtonMapping(CPeripheral* peripheral, JOYSTICK::IButtonMapper* mapper); + CAddonButtonMapping(CPeripheral* peripheral, KODI::JOYSTICK::IButtonMapper* mapper); virtual ~CAddonButtonMapping(void); // implementation of IDriverHandler virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; - virtual bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; + virtual bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state) override; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override; virtual void ProcessAxisMotions(void) override; // implementation of IButtonMapCallback @@ -55,7 +58,7 @@ namespace PERIPHERALS virtual void RevertButtonMap() override; private: - std::unique_ptr<JOYSTICK::CButtonMapping> m_buttonMapping; - std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap; + std::unique_ptr<KODI::JOYSTICK::CButtonMapping> m_buttonMapping; + std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap; }; } diff --git a/xbmc/peripherals/addons/AddonInputHandling.cpp b/xbmc/peripherals/addons/AddonInputHandling.cpp index 2ec2ac801e..cc995ee0b5 100644 --- a/xbmc/peripherals/addons/AddonInputHandling.cpp +++ b/xbmc/peripherals/addons/AddonInputHandling.cpp @@ -28,6 +28,7 @@ #include "peripherals/Peripherals.h" #include "utils/log.h" +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; @@ -84,10 +85,10 @@ bool CAddonInputHandling::OnHatMotion(unsigned int hatIndex, HAT_STATE state) return false; } -bool CAddonInputHandling::OnAxisMotion(unsigned int axisIndex, float position) +bool CAddonInputHandling::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) { if (m_driverHandler) - return m_driverHandler->OnAxisMotion(axisIndex, position); + return m_driverHandler->OnAxisMotion(axisIndex, position, center, range); return false; } diff --git a/xbmc/peripherals/addons/AddonInputHandling.h b/xbmc/peripherals/addons/AddonInputHandling.h index 54f1020e4a..b249792b99 100644 --- a/xbmc/peripherals/addons/AddonInputHandling.h +++ b/xbmc/peripherals/addons/AddonInputHandling.h @@ -24,37 +24,40 @@ #include <memory> +namespace KODI +{ namespace JOYSTICK { class IButtonMap; class IDriverReceiver; class IInputHandler; } +} namespace PERIPHERALS { class CPeripheral; - class CAddonInputHandling : public JOYSTICK::IDriverHandler, - public JOYSTICK::IInputReceiver + class CAddonInputHandling : public KODI::JOYSTICK::IDriverHandler, + public KODI::JOYSTICK::IInputReceiver { public: - CAddonInputHandling(CPeripheral* peripheral, JOYSTICK::IInputHandler* handler, JOYSTICK::IDriverReceiver* receiver); + CAddonInputHandling(CPeripheral* peripheral, KODI::JOYSTICK::IInputHandler* handler, KODI::JOYSTICK::IDriverReceiver* receiver); virtual ~CAddonInputHandling(void); // implementation of IDriverHandler virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; - virtual bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; + virtual bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state) override; + virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override; virtual void ProcessAxisMotions(void) override; // implementation of IInputReceiver - virtual bool SetRumbleState(const JOYSTICK::FeatureName& feature, float magnitude) override; + virtual bool SetRumbleState(const KODI::JOYSTICK::FeatureName& feature, float magnitude) override; private: - std::unique_ptr<JOYSTICK::IDriverHandler> m_driverHandler; - std::unique_ptr<JOYSTICK::IInputReceiver> m_inputReceiver; - std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap; + std::unique_ptr<KODI::JOYSTICK::IDriverHandler> m_driverHandler; + std::unique_ptr<KODI::JOYSTICK::IInputReceiver> m_inputReceiver; + std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap; }; } diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp index b070ac7484..2b408fe980 100644 --- a/xbmc/peripherals/addons/PeripheralAddon.cpp +++ b/xbmc/peripherals/addons/PeripheralAddon.cpp @@ -43,6 +43,7 @@ #include <string.h> #include <utility> +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; using namespace XFILE; diff --git a/xbmc/peripherals/addons/PeripheralAddon.h b/xbmc/peripherals/addons/PeripheralAddon.h index afb5c5760e..016a3fe793 100644 --- a/xbmc/peripherals/addons/PeripheralAddon.h +++ b/xbmc/peripherals/addons/PeripheralAddon.h @@ -30,11 +30,14 @@ #include <memory> #include <vector> +namespace KODI +{ namespace JOYSTICK { class IButtonMap; class IDriverHandler; } +} namespace PERIPHERALS { @@ -42,7 +45,7 @@ namespace PERIPHERALS class CPeripheralJoystick; typedef std::vector<ADDON::DriverPrimitive> PrimitiveVector; - typedef std::map<JOYSTICK::FeatureName, ADDON::JoystickFeature> FeatureMap; + typedef std::map<KODI::JOYSTICK::FeatureName, ADDON::JoystickFeature> FeatureMap; class CPeripheralAddon : public ADDON::CAddonDll { @@ -93,8 +96,8 @@ namespace PERIPHERALS void PowerOffJoystick(unsigned int index); //@} - void RegisterButtonMap(CPeripheral* device, JOYSTICK::IButtonMap* buttonMap); - void UnregisterButtonMap(JOYSTICK::IButtonMap* buttonMap); + void RegisterButtonMap(CPeripheral* device, KODI::JOYSTICK::IButtonMap* buttonMap); + void UnregisterButtonMap(KODI::JOYSTICK::IButtonMap* buttonMap); void RefreshButtonMaps(const std::string& strDeviceName = ""); protected: @@ -149,7 +152,7 @@ namespace PERIPHERALS std::map<unsigned int, PeripheralPtr> m_peripherals; /* @brief Button map observers */ - std::vector<std::pair<CPeripheral*, JOYSTICK::IButtonMap*> > m_buttonMaps; + std::vector<std::pair<CPeripheral*, KODI::JOYSTICK::IButtonMap*> > m_buttonMaps; CCriticalSection m_buttonMapMutex; /* @brief Thread synchronization */ diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp index d344364b53..4c9725cc84 100644 --- a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp +++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp @@ -24,6 +24,7 @@ #include <algorithm> #include <iterator> +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; @@ -104,7 +105,7 @@ CDriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const ADDON::Dri } case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS: { - retVal = CDriverPrimitive(primitive.DriverIndex(), TranslateSemiAxisDirection(primitive.SemiAxisDirection())); + retVal = CDriverPrimitive(primitive.DriverIndex(), primitive.Center(), TranslateSemiAxisDirection(primitive.SemiAxisDirection()), primitive.Range()); break; } case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR: @@ -137,7 +138,7 @@ ADDON::DriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const CDri } case SEMIAXIS: { - retVal = ADDON::DriverPrimitive(primitive.Index(), TranslateSemiAxisDirection(primitive.SemiAxisDirection())); + retVal = ADDON::DriverPrimitive(primitive.Index(), primitive.Center(), TranslateSemiAxisDirection(primitive.SemiAxisDirection()), primitive.Range()); break; } case MOTOR: @@ -268,5 +269,5 @@ JOYSTICK_FEATURE_TYPE CPeripheralAddonTranslator::TranslateFeatureType(JOYSTICK: ADDON::DriverPrimitive CPeripheralAddonTranslator::Opposite(const ADDON::DriverPrimitive& primitive) { - return ADDON::DriverPrimitive(primitive.DriverIndex(), primitive.SemiAxisDirection() * -1); + return ADDON::DriverPrimitive(primitive.DriverIndex(), primitive.Center() * -1, primitive.SemiAxisDirection() * -1, primitive.Range()); } diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.h b/xbmc/peripherals/addons/PeripheralAddonTranslator.h index 88e74dc966..94388641cb 100644 --- a/xbmc/peripherals/addons/PeripheralAddonTranslator.h +++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.h @@ -37,22 +37,22 @@ namespace PERIPHERALS static PeripheralType TranslateType(PERIPHERAL_TYPE type); static PERIPHERAL_TYPE TranslateType(PeripheralType type); - static JOYSTICK::CDriverPrimitive TranslatePrimitive(const ADDON::DriverPrimitive& primitive); - static ADDON::DriverPrimitive TranslatePrimitive(const JOYSTICK::CDriverPrimitive& primitive); + static KODI::JOYSTICK::CDriverPrimitive TranslatePrimitive(const ADDON::DriverPrimitive& primitive); + static ADDON::DriverPrimitive TranslatePrimitive(const KODI::JOYSTICK::CDriverPrimitive& primitive); - static std::vector<JOYSTICK::CDriverPrimitive> TranslatePrimitives(const std::vector<ADDON::DriverPrimitive>& primitives); - static std::vector<ADDON::DriverPrimitive> TranslatePrimitives(const std::vector<JOYSTICK::CDriverPrimitive>& primitives); + static std::vector<KODI::JOYSTICK::CDriverPrimitive> TranslatePrimitives(const std::vector<ADDON::DriverPrimitive>& primitives); + static std::vector<ADDON::DriverPrimitive> TranslatePrimitives(const std::vector<KODI::JOYSTICK::CDriverPrimitive>& primitives); - static JOYSTICK::HAT_DIRECTION TranslateHatDirection(JOYSTICK_DRIVER_HAT_DIRECTION dir); - static JOYSTICK_DRIVER_HAT_DIRECTION TranslateHatDirection(JOYSTICK::HAT_DIRECTION dir); + static KODI::JOYSTICK::HAT_DIRECTION TranslateHatDirection(JOYSTICK_DRIVER_HAT_DIRECTION dir); + static JOYSTICK_DRIVER_HAT_DIRECTION TranslateHatDirection(KODI::JOYSTICK::HAT_DIRECTION dir); - static JOYSTICK::HAT_STATE TranslateHatState(JOYSTICK_STATE_HAT state); + static KODI::JOYSTICK::HAT_STATE TranslateHatState(JOYSTICK_STATE_HAT state); - static JOYSTICK::SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_DIRECTION dir); - static JOYSTICK_DRIVER_SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK::SEMIAXIS_DIRECTION dir); + static KODI::JOYSTICK::SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_DIRECTION dir); + static JOYSTICK_DRIVER_SEMIAXIS_DIRECTION TranslateSemiAxisDirection(KODI::JOYSTICK::SEMIAXIS_DIRECTION dir); - static JOYSTICK::FEATURE_TYPE TranslateFeatureType(JOYSTICK_FEATURE_TYPE type); - static JOYSTICK_FEATURE_TYPE TranslateFeatureType(JOYSTICK::FEATURE_TYPE type); + static KODI::JOYSTICK::FEATURE_TYPE TranslateFeatureType(JOYSTICK_FEATURE_TYPE type); + static JOYSTICK_FEATURE_TYPE TranslateFeatureType(KODI::JOYSTICK::FEATURE_TYPE type); static ADDON::DriverPrimitive Opposite(const ADDON::DriverPrimitive& semiaxis); }; diff --git a/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp b/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp index efb81a8fb5..56e8436b3d 100644 --- a/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp +++ b/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp @@ -31,6 +31,7 @@ #include "utils/log.h" #include "utils/StringUtils.h" +using namespace KODI; using namespace PERIPHERALS; static const std::string DeviceLocationPrefix = "android/inputdevice/"; diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp index fcd3ff6062..9cc928fe32 100644 --- a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp +++ b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp @@ -31,6 +31,7 @@ #include <algorithm> #include <memory> +using namespace KODI; using namespace PERIPHERALS; CPeripheralBusAddon::CPeripheralBusAddon(CPeripherals *manager) : @@ -494,7 +495,7 @@ void CPeripheralBusAddon::UpdateAddons(void) bool CPeripheralBusAddon::PromptEnableAddons(const ADDON::VECADDONS& disabledAddons) { using namespace ADDON; - using namespace KODI::MESSAGING::HELPERS; + using namespace MESSAGING::HELPERS; // True if the user confirms enabling the disabled peripheral add-on bool bAccepted = false; diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp index b0cf3de067..12968e3ec0 100644 --- a/xbmc/peripherals/devices/Peripheral.cpp +++ b/xbmc/peripherals/devices/Peripheral.cpp @@ -38,6 +38,7 @@ #include "Util.h" #include "filesystem/File.h" +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h index f77dfa1910..cc2192c408 100644 --- a/xbmc/peripherals/devices/Peripheral.h +++ b/xbmc/peripherals/devices/Peripheral.h @@ -28,6 +28,8 @@ class TiXmlDocument; class CSetting; +namespace KODI +{ namespace JOYSTICK { class IActionMap; @@ -36,6 +38,7 @@ namespace JOYSTICK class IDriverReceiver; class IInputHandler; } +} namespace PERIPHERALS { @@ -192,18 +195,18 @@ namespace PERIPHERALS virtual bool ErrorOccured(void) const { return m_bError; } - virtual void RegisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler, bool bPromiscuous) { } - virtual void UnregisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler) { } + virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) { } + virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) { } - virtual void RegisterJoystickInputHandler(JOYSTICK::IInputHandler* handler); - virtual void UnregisterJoystickInputHandler(JOYSTICK::IInputHandler* handler); + virtual void RegisterJoystickInputHandler(KODI::JOYSTICK::IInputHandler* handler); + virtual void UnregisterJoystickInputHandler(KODI::JOYSTICK::IInputHandler* handler); - virtual void RegisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper); - virtual void UnregisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper); + virtual void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); + virtual void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); - virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() { return nullptr; } + virtual KODI::JOYSTICK::IDriverReceiver* GetDriverReceiver() { return nullptr; } - virtual JOYSTICK::IActionMap* GetActionMap() { return nullptr; } + virtual KODI::JOYSTICK::IActionMap* GetActionMap() { return nullptr; } protected: virtual void ClearSettings(void); @@ -228,7 +231,7 @@ namespace PERIPHERALS std::map<std::string, PeripheralDeviceSetting> m_settings; std::set<std::string> m_changedSettings; CPeripheralBus* m_bus; - std::map<JOYSTICK::IInputHandler*, std::unique_ptr<JOYSTICK::IDriverHandler>> m_inputHandlers; - std::map<JOYSTICK::IButtonMapper*, JOYSTICK::IDriverHandler*> m_buttonMappers; + std::map<KODI::JOYSTICK::IInputHandler*, std::unique_ptr<KODI::JOYSTICK::IDriverHandler>> m_inputHandlers; + std::map<KODI::JOYSTICK::IButtonMapper*, KODI::JOYSTICK::IDriverHandler*> m_buttonMappers; }; } diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 54dc37e751..5b5b38df65 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -38,7 +38,8 @@ #include <libcec/cec.h> -using namespace KODI::MESSAGING; +using namespace KODI; +using namespace MESSAGING; using namespace PERIPHERALS; using namespace ANNOUNCEMENT; using namespace CEC; diff --git a/xbmc/peripherals/devices/PeripheralJoystick.cpp b/xbmc/peripherals/devices/PeripheralJoystick.cpp index e5035db8c2..493a261191 100644 --- a/xbmc/peripherals/devices/PeripheralJoystick.cpp +++ b/xbmc/peripherals/devices/PeripheralJoystick.cpp @@ -29,6 +29,7 @@ #include <algorithm> +using namespace KODI; using namespace JOYSTICK; using namespace PERIPHERALS; @@ -218,17 +219,23 @@ bool CPeripheralJoystick::OnHatMotion(unsigned int hatIndex, HAT_STATE state) bool CPeripheralJoystick::OnAxisMotion(unsigned int axisIndex, float position) { - CSingleLock lock(m_handlerMutex); + // Get axis properties + int center = 0; + unsigned int range = 1; + if (m_buttonMap) + m_buttonMap->GetAxisProperties(axisIndex, center, range); // Apply deadzone filtering - if (m_deadzoneFilter) + if (center == 0 && m_deadzoneFilter) position = m_deadzoneFilter->FilterAxis(axisIndex, position); + CSingleLock lock(m_handlerMutex); + // Process promiscuous handlers for (std::vector<DriverHandler>::iterator it = m_driverHandlers.begin(); it != m_driverHandlers.end(); ++it) { if (it->bPromiscuous) - it->handler->OnAxisMotion(axisIndex, position); + it->handler->OnAxisMotion(axisIndex, position, center, range); } bool bHandled = false; @@ -238,11 +245,11 @@ bool CPeripheralJoystick::OnAxisMotion(unsigned int axisIndex, float position) { if (!it->bPromiscuous) { - bHandled |= it->handler->OnAxisMotion(axisIndex, position); + bHandled |= it->handler->OnAxisMotion(axisIndex, position, center, range); // If axis is centered, force bHandled to false to notify all handlers. // This avoids "sticking". - if (position == 0.0f) + if (position == static_cast<float>(center)) bHandled = false; // Once an axis is handled, we're done diff --git a/xbmc/peripherals/devices/PeripheralJoystick.h b/xbmc/peripherals/devices/PeripheralJoystick.h index 72e0bb2c65..03288c9946 100644 --- a/xbmc/peripherals/devices/PeripheralJoystick.h +++ b/xbmc/peripherals/devices/PeripheralJoystick.h @@ -21,7 +21,6 @@ #include "Peripheral.h" #include "input/joysticks/DefaultJoystick.h" -#include "input/joysticks/IDriverHandler.h" #include "input/joysticks/IDriverReceiver.h" #include "input/joysticks/JoystickMonitor.h" #include "input/joysticks/JoystickTypes.h" @@ -33,17 +32,20 @@ #define JOYSTICK_PORT_UNKNOWN (-1) +namespace KODI +{ namespace JOYSTICK { class CDeadzoneFilter; class IButtonMap; + class IDriverHandler; +} } namespace PERIPHERALS { class CPeripheralJoystick : public CPeripheral, //! @todo extend CPeripheralHID - public JOYSTICK::IDriverHandler, - public JOYSTICK::IDriverReceiver + public KODI::JOYSTICK::IDriverReceiver { public: CPeripheralJoystick(const PeripheralScanResult& scanResult, CPeripheralBus* bus); @@ -54,16 +56,15 @@ namespace PERIPHERALS virtual bool InitialiseFeature(const PeripheralFeature feature) override; virtual void OnUserNotification() override; virtual bool TestFeature(PeripheralFeature feature) override; - virtual void RegisterJoystickDriverHandler(IDriverHandler* handler, bool bPromiscuous) override; - virtual void UnregisterJoystickDriverHandler(IDriverHandler* handler) override; - virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() override { return this; } - virtual JOYSTICK::IActionMap* GetActionMap() override { return &m_defaultInputHandler; } + virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override; + virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) override; + virtual KODI::JOYSTICK::IDriverReceiver* GetDriverReceiver() override { return this; } + virtual KODI::JOYSTICK::IActionMap* GetActionMap() override { return &m_defaultInputHandler; } - // implementation of IDriverHandler - virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override; - virtual bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state) override; - virtual bool OnAxisMotion(unsigned int axisIndex, float position) override; - virtual void ProcessAxisMotions(void) override; + bool OnButtonMotion(unsigned int buttonIndex, bool bPressed); + bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state); + bool OnAxisMotion(unsigned int axisIndex, float position); + void ProcessAxisMotions(void); // implementation of IDriverReceiver virtual bool SetMotorState(unsigned int motorIndex, float magnitude) override; @@ -109,7 +110,7 @@ namespace PERIPHERALS struct DriverHandler { - JOYSTICK::IDriverHandler* handler; + KODI::JOYSTICK::IDriverHandler* handler; bool bPromiscuous; }; @@ -120,10 +121,10 @@ namespace PERIPHERALS unsigned int m_axisCount; unsigned int m_motorCount; bool m_supportsPowerOff; - JOYSTICK::CDefaultJoystick m_defaultInputHandler; - JOYSTICK::CJoystickMonitor m_joystickMonitor; - std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap; - std::unique_ptr<JOYSTICK::CDeadzoneFilter> m_deadzoneFilter; + KODI::JOYSTICK::CDefaultJoystick m_defaultInputHandler; + KODI::JOYSTICK::CJoystickMonitor m_joystickMonitor; + std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap; + std::unique_ptr<KODI::JOYSTICK::CDeadzoneFilter> m_deadzoneFilter; std::vector<DriverHandler> m_driverHandlers; CCriticalSection m_handlerMutex; }; diff --git a/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp b/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp index dceadeb478..266949b32b 100644 --- a/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp +++ b/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp @@ -25,6 +25,7 @@ #include <sstream> +using namespace KODI; using namespace PERIPHERALS; CPeripheralJoystickEmulation::CPeripheralJoystickEmulation(const PeripheralScanResult& scanResult, CPeripheralBus* bus) : diff --git a/xbmc/peripherals/devices/PeripheralJoystickEmulation.h b/xbmc/peripherals/devices/PeripheralJoystickEmulation.h index 1d22a63e8e..901aedde90 100644 --- a/xbmc/peripherals/devices/PeripheralJoystickEmulation.h +++ b/xbmc/peripherals/devices/PeripheralJoystickEmulation.h @@ -26,7 +26,7 @@ namespace PERIPHERALS { class CPeripheralJoystickEmulation : public CPeripheral, - public KEYBOARD::IKeyboardHandler + public KODI::KEYBOARD::IKeyboardHandler { public: CPeripheralJoystickEmulation(const PeripheralScanResult& scanResult, CPeripheralBus* bus); @@ -35,8 +35,8 @@ namespace PERIPHERALS // implementation of CPeripheral virtual bool InitialiseFeature(const PeripheralFeature feature) override; - virtual void RegisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override; - virtual void UnregisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler) override; + virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override; + virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) override; // implementation of IKeyboardHandler virtual bool OnKeyPress(const CKey& key) override; @@ -50,11 +50,11 @@ namespace PERIPHERALS private: struct KeyboardHandle { - KEYBOARD::IKeyboardHandler* handler; + KODI::KEYBOARD::IKeyboardHandler* handler; bool bPromiscuous; }; - typedef std::map<JOYSTICK::IDriverHandler*, KeyboardHandle> KeyboardHandlers; + typedef std::map<KODI::JOYSTICK::IDriverHandler*, KeyboardHandle> KeyboardHandlers; KeyboardHandlers m_keyboardHandlers; CCriticalSection m_mutex; diff --git a/xbmc/pictures/GUIViewStatePictures.cpp b/xbmc/pictures/GUIViewStatePictures.cpp index 226cb8a173..138e3a42c6 100644 --- a/xbmc/pictures/GUIViewStatePictures.cpp +++ b/xbmc/pictures/GUIViewStatePictures.cpp @@ -73,7 +73,7 @@ std::string CGUIViewStateWindowPictures::GetLockType() std::string CGUIViewStateWindowPictures::GetExtensions() { - std::string extensions = g_advancedSettings.m_pictureExtensions; + std::string extensions = g_advancedSettings.GetPictureExtensions(); if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PICTURES_SHOWVIDEOS)) extensions += "|" + g_advancedSettings.m_videoExtensions; diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp index 7f271c31d2..6b2c4ece87 100644 --- a/xbmc/pictures/PictureThumbLoader.cpp +++ b/xbmc/pictures/PictureThumbLoader.cpp @@ -183,7 +183,7 @@ void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem) CFileItemList items; - CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS); + CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS); // create the folder thumb by choosing 4 random thumbs within the folder and putting // them into one thumb. @@ -202,7 +202,7 @@ void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem) { if (pItem->IsCBZ() || pItem->IsCBR()) { - CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS); + CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS); for (int i=0;i<items.Size();++i) { CFileItemPtr item = items[i]; diff --git a/xbmc/platform/android/jni/InetAddress.h b/xbmc/platform/android/jni/InetAddress.h index a8fb0f8e78..42119b41f9 100644 --- a/xbmc/platform/android/jni/InetAddress.h +++ b/xbmc/platform/android/jni/InetAddress.h @@ -47,4 +47,4 @@ protected: static const char *m_classname; }; -typedef std::vector<CJNIInetAddress> CJNIInetAddresss; +typedef std::vector<CJNIInetAddress> CJNIInetAddresses; diff --git a/xbmc/platform/xbmc.cpp b/xbmc/platform/xbmc.cpp index 34e5ea67d4..5791e306ff 100644 --- a/xbmc/platform/xbmc.cpp +++ b/xbmc/platform/xbmc.cpp @@ -58,7 +58,7 @@ extern "C" int XBMC_Run(bool renderGUI, CFileItemList &playlist) #ifdef TARGET_RASPBERRY_PI if(!g_RBP.Initialize()) return false; - g_RBP.LogFirmwareVerison(); + g_RBP.LogFirmwareVersion(); #endif if (renderGUI && !g_application.CreateGUI()) diff --git a/xbmc/pvr/PVRChannelNumberInputHandler.cpp b/xbmc/pvr/PVRChannelNumberInputHandler.cpp index 3cf8e5b79f..87b52a752a 100644 --- a/xbmc/pvr/PVRChannelNumberInputHandler.cpp +++ b/xbmc/pvr/PVRChannelNumberInputHandler.cpp @@ -55,14 +55,14 @@ void CPVRChannelNumberInputHandler::AppendChannelNumberDigit(int iDigit) CSingleLock lock(m_mutex); - if (m_digits.size() == m_iMaxDigits) + if (m_digits.size() == (size_t)m_iMaxDigits) m_digits.pop_front(); m_digits.emplace_back(iDigit); // recalc channel string m_strChannel.erase(); - if (m_digits.size() != m_iMaxDigits || GetChannelNumber() > 0) + if (m_digits.size() != (size_t)m_iMaxDigits || GetChannelNumber() > 0) { for (int digit : m_digits) m_strChannel.append(StringUtils::Format("%d", digit)); diff --git a/xbmc/pvr/PVRGUIActions.cpp b/xbmc/pvr/PVRGUIActions.cpp index 296ff8d6c1..3265b143b0 100644 --- a/xbmc/pvr/PVRGUIActions.cpp +++ b/xbmc/pvr/PVRGUIActions.cpp @@ -121,8 +121,9 @@ namespace PVR if (windowToClose) windowToClose->Close(); + windowSearch->SetItemToSearch(item); g_windowManager.ActivateWindow(windowSearchId); - return windowSearch->FindSimilar(item); + return true; }; bool CPVRGUIActions::ShowTimerSettings(const CPVRTimerInfoTagPtr &timer) const diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index aa5a5a2f0c..6887349a23 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -160,7 +160,8 @@ CPVRManager::CPVRManager(void) : m_bFirstStart(true), m_bIsSwitchingChannels(false), m_bEpgsCreated(false), - m_progressHandle(NULL), + m_progressBar(nullptr), + m_progressHandle(nullptr), m_managerState(ManagerStateStopped), m_isChannelPreview(false) { @@ -377,6 +378,14 @@ void CPVRManager::Init() settingSet.insert(CSettings::SETTING_PVRPARENTAL_ENABLED); CServiceBroker::GetSettings().RegisterCallback(this, settingSet); + // Note: we're holding the progress bar dialog instance pointer in a member because it is needed by pvr core + // components. The latter might run in a different thread than the gui and g_windowManager.GetWindow() + // locks the global graphics mutex, which easily can lead to deadlocks. + m_progressBar = dynamic_cast<CGUIDialogExtendedProgressBar *>(g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS)); + + if (!m_progressBar) + CLog::Log(LOGERROR, "CPVRManager - %s - unable to get WINDOW_DIALOG_EXT_PROGRESS!", __FUNCTION__); + // initial check for enabled addons // if at least one pvr addon is enabled, PVRManager start up CJobManager::GetInstance().AddJob(new CPVRStartupJob(), nullptr); @@ -691,14 +700,14 @@ bool CPVRManager::Load(bool bShowProgress) void CPVRManager::ShowProgressDialog(const std::string &strText, int iProgress) { - if (!m_progressHandle) + if (!m_progressHandle && m_progressBar) + m_progressHandle = m_progressBar->GetHandle(g_localizeStrings.Get(19235)); // PVR manager is starting up + + if (m_progressHandle) { - CGUIDialogExtendedProgressBar *loadingProgressDialog = (CGUIDialogExtendedProgressBar *)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS); - m_progressHandle = loadingProgressDialog->GetHandle(g_localizeStrings.Get(19235)); // PVR manager is starting up + m_progressHandle->SetPercentage(static_cast<float>(iProgress)); + m_progressHandle->SetText(strText); } - - m_progressHandle->SetPercentage((float)iProgress); - m_progressHandle->SetText(strText); } void CPVRManager::HideProgressDialog(void) @@ -710,6 +719,14 @@ void CPVRManager::HideProgressDialog(void) } } +CGUIDialogProgressBarHandle* CPVRManager::ShowProgressDialog(const std::string &strTitle) const +{ + if (m_progressBar) + return m_progressBar->GetHandle(strTitle); + + return nullptr; +} + bool CPVRManager::ChannelSwitchById(unsigned int iChannelId) { CSingleLock lock(m_critSection); @@ -1390,7 +1407,8 @@ bool CPVRManager::UpdateItem(CFileItem& item) } CSingleLock lock(m_critSection); - if (!m_currentFile || *m_currentFile->GetPVRChannelInfoTag() == *item.GetPVRChannelInfoTag()) + if (!m_currentFile || !m_currentFile->GetPVRChannelInfoTag() || !item.GetPVRChannelInfoTag() || + *m_currentFile->GetPVRChannelInfoTag() == *item.GetPVRChannelInfoTag()) return false; g_application.SetCurrentFileItem(*m_currentFile); @@ -1538,6 +1556,7 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev return false; // check whether we're waiting for a previous switch to complete + CFileItemPtr previousFile; { CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) @@ -1567,12 +1586,11 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev } m_bIsSwitchingChannels = true; - } - CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); - const CFileItemPtr previousFile(m_currentFile); - m_currentFile.reset(); + previousFile = std::move(m_currentFile); + } bool bSwitched(false); diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h index e44fc6ffde..891c3376fb 100644 --- a/xbmc/pvr/PVRManager.h +++ b/xbmc/pvr/PVRManager.h @@ -38,6 +38,7 @@ #include <string> #include <vector> +class CGUIDialogExtendedProgressBar; class CGUIDialogProgressBarHandle; class CStopWatch; class CAction; @@ -603,6 +604,13 @@ namespace PVR */ void PublishEvent(PVREvent state); + /*! + * @brief Show an extended progress bar dialog. + * @param strTitle the title for the dialog. + * @return the handle that can be used to control the progress dialog. + */ + CGUIDialogProgressBarHandle* ShowProgressDialog(const std::string &strTitle) const; + protected: /*! * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data. @@ -695,6 +703,7 @@ namespace PVR bool m_bFirstStart; /*!< true when the PVR manager was started first, false otherwise */ bool m_bIsSwitchingChannels; /*!< true while switching channels */ bool m_bEpgsCreated; /*!< true if epg data for channels has been created */ + CGUIDialogExtendedProgressBar * m_progressBar; /*!< extended progress dialog instance pointer */ CGUIDialogProgressBarHandle * m_progressHandle; /*!< progress dialog that is displayed while the pvrmanager is loading */ CCriticalSection m_managerStateMutex; diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index 302836dec1..e456a05e84 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -28,12 +28,10 @@ #include "dialogs/GUIDialogExtendedProgressBar.h" #include "epg/EpgContainer.h" #include "filesystem/Directory.h" -#include "guilib/GUIWindowManager.h" #include "settings/AdvancedSettings.h" #include "settings/lib/Setting.h" #include "settings/Settings.h" #include "threads/SingleLock.h" -#include "utils/JobManager.h" #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" @@ -269,36 +267,20 @@ bool CPVRChannelGroup::MoveChannel(unsigned int iOldChannelNumber, unsigned int void CPVRChannelGroup::SearchAndSetChannelIcons(bool bUpdateDb /* = false */) { - // searching and setting channel icons may take some time, and (more important) - // it triggers GUI which might lead to deadlocks if directly called. - PVR_CHANNEL_GROUP_MEMBERS groupMembers; - { - CSingleLock lock(m_critSection); - groupMembers = m_members; - } - - CJobManager::GetInstance().AddJob(new CPVRSearchAndSetChannelIcons(groupMembers, bUpdateDb), nullptr); -} - -bool CPVRSearchAndSetChannelIcons::DoWork() -{ std::string iconPath = CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRMENU_ICONPATH); if (iconPath.empty()) - return true; - - const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase()); - if (!database) - return false; + return; /* fetch files in icon path for fast lookup */ CFileItemList fileItemList; XFILE::CDirectory::GetDirectory(iconPath, fileItemList, ".jpg|.png|.tbn"); if (fileItemList.IsEmpty()) - return true; + return; - CGUIDialogExtendedProgressBar* dlgProgress = (CGUIDialogExtendedProgressBar*)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS); - CGUIDialogProgressBarHandle* dlgProgressHandle = dlgProgress ? dlgProgress->GetHandle(g_localizeStrings.Get(19287)) : NULL; + CGUIDialogProgressBarHandle* dlgProgressHandle = g_PVRManager.ShowProgressDialog(g_localizeStrings.Get(19286)); // Searching for channel icons + + CSingleLock lock(m_critSection); /* create a map for fast lookup of normalized file base name */ std::map<std::string, std::string> fileItemMap; @@ -313,14 +295,14 @@ bool CPVRSearchAndSetChannelIcons::DoWork() int channelIndex = 0; CPVRChannelPtr channel; - for(const auto &groupMember : m_groupMembers) + for(PVR_CHANNEL_GROUP_MEMBERS::const_iterator it = m_members.begin(); it != m_members.end(); ++it) { - channel = groupMember.second.channel; + channel = it->second.channel; /* update progress dialog */ if (dlgProgressHandle) { - dlgProgressHandle->SetProgress(channelIndex++, m_groupMembers.size()); + dlgProgressHandle->SetProgress(channelIndex++, m_members.size()); dlgProgressHandle->SetText(channel->ChannelName()); } @@ -345,7 +327,7 @@ bool CPVRSearchAndSetChannelIcons::DoWork() channel->SetIconPath(itItem->second, g_advancedSettings.m_bPVRAutoScanIconsUserSet); } - if (m_bUpdateDb) + if (bUpdateDb) channel->Persist(); //! @todo start channel icon scraper here if nothing was found @@ -353,8 +335,6 @@ bool CPVRSearchAndSetChannelIcons::DoWork() if (dlgProgressHandle) dlgProgressHandle->MarkFinished(); - - return true; } /********** sort methods **********/ diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index d598ac9ad8..5fd56c7c9d 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -540,18 +540,4 @@ namespace PVR private: CPVRChannelGroupPtr m_group; }; - - class CPVRSearchAndSetChannelIcons : public CJob - { - public: - CPVRSearchAndSetChannelIcons(const PVR_CHANNEL_GROUP_MEMBERS &groupMembers, bool bUpdateDb) - : m_groupMembers(groupMembers), m_bUpdateDb(bUpdateDb) {} - virtual ~CPVRSearchAndSetChannelIcons() {} - virtual const char *GetType() const { return "pvr-channelgroup-searchandsetchannelicons"; } - - virtual bool DoWork(); - private: - PVR_CHANNEL_GROUP_MEMBERS m_groupMembers; - const bool m_bUpdateDb; - }; } diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp index fa98244a08..9b8345a2cc 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp @@ -70,12 +70,12 @@ void CGUIDialogPVRGuideSearch::UpdateChannelSpin(void) CPVRChannelGroupPtr group; if (iChannelGroup == EPG_SEARCH_UNSET) - group = g_PVRChannelGroups->GetGroupAll(m_searchFilter->m_bIsRadio); + group = g_PVRChannelGroups->GetGroupAll(m_searchFilter->IsRadio()); else group = g_PVRChannelGroups->GetByIdFromAll(iChannelGroup); if (!group) - group = g_PVRChannelGroups->GetGroupAll(m_searchFilter->m_bIsRadio); + group = g_PVRChannelGroups->GetGroupAll(m_searchFilter->IsRadio()); std::vector<PVRChannelGroupMember> groupMembers(group->GetMembers()); for (std::vector<PVRChannelGroupMember>::const_iterator it = groupMembers.begin(); it != groupMembers.end(); ++it) @@ -84,7 +84,7 @@ void CGUIDialogPVRGuideSearch::UpdateChannelSpin(void) labels.push_back(std::make_pair((*it).channel->ChannelName(), (*it).iChannelNumber)); } - SET_CONTROL_LABELS(CONTROL_SPIN_CHANNELS, m_searchFilter->m_iChannelNumber, &labels); + SET_CONTROL_LABELS(CONTROL_SPIN_CHANNELS, m_searchFilter->GetChannelNumber(), &labels); } void CGUIDialogPVRGuideSearch::UpdateGroupsSpin(void) @@ -92,11 +92,11 @@ void CGUIDialogPVRGuideSearch::UpdateGroupsSpin(void) std::vector< std::pair<std::string, int> > labels; /* groups */ - std::vector<CPVRChannelGroupPtr> groups = g_PVRChannelGroups->Get(m_searchFilter->m_bIsRadio)->GetMembers(); + std::vector<CPVRChannelGroupPtr> groups = g_PVRChannelGroups->Get(m_searchFilter->IsRadio())->GetMembers(); for (std::vector<CPVRChannelGroupPtr>::const_iterator it = groups.begin(); it != groups.end(); ++it) labels.push_back(std::make_pair((*it)->GroupName(), (*it)->GroupID())); - SET_CONTROL_LABELS(CONTROL_SPIN_GROUPS, m_searchFilter->m_iChannelGroup, &labels); + SET_CONTROL_LABELS(CONTROL_SPIN_GROUPS, m_searchFilter->GetChannelGroup(), &labels); } void CGUIDialogPVRGuideSearch::UpdateGenreSpin(void) @@ -116,7 +116,7 @@ void CGUIDialogPVRGuideSearch::UpdateGenreSpin(void) labels.push_back(std::make_pair(g_localizeStrings.Get(19660), EPG_EVENT_CONTENTMASK_SPECIAL)); labels.push_back(std::make_pair(g_localizeStrings.Get(19499), EPG_EVENT_CONTENTMASK_USERDEFINED)); - SET_CONTROL_LABELS(CONTROL_SPIN_GENRE, m_searchFilter->m_iGenreType, &labels); + SET_CONTROL_LABELS(CONTROL_SPIN_GENRE, m_searchFilter->GetGenreType(), &labels); } void CGUIDialogPVRGuideSearch::UpdateDurationSpin(void) @@ -128,7 +128,7 @@ void CGUIDialogPVRGuideSearch::UpdateDurationSpin(void) for (int i = 1; i < 12*60/5; ++i) labels.push_back(std::make_pair(StringUtils::Format(g_localizeStrings.Get(14044).c_str(), i*5), i*5)); - SET_CONTROL_LABELS(CONTROL_SPIN_MIN_DURATION, m_searchFilter->m_iMinimumDuration, &labels); + SET_CONTROL_LABELS(CONTROL_SPIN_MIN_DURATION, m_searchFilter->GetMinimumDuration(), &labels); /* maximum duration */ labels.clear(); @@ -137,7 +137,7 @@ void CGUIDialogPVRGuideSearch::UpdateDurationSpin(void) for (int i = 1; i < 12*60/5; ++i) labels.push_back(std::make_pair(StringUtils::Format(g_localizeStrings.Get(14044).c_str(), i*5), i*5)); - SET_CONTROL_LABELS(CONTROL_SPIN_MAX_DURATION, m_searchFilter->m_iMaximumDuration, &labels); + SET_CONTROL_LABELS(CONTROL_SPIN_MAX_DURATION, m_searchFilter->GetMaximumDuration(), &labels); } bool CGUIDialogPVRGuideSearch::OnMessage(CGUIMessage& message) @@ -199,12 +199,14 @@ void CGUIDialogPVRGuideSearch::OnWindowLoaded() return CGUIDialog::OnWindowLoaded(); } -void CGUIDialogPVRGuideSearch::ReadDateTime(const std::string &strDate, const std::string &strTime, CDateTime &dateTime) const +CDateTime CGUIDialogPVRGuideSearch::ReadDateTime(const std::string &strDate, const std::string &strTime) const { + CDateTime dateTime; int iHours, iMinutes; sscanf(strTime.c_str(), "%d:%d", &iHours, &iMinutes); dateTime.SetFromDBDate(strDate); dateTime.SetDateTime(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), iHours, iMinutes, 0); + return dateTime; } bool CGUIDialogPVRGuideSearch::IsRadioSelected(int controlID) @@ -233,26 +235,24 @@ void CGUIDialogPVRGuideSearch::OnSearch() if (!m_searchFilter) return; - m_searchFilter->m_strSearchTerm = GetEditValue(CONTROL_EDIT_SEARCH); - - m_searchFilter->m_bSearchInDescription = IsRadioSelected(CONTROL_BTN_INC_DESC); - m_searchFilter->m_bIsCaseSensitive = IsRadioSelected(CONTROL_BTN_CASE_SENS); - m_searchFilter->m_bFTAOnly = IsRadioSelected(CONTROL_BTN_FTA_ONLY); - m_searchFilter->m_bIncludeUnknownGenres = IsRadioSelected(CONTROL_BTN_UNK_GENRE); - m_searchFilter->m_bIgnorePresentRecordings = IsRadioSelected(CONTROL_BTN_IGNORE_REC); - m_searchFilter->m_bIgnorePresentTimers = IsRadioSelected(CONTROL_BTN_IGNORE_TMR); - m_searchFilter->m_bPreventRepeats = IsRadioSelected(CONTROL_SPIN_NO_REPEATS); - - m_searchFilter->m_iGenreType = GetSpinValue(CONTROL_SPIN_GENRE); - m_searchFilter->m_iMinimumDuration = GetSpinValue(CONTROL_SPIN_MIN_DURATION); - m_searchFilter->m_iMaximumDuration = GetSpinValue(CONTROL_SPIN_MAX_DURATION); - m_searchFilter->m_iChannelNumber = GetSpinValue(CONTROL_SPIN_CHANNELS); - m_searchFilter->m_iChannelGroup = GetSpinValue(CONTROL_SPIN_GROUPS); - - std::string strTmp = GetEditValue(CONTROL_EDIT_START_TIME); - ReadDateTime(GetEditValue(CONTROL_EDIT_START_DATE), strTmp, m_searchFilter->m_startDateTime); - strTmp = GetEditValue(CONTROL_EDIT_STOP_TIME); - ReadDateTime(GetEditValue(CONTROL_EDIT_STOP_DATE), strTmp, m_searchFilter->m_endDateTime); + m_searchFilter->SetSearchTerm(GetEditValue(CONTROL_EDIT_SEARCH)); + + m_searchFilter->SetSearchInDescription(IsRadioSelected(CONTROL_BTN_INC_DESC)); + m_searchFilter->SetCaseSensitive(IsRadioSelected(CONTROL_BTN_CASE_SENS)); + m_searchFilter->SetFreeToAirOnly(IsRadioSelected(CONTROL_BTN_FTA_ONLY)); + m_searchFilter->SetIncludeUnknownGenres(IsRadioSelected(CONTROL_BTN_UNK_GENRE)); + m_searchFilter->SetIgnorePresentRecordings(IsRadioSelected(CONTROL_BTN_IGNORE_REC)); + m_searchFilter->SetIgnorePresentTimers(IsRadioSelected(CONTROL_BTN_IGNORE_TMR)); + m_searchFilter->SetRemoveDuplicates(IsRadioSelected(CONTROL_SPIN_NO_REPEATS)); + + m_searchFilter->SetGenreType(GetSpinValue(CONTROL_SPIN_GENRE)); + m_searchFilter->SetMinimumDuration(GetSpinValue(CONTROL_SPIN_MIN_DURATION)); + m_searchFilter->SetMaximumDuration(GetSpinValue(CONTROL_SPIN_MAX_DURATION)); + m_searchFilter->SetChannelNumber(GetSpinValue(CONTROL_SPIN_CHANNELS)); + m_searchFilter->SetChannelGroup(GetSpinValue(CONTROL_SPIN_GROUPS)); + + m_searchFilter->SetStartDateTime(ReadDateTime(GetEditValue(CONTROL_EDIT_START_DATE), GetEditValue(CONTROL_EDIT_START_TIME))); + m_searchFilter->SetEndDateTime(ReadDateTime(GetEditValue(CONTROL_EDIT_STOP_DATE), GetEditValue(CONTROL_EDIT_STOP_TIME))); } void CGUIDialogPVRGuideSearch::Update() @@ -260,37 +260,37 @@ void CGUIDialogPVRGuideSearch::Update() if (!m_searchFilter) return; - SET_CONTROL_LABEL2(CONTROL_EDIT_SEARCH, m_searchFilter->m_strSearchTerm); + SET_CONTROL_LABEL2(CONTROL_EDIT_SEARCH, m_searchFilter->GetSearchTerm()); { CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_SEARCH, CGUIEditControl::INPUT_TYPE_TEXT, 16017); OnMessage(msg); } - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_CASE_SENS, m_searchFilter->m_bIsCaseSensitive); - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_INC_DESC, m_searchFilter->m_bSearchInDescription); - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_FTA_ONLY, m_searchFilter->m_bFTAOnly); - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_UNK_GENRE, m_searchFilter->m_bIncludeUnknownGenres); - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_REC, m_searchFilter->m_bIgnorePresentRecordings); - SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_TMR, m_searchFilter->m_bIgnorePresentTimers); - SET_CONTROL_SELECTED(GetID(), CONTROL_SPIN_NO_REPEATS, m_searchFilter->m_bPreventRepeats); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_CASE_SENS, m_searchFilter->IsCaseSensitive()); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_INC_DESC, m_searchFilter->ShouldSearchInDescription()); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_FTA_ONLY, m_searchFilter->IsFreeToAirOnly()); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_UNK_GENRE, m_searchFilter->ShouldIncludeUnknownGenres()); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_REC, m_searchFilter->ShouldIgnorePresentRecordings()); + SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_TMR, m_searchFilter->ShouldIgnorePresentTimers()); + SET_CONTROL_SELECTED(GetID(), CONTROL_SPIN_NO_REPEATS, m_searchFilter->ShouldRemoveDuplicates()); /* Set time fields */ - SET_CONTROL_LABEL2(CONTROL_EDIT_START_TIME, m_searchFilter->m_startDateTime.GetAsLocalizedTime("", false)); + SET_CONTROL_LABEL2(CONTROL_EDIT_START_TIME, m_searchFilter->GetStartDateTime().GetAsLocalizedTime("", false)); { CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_START_TIME, CGUIEditControl::INPUT_TYPE_TIME, 14066); OnMessage(msg); } - SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_TIME, m_searchFilter->m_endDateTime.GetAsLocalizedTime("", false)); + SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_TIME, m_searchFilter->GetEndDateTime().GetAsLocalizedTime("", false)); { CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_STOP_TIME, CGUIEditControl::INPUT_TYPE_TIME, 14066); OnMessage(msg); } - SET_CONTROL_LABEL2(CONTROL_EDIT_START_DATE, m_searchFilter->m_startDateTime.GetAsDBDate()); + SET_CONTROL_LABEL2(CONTROL_EDIT_START_DATE, m_searchFilter->GetStartDateTime().GetAsDBDate()); { CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_START_DATE, CGUIEditControl::INPUT_TYPE_DATE, 14067); OnMessage(msg); } - SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_DATE, m_searchFilter->m_endDateTime.GetAsDBDate()); + SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_DATE, m_searchFilter->GetEndDateTime().GetAsDBDate()); { CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_STOP_DATE, CGUIEditControl::INPUT_TYPE_DATE, 14067); OnMessage(msg); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.h b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.h index 0d7cbfa0bd..27c2803b6d 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.h +++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.h @@ -24,7 +24,7 @@ namespace EPG { - struct EpgSearchFilter; + class CEpgSearchFilter; } namespace PVR @@ -37,7 +37,7 @@ namespace PVR virtual bool OnMessage(CGUIMessage& message); virtual void OnWindowLoaded(); - void SetFilterData(EPG::EpgSearchFilter *searchFilter) { m_searchFilter = searchFilter; } + void SetFilterData(EPG::CEpgSearchFilter *searchFilter) { m_searchFilter = searchFilter; } bool IsConfirmed() const { return m_bConfirmed; } bool IsCanceled() const { return m_bCanceled; } void OnSearch(); @@ -49,7 +49,7 @@ namespace PVR void UpdateGroupsSpin(void); void UpdateGenreSpin(void); void UpdateDurationSpin(void); - void ReadDateTime(const std::string &strDate, const std::string &strTime, CDateTime &dateTime) const; + CDateTime ReadDateTime(const std::string &strDate, const std::string &strTime) const; void Update(); bool IsRadioSelected(int controlID); @@ -58,6 +58,6 @@ namespace PVR bool m_bConfirmed; bool m_bCanceled; - EPG::EpgSearchFilter *m_searchFilter; + EPG::CEpgSearchFilter *m_searchFilter; }; } diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp index 18a0ec3341..c0b396d4cb 100644 --- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp @@ -27,6 +27,7 @@ #include "utils/Variant.h" #include "pvr/PVRGUIActions.h" +#include "pvr/PVRItem.h" #include "pvr/PVRManager.h" #include "pvr/addons/PVRClients.h" #include "pvr/channels/PVRChannelGroupsContainer.h" @@ -53,12 +54,6 @@ void CGUIWindowPVRSearch::GetContextButtons(int itemNumber, CContextButtons &but CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } -void CGUIWindowPVRSearch::OnWindowLoaded() -{ - CGUIMediaWindow::OnWindowLoaded(); - m_searchfilter.Reset(); -} - bool CGUIWindowPVRSearch::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { if (itemNumber < 0 || itemNumber >= m_vecItems->Size()) @@ -69,33 +64,25 @@ bool CGUIWindowPVRSearch::OnContextButton(int itemNumber, CONTEXT_BUTTON button) CGUIMediaWindow::OnContextButton(itemNumber, button); } -bool CGUIWindowPVRSearch::FindSimilar(const CFileItemPtr &item) +void CGUIWindowPVRSearch::SetItemToSearch(const CFileItemPtr &item) { m_searchfilter.Reset(); - // construct the search term - if (item->IsEPG()) - m_searchfilter.m_strSearchTerm = "\"" + item->GetEPGInfoTag()->Title() + "\""; - else if (item->IsPVRChannel()) + if (item->IsUsablePVRRecording()) { - const CEpgInfoTagPtr tag(item->GetPVRChannelInfoTag()->GetEPGNow()); - if (tag) - m_searchfilter.m_strSearchTerm = "\"" + tag->Title() + "\""; + m_searchfilter.SetSearchPhrase(item->GetPVRRecordingInfoTag()->m_strTitle); } - else if (item->IsUsablePVRRecording()) - m_searchfilter.m_strSearchTerm = "\"" + item->GetPVRRecordingInfoTag()->m_strTitle + "\""; - else if (item->IsPVRTimer()) + else { - const CPVRTimerInfoTagPtr info(item->GetPVRTimerInfoTag()); - const CEpgInfoTagPtr tag(info->GetEpgInfoTag()); - if (tag) - m_searchfilter.m_strSearchTerm = "\"" + tag->Title() + "\""; - else - m_searchfilter.m_strSearchTerm = "\"" + info->m_strTitle + "\""; + const CEpgInfoTagPtr epgTag(CPVRItem(item).GetEpgInfoTag()); + if (epgTag) + m_searchfilter.SetSearchPhrase(epgTag->Title()); } + m_bSearchConfirmed = true; - Refresh(true); - return true; + + if (IsActive()) + Refresh(true); } void CGUIWindowPVRSearch::OnPrepareFileItems(CFileItemList &items) @@ -111,7 +98,7 @@ void CGUIWindowPVRSearch::OnPrepareFileItems(CFileItemList &items) if (dlgProgress) { dlgProgress->SetHeading(CVariant{194}); // "Searching..." - dlgProgress->SetText(CVariant{m_searchfilter.m_strSearchTerm}); + dlgProgress->SetText(CVariant{m_searchfilter.GetSearchTerm()}); dlgProgress->Open(); dlgProgress->Progress(); } @@ -205,7 +192,7 @@ void CGUIWindowPVRSearch::OpenDialogSearch() dlgSearch->SetFilterData(&m_searchfilter); /* Set channel type filter */ - m_searchfilter.m_bIsRadio = m_bRadio; + m_searchfilter.SetIsRadio(m_bRadio); /* Open dialog window */ dlgSearch->Open(); diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.h b/xbmc/pvr/windows/GUIWindowPVRSearch.h index e9a2812871..155ee05040 100644 --- a/xbmc/pvr/windows/GUIWindowPVRSearch.h +++ b/xbmc/pvr/windows/GUIWindowPVRSearch.h @@ -31,16 +31,14 @@ namespace PVR virtual ~CGUIWindowPVRSearch(void) {}; virtual bool OnMessage(CGUIMessage& message) override; - virtual void OnWindowLoaded() override; virtual void GetContextButtons(int itemNumber, CContextButtons &buttons) override; virtual bool OnContextButton(int itemNumber, CONTEXT_BUTTON button) override; /*! - * @brief trigger a search for events similar to the given item. + * @brief set the item to search similar events for. * @param item the epg event to search similar events for. - * @return True on success (note: empty result set also means success), false otherwise. */ - bool FindSimilar(const CFileItemPtr &item); + void SetItemToSearch(const CFileItemPtr &item); protected: virtual void OnPrepareFileItems(CFileItemList &items) override; @@ -52,6 +50,6 @@ namespace PVR void OpenDialogSearch(); bool m_bSearchConfirmed; - EPG::EpgSearchFilter m_searchfilter; + EPG::CEpgSearchFilter m_searchfilter; }; } diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp index 94ef64a2d3..a2cdc15039 100644 --- a/xbmc/rendering/dx/RenderSystemDX.cpp +++ b/xbmc/rendering/dx/RenderSystemDX.cpp @@ -299,7 +299,7 @@ void CRenderSystemDX::SetFullScreenInternal() OnDisplayLost(); hr = m_pSwapChain->SetFullscreenState(false, nullptr); if (SUCCEEDED(hr)) - m_bResizeRequred = true; + m_bResizeRequired = true; else CLog::Log(LOGERROR, "%s - Failed switch full screen state: %s.", __FUNCTION__, GetErrorDescription(hr).c_str()); } @@ -321,7 +321,7 @@ void CRenderSystemDX::SetFullScreenInternal() OnDisplayLost(); hr = m_pSwapChain->SetFullscreenState(true, m_pOutput); if (SUCCEEDED(hr)) - m_bResizeRequred = true; + m_bResizeRequired = true; else CLog::Log(LOGERROR, "%s - Failed switch full screen state: %s.", __FUNCTION__, GetErrorDescription(hr).c_str()); } @@ -372,12 +372,12 @@ void CRenderSystemDX::SetFullScreenInternal() // change monitor resolution (in fullscreen mode) to required mode CLog::Log(LOGDEBUG, "%s - Switching mode to %dx%d@%0.3f.", __FUNCTION__, matchedMode.Width, matchedMode.Height, matchedRefreshRate); - if (!m_bResizeRequred) + if (!m_bResizeRequired) OnDisplayLost(); hr = m_pSwapChain->ResizeTarget(&matchedMode); if (SUCCEEDED(hr)) - m_bResizeRequred = true; + m_bResizeRequired = true; else CLog::Log(LOGERROR, "%s - Failed to switch output mode: %s", __FUNCTION__, GetErrorDescription(hr).c_str()); } @@ -462,7 +462,7 @@ void CRenderSystemDX::DeleteDevice() SAFE_RELEASE(m_d3dDebug); } #endif - m_bResizeRequred = false; + m_bResizeRequired = false; m_bHWStereoEnabled = false; m_bRenderCreated = false; m_bStereoEnabled = false; @@ -756,7 +756,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() if (m_pSwapChain) { m_pSwapChain->GetDesc(&scDesc); - bNeedResize = m_bResizeRequred || + bNeedResize = m_bResizeRequired || m_nBackBufferWidth != scDesc.BufferDesc.Width || m_nBackBufferHeight != scDesc.BufferDesc.Height; } @@ -772,7 +772,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() if (!bNeedRecreate && !bNeedResize) { - CheckInterlasedStereoView(); + CheckInterlacedStereoView(); return true; } @@ -801,10 +801,10 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() if (bNeedRecreate) { - if (!m_bResizeRequred) + if (!m_bResizeRequired) { OnDisplayLost(); - m_bResizeRequred = true; + m_bResizeRequired = true; } BOOL fullScreen; @@ -1010,22 +1010,22 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() CPoint camPoint = { m_nBackBufferWidth * 0.5f, m_nBackBufferHeight * 0.5f }; SetCameraPosition(camPoint, m_nBackBufferWidth, m_nBackBufferHeight); - CheckInterlasedStereoView(); + CheckInterlacedStereoView(); if (bRestoreRTView) m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView); // notify about resurrection of display - if (m_bResizeRequred) + if (m_bResizeRequired) OnDisplayBack(); m_resizeInProgress = false; - m_bResizeRequred = false; + m_bResizeRequired = false; return true; } -void CRenderSystemDX::CheckInterlasedStereoView(void) +void CRenderSystemDX::CheckInterlacedStereoView(void) { RENDER_STEREO_MODE stereoMode = g_graphicsContext.GetStereoMode(); diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h index f0bf875616..19f5964dba 100644 --- a/xbmc/rendering/dx/RenderSystemDX.h +++ b/xbmc/rendering/dx/RenderSystemDX.h @@ -115,7 +115,7 @@ protected: void OnResize(unsigned int width, unsigned int height); void SetFullScreenInternal(); void GetClosestDisplayModeToCurrent(IDXGIOutput* output, DXGI_MODE_DESC* outCurrentDisplayMode, bool useCached = false); - void CheckInterlasedStereoView(void); + void CheckInterlacedStereoView(void); void SetMaximumFrameLatency(uint8_t latency = -1) const; bool GetStereoEnabled() const; @@ -179,7 +179,7 @@ protected: ID3D11Texture2D* m_pTextureRight{nullptr}; ID3D11RenderTargetView* m_pRenderTargetViewRight{nullptr}; ID3D11ShaderResourceView* m_pShaderResourceViewRight{nullptr}; - bool m_bResizeRequred{false}; + bool m_bResizeRequired{false}; bool m_bHWStereoEnabled{false}; // improve get current mode DXGI_MODE_DESC m_cachedMode; diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h index 55e9bf5549..fe2c6a8fa7 100644 --- a/xbmc/rendering/gl/RenderSystemGL.h +++ b/xbmc/rendering/gl/RenderSystemGL.h @@ -72,7 +72,7 @@ protected: virtual void PresentRenderImpl(bool rendered) = 0; void CalculateMaxTexturesize(); - bool m_bVsyncInit; + bool m_bVsyncInit = false; int m_width; int m_height; diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 4c9b2f99cb..9ce6384c07 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -28,6 +28,7 @@ #include "addons/AudioDecoder.h" #include "addons/BinaryAddonCache.h" #include "addons/IAddon.h" +#include "addons/ImageDecoder.h" #include "Application.h" #include "ServiceBroker.h" #include "filesystem/File.h" @@ -160,7 +161,7 @@ void CAdvancedSettings::Initialize() m_videoFpsDetect = 1; m_videoBusyDialogDelay_ms = 500; - m_mediacodecForceSoftwareRendring = false; + m_mediacodecForceSoftwareRendering = false; m_videoDefaultLatency = 0.0; @@ -275,6 +276,7 @@ void CAdvancedSettings::Initialize() m_bMusicLibraryAllItemsOnBottom = false; m_bMusicLibraryCleanOnUpdate = false; + m_bMusicLibraryPromptFullTagScan = false; m_iMusicLibraryRecentlyAddedItems = 25; m_strMusicLibraryAlbumFormat = ""; m_prioritiseAPEv2tags = false; @@ -592,7 +594,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) XMLUtils::GetBoolean(pElement,"vdpauHDdeintSkipChroma",m_videoVDPAUdeintSkipChromaHD); XMLUtils::GetBoolean(pElement,"useffmpegvda", m_useFfmpegVda); - XMLUtils::GetBoolean(pElement,"mediacodecforcesoftwarerendering",m_mediacodecForceSoftwareRendring); + XMLUtils::GetBoolean(pElement,"mediacodecforcesoftwarerendering",m_mediacodecForceSoftwareRendering); TiXmlElement* pAdjustRefreshrate = pElement->FirstChildElement("adjustrefreshrate"); if (pAdjustRefreshrate) @@ -732,6 +734,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags); XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom); XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bMusicLibraryCleanOnUpdate); + XMLUtils::GetBoolean(pElement, "promptfulltagscan", m_bMusicLibraryPromptFullTagScan); XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat); XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator); XMLUtils::GetInt(pElement, "dateadded", m_iMusicLibraryDateAdded); @@ -1437,3 +1440,20 @@ std::string CAdvancedSettings::GetMusicExtensions() const return result; } + +std::string CAdvancedSettings::GetPictureExtensions() const +{ + std::string result(m_pictureExtensions); + + VECADDONS codecs; + CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache(); + addonCache.GetAddons(codecs, ADDON_IMAGEDECODER); + for (size_t i=0;i<codecs.size();++i) + { + std::shared_ptr<CImageDecoder> dec(std::static_pointer_cast<CImageDecoder>(codecs[i])); + result += '|'; + result += dec->GetExtensions(); + } + + return result; +} diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index d9d48987ee..76428eef8d 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -191,7 +191,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler bool m_DXVAAllowHqScaling; int m_videoFpsDetect; int m_videoBusyDialogDelay_ms; - bool m_mediacodecForceSoftwareRendring; + bool m_mediacodecForceSoftwareRendering; std::string m_videoDefaultPlayer; float m_videoPlayCountMinimumPercent; @@ -256,6 +256,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler int m_iMusicLibraryDateAdded; bool m_bMusicLibraryAllItemsOnBottom; bool m_bMusicLibraryCleanOnUpdate; + bool m_bMusicLibraryPromptFullTagScan; std::string m_strMusicLibraryAlbumFormat; bool m_prioritiseAPEv2tags; std::string m_musicItemSeparator; @@ -356,6 +357,9 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler float GetDisplayLatency(float refreshrate); bool m_initialized; + //! \brief Returns a list of picture extension for filtering in the GUI + std::string GetPictureExtensions() const; + //! \brief Returns a list of music extension for filtering in the GUI std::string GetMusicExtensions() const; @@ -365,7 +369,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler void ToggleDirtyRegionVisualization() { m_guiVisualizeDirtyRegions = !m_guiVisualizeDirtyRegions; }; // runtime settings which cannot be set from advancedsettings.xml - std::string m_pictureExtensions; std::string m_videoExtensions; std::string m_discStubExtensions; std::string m_subtitlesExtensions; @@ -385,6 +388,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler private: std::string m_musicExtensions; + std::string m_pictureExtensions; void setExtraLogLevel(const std::vector<CVariant> &components); }; diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index e745aebf57..89f0414803 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -728,7 +728,7 @@ bool CSettings::InitializeDefinitions() #elif defined(TARGET_RASPBERRY_PI) if (CFile::Exists(SETTINGS_XML_FOLDER "rbp.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp.xml")) CLog::Log(LOGFATAL, "Unable to load rbp-specific settings definitions"); - if (g_RBP.RasberryPiVersion() > 1 && CFile::Exists(SETTINGS_XML_FOLDER "rbp2.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp2.xml")) + if (g_RBP.RaspberryPiVersion() > 1 && CFile::Exists(SETTINGS_XML_FOLDER "rbp2.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp2.xml")) CLog::Log(LOGFATAL, "Unable to load rbp2-specific settings definitions"); #elif defined(TARGET_FREEBSD) if (CFile::Exists(SETTINGS_XML_FOLDER "freebsd.xml") && !Initialize(SETTINGS_XML_FOLDER "freebsd.xml")) diff --git a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp index 2526535fad..8a39ebbcb3 100644 --- a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp +++ b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp @@ -75,7 +75,7 @@ CGUIDialogAudioDSPManager::CGUIDialogAudioDSPManager(void) { m_bMovingMode = false; m_bContainsChanges = false; - m_bContinousSaving = true; + m_bContinuousSaving = true; m_iSelected[LIST_AVAILABLE] = 0; m_iSelected[LIST_ACTIVE] = 0; @@ -195,8 +195,8 @@ void CGUIDialogAudioDSPManager::OnInitWindow() return; } - SET_CONTROL_SELECTED(GetID(), CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING, m_bContinousSaving); - applyButton->SetEnabled(!m_bContinousSaving); + SET_CONTROL_SELECTED(GetID(), CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING, m_bContinuousSaving); + applyButton->SetEnabled(!m_bContinuousSaving); Update(); SetSelectedModeType(); @@ -206,7 +206,7 @@ void CGUIDialogAudioDSPManager::OnDeinitWindow(int nextWindowID) { if (m_bContainsChanges) { - if (m_bContinousSaving) + if (m_bContinuousSaving) { SaveList(); } @@ -218,7 +218,7 @@ void CGUIDialogAudioDSPManager::OnDeinitWindow(int nextWindowID) } else { - m_bContinousSaving = false; + m_bContinuousSaving = false; } } } @@ -277,7 +277,7 @@ bool CGUIDialogAudioDSPManager::OnClickListActive(CGUIMessage &message) m_bMovingMode = false; m_bContainsChanges = true; - if (m_bContinousSaving) + if (m_bContinuousSaving) { SaveList(); } @@ -294,7 +294,7 @@ bool CGUIDialogAudioDSPManager::OnClickListActive(CGUIMessage &message) // reenable all buttons and mode selection list modeList->SetEnabled(true); clearActiveModesButton->SetEnabled(true); - if (!m_bContinousSaving) + if (!m_bContinuousSaving) { applyButton->SetEnabled(true); } @@ -306,7 +306,7 @@ bool CGUIDialogAudioDSPManager::OnClickListActive(CGUIMessage &message) return false; } -bool CGUIDialogAudioDSPManager::OnClickRadioContinousSaving(CGUIMessage &message) +bool CGUIDialogAudioDSPManager::OnClickRadioContinuousSaving(CGUIMessage &message) { CGUIRadioButtonControl *radioButton = dynamic_cast<CGUIRadioButtonControl*>(GetControl(CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING)); CGUIButtonControl *applyChangesButton = dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_BUTTON_APPLY_CHANGES)); @@ -320,11 +320,11 @@ bool CGUIDialogAudioDSPManager::OnClickRadioContinousSaving(CGUIMessage &message if (!radioButton->IsSelected()) { applyChangesButton->SetEnabled(true); - m_bContinousSaving = false; + m_bContinuousSaving = false; } else { - m_bContinousSaving = true; + m_bContinuousSaving = true; applyChangesButton->SetEnabled(false); } @@ -364,7 +364,7 @@ bool CGUIDialogAudioDSPManager::OnClickClearActiveModes(CGUIMessage &message) m_activeViewControl.SetItems(*m_activeItems[m_iCurrentType]); m_bContainsChanges = true; - if (m_bContinousSaving) + if (m_bContinuousSaving) { SaveList(); } @@ -383,7 +383,7 @@ bool CGUIDialogAudioDSPManager::OnMessageClick(CGUIMessage &message) case CONTROL_LIST_ACTIVE: return OnClickListActive(message); case CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING: - return OnClickRadioContinousSaving(message); + return OnClickRadioContinuousSaving(message); case CONTROL_BUTTON_CLEAR_ACTIVE_MODES: return OnClickClearActiveModes(message); case CONTROL_BUTTON_APPLY_CHANGES: @@ -617,7 +617,7 @@ bool CGUIDialogAudioDSPManager::OnContextButton(int itemNumber, CONTEXT_BUTTON b } m_bContainsChanges = true; - if (m_bContinousSaving) + if (m_bContinuousSaving) { SaveList(); } @@ -648,7 +648,7 @@ bool CGUIDialogAudioDSPManager::OnContextButton(int itemNumber, CONTEXT_BUTTON b // if we are in MovingMode all buttons and mode selection list will be disabled! modeList->SetEnabled(false); clearActiveModesButton->SetEnabled(false); - if (!m_bContinousSaving) + if (!m_bContinuousSaving) { applyButton->SetEnabled(false); } diff --git a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h index bf5ed9c5aa..3e13225969 100644 --- a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h +++ b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h @@ -53,7 +53,7 @@ namespace ActiveAE bool OnClickListAvailable(CGUIMessage &message); bool OnClickListActive(CGUIMessage &message); - bool OnClickRadioContinousSaving(CGUIMessage &message); + bool OnClickRadioContinuousSaving(CGUIMessage &message); bool OnClickApplyChanges(CGUIMessage &message); bool OnClickClearActiveModes(CGUIMessage &message); @@ -76,7 +76,7 @@ namespace ActiveAE bool m_bMovingMode; bool m_bContainsChanges; - bool m_bContinousSaving; // if true, all settings are directly saved + bool m_bContinuousSaving; // if true, all settings are directly saved int m_iCurrentType; int m_iSelected[AE_DSP_MODE_TYPE_MAX]; diff --git a/xbmc/test/TestTextureUtils.cpp b/xbmc/test/TestTextureUtils.cpp index 917eca74ff..c9764ad1f1 100644 --- a/xbmc/test/TestTextureUtils.cpp +++ b/xbmc/test/TestTextureUtils.cpp @@ -35,12 +35,12 @@ typedef struct const char *out; } TestFiles; -const TestFiles test_files[] = {{ "/path/to/image/file.jpg", "", "", "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/" }, - { "/path/to/image/file.jpg", "", "size=thumb", "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/transform?size=thumb" }, - { "/path/to/video/file.mkv", "video", "", "image://video@%2Fpath%2Fto%2Fvideo%2Ffile.mkv/" }, - { "/path/to/music/file.mp3", "music", "", "image://music@%2Fpath%2Fto%2Fmusic%2Ffile.mp3/" }, - { "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/", "", "", "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/" }, - { "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/transform?size=thumb", "", "size=thumb", "image://%2Fpath%2Fto%2Fimage%2Ffile.jpg/transform?size=thumb" }}; +const TestFiles test_files[] = {{ "/path/to/image/file.jpg", "", "", "image://%2fpath%2fto%2fimage%2ffile.jpg/" }, + { "/path/to/image/file.jpg", "", "size=thumb", "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb" }, + { "/path/to/video/file.mkv", "video", "", "image://video@%2fpath%2fto%2fvideo%2ffile.mkv/" }, + { "/path/to/music/file.mp3", "music", "", "image://music@%2fpath%2fto%2fmusic%2ffile.mp3/" }, + { "image://%2fpath%2fto%2fimage%2ffile.jpg/", "", "", "image://%2fpath%2fto%2fimage%2ffile.jpg/" }, + { "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb", "", "size=thumb", "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb" }}; class TestTextureUtils : diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp index feadb00932..84f105f5fe 100644 --- a/xbmc/utils/BitstreamConverter.cpp +++ b/xbmc/utils/BitstreamConverter.cpp @@ -74,6 +74,34 @@ enum { HEVC_NAL_SEI_SUFFIX = 40 }; +enum { + SEI_BUFFERING_PERIOD = 0, + SEI_PIC_TIMING, + SEI_PAN_SCAN_RECT, + SEI_FILLER_PAYLOAD, + SEI_USER_DATA_REGISTERED_ITU_T_T35, + SEI_USER_DATA_UNREGISTERED, + SEI_RECOVERY_POINT, + SEI_DEC_REF_PIC_MARKING_REPETITION, + SEI_SPARE_PIC, + SEI_SCENE_INFO, + SEI_SUB_SEQ_INFO, + SEI_SUB_SEQ_LAYER_CHARACTERISTICS, + SEI_SUB_SEQ_CHARACTERISTICS, + SEI_FULL_FRAME_FREEZE, + SEI_FULL_FRAME_FREEZE_RELEASE, + SEI_FULL_FRAME_SNAPSHOT, + SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START, + SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END, + SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET, + SEI_FILM_GRAIN_CHARACTERISTICS, + SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE, + SEI_STEREO_VIDEO_INFO, + SEI_POST_FILTER_HINTS, + SEI_TONE_MAPPING +}; + + //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// // GStreamer h264 parser @@ -207,55 +235,82 @@ static const uint8_t* avc_find_startcode(const uint8_t *p, const uint8_t *end) return out; } +static bool has_sei_recovery_point(const uint8_t *p, const uint8_t *end) +{ + int pt(0), ps(0), offset(1); + + do + { + pt = 0; + do { + pt += p[offset]; + } while (p[offset++] == 0xFF); + + ps = 0; + do { + ps += p[offset]; + } while (p[offset++] == 0xFF); + + if (pt == SEI_RECOVERY_POINT) + { + nal_bitstream bs; + nal_bs_init(&bs, p + offset, ps); + return nal_bs_read_ue(&bs) >= 0; + } + offset += ps; + } while(p + offset < end && p[offset] != 0x80); + + return false; +} + //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// CBitstreamParser::CBitstreamParser() { } -bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size) +CBitstreamParser::~CBitstreamParser() +{ +} + +bool CBitstreamParser::HasKeyframe(const uint8_t *buf, int buf_size) { if (!buf) return false; bool rtn = false; uint32_t state = -1; - const uint8_t *buf_end = buf + buf_size; + const uint8_t *buf_begin, *buf_end = buf + buf_size; - for(;;) + for(;rtn == false;) { buf = find_start_code(buf, buf_end, &state); if (buf >= buf_end) { - //CLog::Log(LOGDEBUG, "FindIdrSlice: buf(%p), buf_end(%p)", buf, buf_end); break; } - --buf; - int src_length = buf_end - buf; switch (state & 0x1f) { - default: - CLog::Log(LOGDEBUG, "FindIdrSlice: found nal_type(%d)", state & 0x1f); - break; case AVC_NAL_SLICE: - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SLICE"); break; case AVC_NAL_IDR_SLICE: - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_IDR_SLICE"); rtn = true; break; case AVC_NAL_SEI: - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SEI"); + buf_begin = buf - 1; + buf = find_start_code(buf, buf_end, &state) - 4; + if (has_sei_recovery_point(buf_begin, buf)) + rtn = true; break; case AVC_NAL_SPS: - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SPS"); + rtn = true; break; case AVC_NAL_PPS: - CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_PPS"); + break; + default: break; } - buf += src_length; } return rtn; @@ -276,6 +331,7 @@ CBitstreamConverter::CBitstreamConverter() m_convert_3byteTo4byteNALSize = false; m_convert_bytestream = false; m_sps_pps_context.sps_pps_data = NULL; + m_has_keyframe = true; } CBitstreamConverter::~CBitstreamConverter() @@ -355,7 +411,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int // are valid, setup to convert 3 byte NAL sizes to 4 byte. in_extradata[4] = 0xFF; m_convert_3byteTo4byteNALSize = true; - + m_extradata = (uint8_t *)av_malloc(in_extrasize); memcpy(m_extradata, in_extradata, in_extrasize); m_extrasize = in_extrasize; @@ -466,7 +522,7 @@ void CBitstreamConverter::Close(void) bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) { if (m_convertBuffer) - { + { av_free(m_convertBuffer); m_convertBuffer = NULL; } @@ -516,7 +572,7 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize) { m_inputSize = iSize; m_inputBuffer = pData; - + if (m_convert_bytestream) { if(m_convertBuffer) @@ -604,6 +660,16 @@ int CBitstreamConverter::GetExtraSize() const return m_extrasize; } +void CBitstreamConverter::ResetKeyframe(void) +{ + m_has_keyframe = false; +} + +bool CBitstreamConverter::HasKeyframe() const +{ + return m_has_keyframe; +} + bool CBitstreamConverter::BitstreamConvertInitAVC(void *in_extradata, int in_extrasize) { // based on h264_mp4toannexb_bsf.c (ffmpeg) @@ -818,7 +884,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** int i; uint8_t *buf = pData; uint32_t buf_size = iSize; - uint8_t unit_type, nal_sps, nal_pps; + uint8_t unit_type, nal_sps, nal_pps, nal_sei; int32_t nal_size; uint32_t cumul_size = 0; const uint8_t *buf_end = buf + buf_size; @@ -828,10 +894,12 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** case AV_CODEC_ID_H264: nal_sps = AVC_NAL_SPS; nal_pps = AVC_NAL_PPS; + nal_sei = AVC_NAL_SEI; break; case AV_CODEC_ID_HEVC: nal_sps = HEVC_NAL_SPS; nal_pps = HEVC_NAL_PPS; + nal_sei = HEVC_NAL_SEI_PREFIX; break; default: return false; @@ -862,7 +930,10 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t ** if (m_sps_pps_context.first_idr && (unit_type == nal_sps || unit_type == nal_pps)) m_sps_pps_context.idr_sps_pps_seen = 1; - // prepend only to the first access unit of an IDR picture, if no sps/pps already present + if (!m_has_keyframe && (unit_type == nal_sps || IsIDR(unit_type) || (unit_type == nal_sei && has_sei_recovery_point(buf, buf + nal_size)))) + m_has_keyframe = true; + + // prepend only to the first access unit of an IDR picture, if no sps/pps already present if (m_sps_pps_context.first_idr && IsIDR(unit_type) && !m_sps_pps_context.idr_sps_pps_seen) { BitstreamAllocAndCopy(poutbuf, poutbuf_size, diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h index 81e4037473..bdcc3be630 100644 --- a/xbmc/utils/BitstreamConverter.h +++ b/xbmc/utils/BitstreamConverter.h @@ -87,7 +87,9 @@ public: CBitstreamParser(); ~CBitstreamParser(); - static bool FindIdrSlice(const uint8_t *buf, int buf_size); + static bool Open(){}; + static void Close(){}; + static bool HasKeyframe(const uint8_t *buf, int buf_size); }; class CBitstreamConverter @@ -104,6 +106,8 @@ public: int GetConvertSize() const; uint8_t* GetExtraData(void) const; int GetExtraSize() const; + void ResetKeyframe(void); + bool HasKeyframe() const; static void parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames); static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence); @@ -144,4 +148,5 @@ protected: bool m_convert_3byteTo4byteNALSize; bool m_convert_bytestream; AVCodecID m_codec; + bool m_has_keyframe; }; diff --git a/xbmc/utils/Fanart.cpp b/xbmc/utils/Fanart.cpp index 95744448cc..6ed6db142c 100644 --- a/xbmc/utils/Fanart.cpp +++ b/xbmc/utils/Fanart.cpp @@ -46,7 +46,6 @@ void CFanart::Pack() for (std::vector<SFanartData>::const_iterator it = m_fanart.begin(); it != m_fanart.end(); ++it) { TiXmlElement thumb("thumb"); - thumb.SetAttribute("dim", it->strResolution.c_str()); thumb.SetAttribute("colors", it->strColors.c_str()); thumb.SetAttribute("preview", it->strPreview.c_str()); TiXmlText text(it->strImage); @@ -56,6 +55,21 @@ void CFanart::Pack() m_xml << fanart; } +void CFanart::AddFanart(const std::string& image, const std::string& preview, const std::string& colors) +{ + SFanartData info; + info.strPreview = preview; + info.strImage = image; + ParseColors(colors, info.strColors); + m_fanart.push_back(std::move(info)); +} + +void CFanart::Clear() +{ + m_fanart.clear(); + m_xml.clear(); +} + bool CFanart::Unpack() { CXBMCTinyXML doc; @@ -84,7 +98,6 @@ bool CFanart::Unpack() if (fanartThumb->Attribute("preview")) data.strPreview = URIUtils::AddFileToFolder(url, fanartThumb->Attribute("preview")); } - data.strResolution = XMLUtils::GetAttribute(fanartThumb, "dim"); ParseColors(XMLUtils::GetAttribute(fanartThumb, "colors"), data.strColors); m_fanart.push_back(data); } diff --git a/xbmc/utils/Fanart.h b/xbmc/utils/Fanart.h index 040a85124b..d6d2f25d35 100644 --- a/xbmc/utils/Fanart.h +++ b/xbmc/utils/Fanart.h @@ -82,6 +82,10 @@ public: /// Returns how many fanarts are stored /// \return An integer indicating how many fanarts are stored in the class. Fanart indices are 0 to (GetNumFanarts() - 1) unsigned int GetNumFanarts() const; + /// Adds an image to internal fanart data + void AddFanart(const std::string& image, const std::string& preview, const std::string& colors); + /// Clear all internal fanart data + void Clear(); /// /// m_xml contains an XML formatted string which is all fanart packed into one string. /// @@ -107,7 +111,6 @@ private: struct SFanartData { std::string strImage; - std::string strResolution; std::string strColors; std::string strPreview; }; diff --git a/xbmc/utils/Mime.cpp b/xbmc/utils/Mime.cpp index 91234c90da..875148f6d8 100644 --- a/xbmc/utils/Mime.cpp +++ b/xbmc/utils/Mime.cpp @@ -55,6 +55,7 @@ std::map<std::string, std::string> fillMimeTypes() mimeTypes.insert(std::pair<std::string, std::string>("arc", "application/octet-stream")); mimeTypes.insert(std::pair<std::string, std::string>("arj", "application/arj")); mimeTypes.insert(std::pair<std::string, std::string>("art", "image/x-jg")); + mimeTypes.insert(std::pair<std::string, std::string>("arw", "image/arw")); mimeTypes.insert(std::pair<std::string, std::string>("asf", "video/x-ms-asf")); mimeTypes.insert(std::pair<std::string, std::string>("asm", "text/x-asm")); mimeTypes.insert(std::pair<std::string, std::string>("asp", "text/asp")); @@ -91,6 +92,7 @@ std::map<std::string, std::string> fillMimeTypes() mimeTypes.insert(std::pair<std::string, std::string>("cpt", "application/x-cpt")); mimeTypes.insert(std::pair<std::string, std::string>("crl", "application/pkcs-crl")); mimeTypes.insert(std::pair<std::string, std::string>("crt", "application/pkix-cert")); + mimeTypes.insert(std::pair<std::string, std::string>("cr2", "image/cr2")); mimeTypes.insert(std::pair<std::string, std::string>("csh", "application/x-csh")); mimeTypes.insert(std::pair<std::string, std::string>("css", "text/css")); mimeTypes.insert(std::pair<std::string, std::string>("cxx", "text/plain")); @@ -102,6 +104,7 @@ std::map<std::string, std::string> fillMimeTypes() mimeTypes.insert(std::pair<std::string, std::string>("dir", "application/x-director")); mimeTypes.insert(std::pair<std::string, std::string>("dl", "video/dl")); mimeTypes.insert(std::pair<std::string, std::string>("divx", "video/x-msvideo")); + mimeTypes.insert(std::pair<std::string, std::string>("dng", "image/dng")); mimeTypes.insert(std::pair<std::string, std::string>("doc", "application/msword")); mimeTypes.insert(std::pair<std::string, std::string>("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")); mimeTypes.insert(std::pair<std::string, std::string>("dot", "application/msword")); @@ -268,6 +271,7 @@ std::map<std::string, std::string> fillMimeTypes() mimeTypes.insert(std::pair<std::string, std::string>("naplps", "image/naplps")); mimeTypes.insert(std::pair<std::string, std::string>("nc", "application/x-netcdf")); mimeTypes.insert(std::pair<std::string, std::string>("ncm", "application/vnd.nokia.configuration-message")); + mimeTypes.insert(std::pair<std::string, std::string>("nef", "image/nef")); mimeTypes.insert(std::pair<std::string, std::string>("nfo", "text/xml")); mimeTypes.insert(std::pair<std::string, std::string>("nif", "image/x-niff")); mimeTypes.insert(std::pair<std::string, std::string>("niff", "image/x-niff")); diff --git a/xbmc/utils/ScraperUrl.cpp b/xbmc/utils/ScraperUrl.cpp index bf2e09beb3..9eb09c48a6 100644 --- a/xbmc/utils/ScraperUrl.cpp +++ b/xbmc/utils/ScraperUrl.cpp @@ -339,6 +339,43 @@ bool CScraperUrl::ParseEpisodeGuide(std::string strUrls) return true; } +void CScraperUrl::AddElement(std::string url, std::string aspect, std::string referrer, std::string cache, bool post, bool isgz, int season) +{ + TiXmlElement thumb("thumb"); + thumb.SetAttribute("spoof", referrer); + thumb.SetAttribute("cache", cache); + if (post) + thumb.SetAttribute("post", "yes"); + if (isgz) + thumb.SetAttribute("gzip", "yes"); + if (season >= 0) + { + thumb.SetAttribute("season", StringUtils::Format("%i", season)); + thumb.SetAttribute("type", "season"); + } + thumb.SetAttribute("aspect", aspect); + TiXmlText text(url); + thumb.InsertEndChild(text); + m_xml << thumb; + SUrlEntry nUrl; + nUrl.m_url = url; + nUrl.m_spoof = referrer; + nUrl.m_post = post; + nUrl.m_isgz = isgz; + nUrl.m_cache = cache; + if (season >= 0) + { + nUrl.m_type = URL_TYPE_SEASON; + nUrl.m_season = season; + } + else + nUrl.m_type = URL_TYPE_GENERAL; + + nUrl.m_aspect = aspect; + + m_url.push_back(nUrl); +} + std::string CScraperUrl::GetThumbURL(const CScraperUrl::SUrlEntry &entry) { if (entry.m_spoof.empty()) diff --git a/xbmc/utils/ScraperUrl.h b/xbmc/utils/ScraperUrl.h index d9871e8f8f..7fe69b2377 100644 --- a/xbmc/utils/ScraperUrl.h +++ b/xbmc/utils/ScraperUrl.h @@ -58,6 +58,7 @@ public: bool ParseString(std::string); // copies by intention bool ParseElement(const TiXmlElement*); bool ParseEpisodeGuide(std::string strUrls); // copies by intention + void AddElement(std::string url, std::string aspect = "", std::string referrer = "", std::string cache = "", bool post = false, bool isgz = false, int season = -1); const SUrlEntry GetFirstThumb(const std::string &type = "") const; const SUrlEntry GetSeasonThumb(int season, const std::string &type = "") const; diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 06b2068207..76f4c6f750 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -127,7 +127,7 @@ void URIUtils::RemoveExtension(std::string& strFileName) strExtension += "|"; std::string strFileMask; - strFileMask = g_advancedSettings.m_pictureExtensions; + strFileMask = g_advancedSettings.GetPictureExtensions(); strFileMask += "|" + g_advancedSettings.GetMusicExtensions(); strFileMask += "|" + g_advancedSettings.m_videoExtensions; strFileMask += "|" + g_advancedSettings.m_subtitlesExtensions; diff --git a/xbmc/utils/test/TestHttpHeader.cpp b/xbmc/utils/test/TestHttpHeader.cpp index 72a50e1a2f..45c8337858 100644 --- a/xbmc/utils/test/TestHttpHeader.cpp +++ b/xbmc/utils/test/TestHttpHeader.cpp @@ -75,7 +75,7 @@ "\r\n" // local helper function: replace substrings -std::string strReplc(const std::string& str, const std::string& from, const std::string& to) +std::string strReplace(const std::string& str, const std::string& from, const std::string& to) { std::string result; size_t prevPos = 0; @@ -175,14 +175,14 @@ TEST(TestHttpHeader, Parse) EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()); // case-sensitive match of value /* check support for '\n' line endings */ - testHdr.Parse(strReplc(CHECK_HEADER_SMPL, "\r\n", "\n")); + testHdr.Parse(strReplace(CHECK_HEADER_SMPL, "\r\n", "\n")); EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; EXPECT_STRCASEEQ(CHECK_HEADER_SMPL, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header"; EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; - testHdr.Parse(strReplc(CHECK_HEADER_L1, "\r\n", "\n")); + testHdr.Parse(strReplace(CHECK_HEADER_L1, "\r\n", "\n")); EXPECT_STRCASEEQ(CHECK_HEADER_L1, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header"; EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; - testHdr.Parse(strReplc(CHECK_HEADER_L2, "\r\n", "\n")); + testHdr.Parse(strReplace(CHECK_HEADER_L2, "\r\n", "\n")); EXPECT_STRCASEEQ(CHECK_HEADER_L2, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header"; EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; testHdr.Parse(CHECK_PROT_LINE_200 "\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n"); // mixed "\n" and "\r\n" @@ -332,7 +332,7 @@ TEST(TestHttpHeader, Parse_Multiline) EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string"; EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string"; - EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplc(strReplc(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces"; + EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces"; testHdr.Clear(); testHdr.Parse(CHECK_PROT_LINE_200 "\r\n"); @@ -343,7 +343,7 @@ TEST(TestHttpHeader, Parse_Multiline) EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state"; EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string"; EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string"; - EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplc(strReplc(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces"; + EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces"; } TEST(TestHttpHeader, GetValue) diff --git a/xbmc/utils/test/TestURIUtils.cpp b/xbmc/utils/test/TestURIUtils.cpp index 19ab5fe2d5..6b95a6b179 100644 --- a/xbmc/utils/test/TestURIUtils.cpp +++ b/xbmc/utils/test/TestURIUtils.cpp @@ -452,7 +452,7 @@ TEST_F(TestURIUtils, CreateArchivePath) { std::string ref, var; - ref = "zip://%2Fpath%2Fto%2F/file"; + ref = "zip://%2fpath%2fto%2f/file"; var = URIUtils::CreateArchivePath("zip", CURL("/path/to/"), "file").Get(); EXPECT_STREQ(ref.c_str(), var.c_str()); } @@ -546,8 +546,8 @@ TEST_F(TestURIUtils, GetRealPath) EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("rar://%2fpath%2fto%2fsome%2f..%2frar/subpath/to/file").c_str()); // test rar/zip path in rar/zip path - ref ="zip://rar%3A%2F%2F%252Fpath%252Fto%252Frar%2Fpath%2Fto%2Fzip/subpath/to/file"; - EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://rar%3A%2F%2F%252Fpath%252Fto%252Fsome%252F..%252Frar%2Fpath%2Fto%2Fsome%2F..%2Fzip/subpath/to/some/../file").c_str()); + ref ="zip://rar%3a%2f%2f%252Fpath%252Fto%252Frar%2fpath%2fto%2fzip/subpath/to/file"; + EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://rar%3a%2f%2f%252Fpath%252Fto%252Fsome%252F..%252Frar%2fpath%2fto%2fsome%2f..%2fzip/subpath/to/some/../file").c_str()); } TEST_F(TestURIUtils, UpdateUrlEncoding) diff --git a/xbmc/utils/test/TestVariant.cpp b/xbmc/utils/test/TestVariant.cpp index 45ee687758..ad9f089907 100644 --- a/xbmc/utils/test/TestVariant.cpp +++ b/xbmc/utils/test/TestVariant.cpp @@ -236,7 +236,7 @@ TEST(TestVariant, swap) EXPECT_TRUE(a.isString()); } -TEST(TestVariant, interator_array) +TEST(TestVariant, iterator_array) { std::vector<std::string> strarray; strarray.push_back("string"); diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index e33a4392ec..d888d28c41 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -1961,6 +1961,9 @@ bool CVideoDatabase::GetMovieInfo(const std::string& strFilenameAndPath, CVideoI { try { + if (m_pDB == nullptr || m_pDS == nullptr) + return false; + if (idMovie < 0) idMovie = GetMovieId(strFilenameAndPath); if (idMovie < 0) return false; @@ -1983,6 +1986,9 @@ bool CVideoDatabase::GetTvShowInfo(const std::string& strPath, CVideoInfoTag& de { try { + if (m_pDB == nullptr || m_pDS == nullptr) + return false; + if (idTvShow < 0) idTvShow = GetTvShowId(strPath); if (idTvShow < 0) return false; @@ -2048,6 +2054,9 @@ bool CVideoDatabase::GetEpisodeInfo(const std::string& strFilenameAndPath, CVide { try { + if (m_pDB == nullptr || m_pDS == nullptr) + return false; + if (idEpisode < 0) idEpisode = GetEpisodeId(strFilenameAndPath); if (idEpisode < 0) return false; @@ -2069,6 +2078,9 @@ bool CVideoDatabase::GetMusicVideoInfo(const std::string& strFilenameAndPath, CV { try { + if (m_pDB == nullptr || m_pDS == nullptr) + return false; + if (idMVideo < 0) idMVideo = GetMusicVideoId(strFilenameAndPath); if (idMVideo < 0) return false; diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp index 5f8dbf85bc..b3bef3e19f 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp @@ -126,7 +126,7 @@ namespace VIDEO m_itemCount = -1; // Database operations should not be canceled - // using Interupt() while scanning as it could + // using Interrupt() while scanning as it could // result in unexpected behaviour. m_bCanInterrupt = false; @@ -229,7 +229,7 @@ namespace VIDEO void CVideoInfoScanner::Stop() { if (m_bCanInterrupt) - m_database.Interupt(); + m_database.Interrupt(); m_bStop = true; } diff --git a/xbmc/video/VideoInfoTag.cpp b/xbmc/video/VideoInfoTag.cpp index 74bfef9989..79ae1a34ce 100644 --- a/xbmc/video/VideoInfoTag.cpp +++ b/xbmc/video/VideoInfoTag.cpp @@ -1453,7 +1453,10 @@ void CVideoInfoTag::SetOriginalTitle(std::string originalTitle) void CVideoInfoTag::SetEpisodeGuide(std::string episodeGuide) { - m_strEpisodeGuide = Trim(std::move(episodeGuide)); + if (StringUtils::StartsWith(episodeGuide, "<episodeguide")) + m_strEpisodeGuide = Trim(std::move(episodeGuide)); + else + m_strEpisodeGuide = StringUtils::Format("<episodeguide>%s</episodeguide>", Trim(std::move(episodeGuide)).c_str()); } void CVideoInfoTag::SetStatus(std::string status) diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp index 83bed67a32..2d85839d23 100644 --- a/xbmc/video/VideoReferenceClock.cpp +++ b/xbmc/video/VideoReferenceClock.cpp @@ -50,6 +50,9 @@ #if defined(TARGET_ANDROID) #include "video/videosync/VideoSyncAndroid.h" #endif +#if defined(HAS_LIBAMCODEC) +#include "video/videosync/VideoSyncAML.h" +#endif #ifdef TARGET_POSIX #include "linux/XTimeUtils.h" @@ -126,6 +129,8 @@ void CVideoReferenceClock::Process() m_pVideoSync = new CVideoSyncIMX(this); #elif defined(TARGET_ANDROID) m_pVideoSync = new CVideoSyncAndroid(this); +#elif defined(HAS_LIBAMCODEC) + m_pVideoSync = new CVideoSyncAML(this); #endif if (m_pVideoSync) diff --git a/xbmc/video/videosync/CMakeLists.txt b/xbmc/video/videosync/CMakeLists.txt index 82f7169c78..177c656ea6 100644 --- a/xbmc/video/videosync/CMakeLists.txt +++ b/xbmc/video/videosync/CMakeLists.txt @@ -40,6 +40,11 @@ if(IMX_FOUND) list(APPEND HEADERS VideoSyncIMX.h) endif() +if(AML_FOUND) + list(APPEND SOURCES VideoSyncAML.cpp) + list(APPEND HEADERS VideoSyncAML.h) +endif() + if(SOURCES AND HEADERS) core_add_library(video_sync) endif() diff --git a/xbmc/video/videosync/VideoSyncAML.cpp b/xbmc/video/videosync/VideoSyncAML.cpp new file mode 100644 index 0000000000..cd8559e94d --- /dev/null +++ b/xbmc/video/videosync/VideoSyncAML.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2017 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "system.h" + +#if defined(HAS_LIBAMCODEC) + +#include "video/videosync/VideoSyncAML.h" +#include "guilib/GraphicContext.h" +#include "windowing/WindowingFactory.h" +#include "utils/TimeUtils.h" +#include "utils/log.h" +#include "threads/Thread.h" +#include <sys/poll.h> + +#include <chrono> +#include <thread> + +extern CEvent g_aml_sync_event; + +CVideoSyncAML::CVideoSyncAML(CVideoReferenceClock *clock) +: CVideoSync(clock) +, m_abort(false) +{ +} + +CVideoSyncAML::~CVideoSyncAML() +{ +} + +bool CVideoSyncAML::Setup(PUPDATECLOCK func) +{ + UpdateClock = func; + + m_abort = false; + + g_Windowing.Register(this); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up AML"); + + return true; +} + +void CVideoSyncAML::Run(std::atomic<bool>& stop) +{ + // We use the wall clock for timout handling (no AML h/w, startup) + std::chrono::time_point<std::chrono::system_clock> now(std::chrono::system_clock::now()); + unsigned int waittime (3000 / m_fps); + uint64_t numVBlanks (0); + + while (!stop && !m_abort) + { + int countVSyncs(1); + if( !g_aml_sync_event.WaitMSec(waittime)) + { + std::chrono::milliseconds elapsed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now).count()); + uint64_t curVBlanks = (m_fps * elapsed.count()) / 1000; + int64_t lastVBlankTime((curVBlanks * 1000) / m_fps); + if (elapsed.count() > lastVBlankTime) + { + lastVBlankTime = (++curVBlanks * 1000) / m_fps; + std::this_thread::sleep_for(std::chrono::milliseconds(lastVBlankTime - elapsed.count())); + } + countVSyncs = curVBlanks - numVBlanks; + numVBlanks = curVBlanks; + } + else + ++numVBlanks; + + uint64_t now = CurrentHostCounter(); + + UpdateClock(countVSyncs, now, m_refClock); + } +} + +void CVideoSyncAML::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up AML"); + g_Windowing.Unregister(this); +} + +float CVideoSyncAML::GetFps() +{ + m_fps = g_graphicsContext.GetFPS(); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.3f", m_fps); + return m_fps; +} + +void CVideoSyncAML::OnResetDisplay() +{ + m_abort = true; +} + +#endif diff --git a/xbmc/video/videosync/VideoSyncAML.h b/xbmc/video/videosync/VideoSyncAML.h new file mode 100644 index 0000000000..f12230ea90 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncAML.h @@ -0,0 +1,41 @@ +#pragma once +/* + * Copyright (C) 2017 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#if defined(HAS_LIBAMCODEC) + +#include "video/videosync/VideoSync.h" +#include "guilib/DispResource.h" + +class CVideoSyncAML : public CVideoSync, IDispResource +{ +public: + CVideoSyncAML(CVideoReferenceClock *clock); + virtual ~CVideoSyncAML(); + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(std::atomic<bool>& stop); + virtual void Cleanup(); + virtual float GetFps(); + virtual void OnResetDisplay(); +private: + volatile bool m_abort; +}; + +#endif diff --git a/xbmc/windowing/X11/CMakeLists.txt b/xbmc/windowing/X11/CMakeLists.txt index 5cdac0c6fa..6d2527d563 100644 --- a/xbmc/windowing/X11/CMakeLists.txt +++ b/xbmc/windowing/X11/CMakeLists.txt @@ -1,17 +1,21 @@ -set(SOURCES GLContextEGL.cpp - GLContextGLX.cpp - GLContext.cpp - WinSystemX11.cpp - WinSystemX11GLContext.cpp - WinSystemX11GLESContext.cpp - XRandR.cpp) +if (X_FOUND) -set(HEADERS GLContext.h - GLContextEGL.h - GLContextGLX.h - WinSystemX11.h - WinSystemX11GLContext.h - WinSystemX11GLESContext.h - XRandR.h) + set(SOURCES GLContextEGL.cpp + GLContextGLX.cpp + GLContext.cpp + WinSystemX11GLContext.cpp + WinSystemX11GLESContext.cpp + XRandR.cpp + WinSystemX11.cpp) -core_add_library(windowing_X11) + set(HEADERS GLContext.h + GLContextEGL.h + GLContextGLX.h + WinSystemX11GLContext.h + WinSystemX11GLESContext.h + XRandR.h + WinSystemX11.h) + + core_add_library(windowing_X11) + +endif() diff --git a/xbmc/windowing/windows/WinSystemWin32DX.h b/xbmc/windowing/windows/WinSystemWin32DX.h index dc32ad28a8..e872f9e79f 100644 --- a/xbmc/windowing/windows/WinSystemWin32DX.h +++ b/xbmc/windowing/windows/WinSystemWin32DX.h @@ -42,7 +42,7 @@ public: virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays); virtual bool WindowedMode() { return CRenderSystemDX::m_useWindowedDX; } virtual void NotifyAppFocusChange(bool bGaining); - virtual void PresentRender(bool rendererd, bool videoLayer); + virtual void PresentRender(bool rendered, bool videoLayer); std::string GetClipboardText(void); diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp index 81a0629325..45deff8cec 100644 --- a/xbmc/windows/GUIMediaWindow.cpp +++ b/xbmc/windows/GUIMediaWindow.cpp @@ -490,7 +490,10 @@ bool CGUIMediaWindow::OnMessage(CGUIMessage& message) resetHistory = true; } if (resetHistory) + { + m_vecItems->RemoveDiscCache(GetID()); SetHistoryForPath(m_vecItems->GetPath()); + } } if (message.GetParam1() != WINDOW_INVALID) { // first time to this window - make sure we set the root path @@ -498,7 +501,7 @@ bool CGUIMediaWindow::OnMessage(CGUIMessage& message) } if (message.GetParam2() == PLUGIN_REFRESH_DELAY) { - Refresh(true); + Refresh(); SetInitialVisibility(); RestoreControlStates(); SetInitialVisibility(); |