From f3cde16786eae9cfdfe591cfc626c27770d7b594 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 14:55:07 -0400 Subject: [PATCH 01/10] update listviews --- .../emby-webcomponents/.bower.json | 8 +- .../emby-itemscontainer.js | 90 ++++++++++- .../emby-webcomponents/itemcontextmenu.js | 12 +- .../emby-webcomponents/listview/listview.js | 7 +- .../emby-webcomponents/mediainfo/mediainfo.js | 4 +- .../emby-webcomponents/shortcuts.js | 30 +++- .../emby-webcomponents/strings/da.json | 2 + .../emby-webcomponents/strings/de.json | 2 + .../emby-webcomponents/strings/es-MX.json | 2 + .../emby-webcomponents/strings/fr.json | 116 +++++++++++++++ .../emby-webcomponents/strings/kk.json | 38 ++--- .../emby-webcomponents/strings/nb.json | 2 + .../emby-webcomponents/strings/nl.json | 2 + .../emby-webcomponents/strings/pt-BR.json | 2 + .../emby-webcomponents/strings/pt-PT.json | 2 + .../emby-webcomponents/strings/ru.json | 38 ++--- .../emby-webcomponents/strings/sv.json | 38 ++--- .../emby-webcomponents/strings/zh-TW.json | 2 + dashboard-ui/channelitems.html | 2 +- dashboard-ui/channels.html | 2 +- dashboard-ui/components/favoriteitems.js | 7 +- .../metadataeditor/metadataeditor.js | 2 + dashboard-ui/components/remotecontrol.js | 3 - dashboard-ui/home.html | 2 +- dashboard-ui/itemdetails.html | 4 +- dashboard-ui/livetv.html | 16 +- dashboard-ui/livetvitems.html | 2 +- dashboard-ui/movies.html | 8 +- dashboard-ui/music.html | 12 +- dashboard-ui/scripts/channelitems.js | 2 +- dashboard-ui/scripts/channels.js | 2 +- dashboard-ui/scripts/homenextup.js | 2 +- dashboard-ui/scripts/homeupcoming.js | 7 +- dashboard-ui/scripts/itembynamedetailpage.js | 1 - dashboard-ui/scripts/itemdetailpage.js | 13 +- dashboard-ui/scripts/librarybrowser.js | 4 +- dashboard-ui/scripts/librarylist.js | 140 +----------------- dashboard-ui/scripts/livetvchannels.js | 2 +- dashboard-ui/scripts/livetvitems.js | 2 +- dashboard-ui/scripts/livetvrecordings.js | 1 - dashboard-ui/scripts/livetvsuggested.js | 3 +- dashboard-ui/scripts/moviesrecommended.js | 10 +- dashboard-ui/scripts/musicrecommended.js | 4 +- dashboard-ui/scripts/playlistedit.js | 1 - dashboard-ui/scripts/searchpage.js | 7 +- dashboard-ui/scripts/sections.js | 47 ++---- dashboard-ui/scripts/site.js | 7 +- dashboard-ui/scripts/tvrecommended.js | 4 +- dashboard-ui/scripts/tvupcoming.js | 7 +- dashboard-ui/search.html | 2 +- dashboard-ui/tv.html | 10 +- 51 files changed, 402 insertions(+), 333 deletions(-) create mode 100644 dashboard-ui/bower_components/emby-webcomponents/strings/fr.json diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index 4480485a4..e9c2692cc 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -15,12 +15,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.91", - "_release": "1.4.91", + "version": "1.4.93", + "_release": "1.4.93", "_resolution": { "type": "version", - "tag": "1.4.91", - "commit": "a4c5466d5a59e57b157aa941fcadb1e0df602f75" + "tag": "1.4.93", + "commit": "8b6b445547b02a088fbafed08120ed87c4004df5" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.0", diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js index 751c12149..356375824 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js @@ -1,4 +1,4 @@ -define(['itemShortcuts', 'connectionManager', 'registerElement'], function (itemShortcuts, connectionManager) { +define(['itemShortcuts', 'connectionManager', 'layoutManager', 'browser', 'registerElement'], function (itemShortcuts, connectionManager, layoutManager, browser) { var ItemsContainerProtoType = Object.create(HTMLDivElement.prototype); @@ -85,23 +85,99 @@ function onClick(e) { var itemsContainer = this; + var target = e.target; - var menuButton = parentWithClass(e.target, 'menuButton'); + var menuButton = parentWithClass(target, 'menuButton'); if (menuButton) { - showContextMenu(menuButton, itemsContainer); - e.stopPropagation(); - return false; + var card = parentWithAttribute(target, 'data-id'); + if (card) { + showContextMenu(card, target); + e.stopPropagation(); + return false; + } } + + itemShortcuts.onClick.call(this, e); + } + + function disableEvent(e) { + + e.preventDefault(); + e.stopPropagation(); + return false; + } + + function showContextMenu(card, target, options) { + + var itemId = card.getAttribute('data-id'); + var serverId = card.getAttribute('data-serverid'); + var type = card.getAttribute('data-type'); + + var apiClient = connectionManager.getApiClient(serverId); + + var promise = type == 'Timer' ? apiClient.getLiveTvTimer(itemId) : apiClient.getItem(apiClient.getCurrentUserId(), itemId); + + promise.then(function (item) { + + require(['itemContextMenu'], function (itemContextMenu) { + + itemContextMenu.show(Object.assign(options || {}, { + item: item, + positionTo: target + })); + }); + }); + } + + function onContextMenu(e) { + + var itemsContainer = this; + + var target = e.target; + var card = parentWithAttribute(target, 'data-id'); + if (card) { + + //var itemSelectionPanel = card.querySelector('.itemSelectionPanel'); + + //if (!itemSelectionPanel) { + // showContextMenu(card, {}); + //} + + showContextMenu(card, target, { + identify: false + }); + } + + e.preventDefault(); + e.stopPropagation(); + return false; + } + + function getShortcutOptions() { + return { + click: false + }; } ItemsContainerProtoType.attachedCallback = function () { this.addEventListener('click', onClick); - itemShortcuts.on(this); + + // mobile safari doesn't allow contextmenu override + if (browser.safari && browser.mobile) { + this.addEventListener('contextmenu', disableEvent); + // todo: use tap hold + } else { + this.addEventListener('contextmenu', onContextMenu); + } + + itemShortcuts.on(this, getShortcutOptions()); }; ItemsContainerProtoType.detachedCallback = function () { this.removeEventListener('click', onClick); - itemShortcuts.off(this); + this.removeEventListener('contextmenu', onContextMenu); + this.removeEventListener('contextmenu', disableEvent); + itemShortcuts.off(this, getShortcutOptions()); }; document.registerElement('emby-itemscontainer', { diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js index 8d8afc075..a3e00bab2 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js +++ b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js @@ -39,20 +39,24 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter', }); } - if (options.edit !== false) { - if (itemHelper.canEdit(user, item.Type)) { + if (itemHelper.canEdit(user, item.Type)) { - if (!isTheater) { + if (!isTheater) { + if (options.edit !== false) { commands.push({ name: globalize.translate('sharedcomponents#EditInfo'), id: 'edit' }); + } + if (options.editImages !== false) { commands.push({ name: globalize.translate('sharedcomponents#EditImages'), id: 'editimages' }); } - if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual') { + } + if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual') { + if (options.editSubtitles !== false) { commands.push({ name: globalize.translate('sharedcomponents#EditSubtitles'), id: 'editsubtitles' diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js index a2d52f8ed..947959be6 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js @@ -282,7 +282,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan html += ''; if (enableSideMediaInfo) { - html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item) + '
'; + html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item, { + + year: false, + container: false + + }) + '
'; } if (!clickEntireItem) { diff --git a/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js b/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js index 77e78850e..449da26ff 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js +++ b/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.js @@ -125,7 +125,7 @@ define(['datetime', 'globalize', 'embyRouter', 'material-icons', 'css!./mediainf } } - if (item.ProductionYear && item.Type == "Series") { + if (options.year !== false && item.ProductionYear && item.Type == "Series") { if (item.Status == "Continuing") { miscInfo.push(globalize.translate('sharedcomponents#ValueSeriesYearToPresent', item.ProductionYear)); @@ -237,7 +237,7 @@ define(['datetime', 'globalize', 'embyRouter', 'material-icons', 'css!./mediainf miscInfo.push(item.Width + "x" + item.Height); } - if (item.Type == 'Audio' && item.Container) { + if (options.container !== false && item.Type == 'Audio' && item.Container) { miscInfo.push(item.Container); } diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js index 3138b5ec9..6b9fc7a74 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js +++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js @@ -235,6 +235,10 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g if (action) { executeAction(card, action); + + e.preventDefault(); + e.stopPropagation(); + return false; } } } @@ -277,20 +281,34 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } } - function on(context) { - context.addEventListener('click', onClick); - inputManager.on(context, onCommand); + function on(context, options) { + + options = options || {}; + + if (options.click !== false) { + context.addEventListener('click', onClick); + } + + if (options.command !== false) { + inputManager.on(context, onCommand); + } } - function off(context) { + function off(context, options) { + options = options || {}; + context.removeEventListener('click', onClick); - inputManager.off(context, onCommand); + + if (options.command !== false) { + inputManager.off(context, onCommand); + } } return { on: on, off: off, - execute: executeAction + execute: executeAction, + onClick: onClick }; }); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/da.json b/dashboard-ui/bower_components/emby-webcomponents/strings/da.json index c536180e8..651c8b85f 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/da.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/da.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Special - {0}", "Share": "Del", "ServerUpdateNeeded": "Denne Emby server b\u00f8r opdateres. For at downloade den nyeste version bes\u00f8g venligst {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/de.json b/dashboard-ui/bower_components/emby-webcomponents/strings/de.json index c2601c782..3ca2976be 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/de.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/de.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Special - {0}", "Share": "Teilen", "ServerUpdateNeeded": "Dieser Emby Server sollte aktualisiert werden. Um die neueste Version zu laden, besuche bitte {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json b/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json index c89a81249..e694d49f1 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Compartir", "ServerUpdateNeeded": "Este Servidor Emby necesita ser actualizado. Para descargar la ultima versi\u00f3n, por favor visite {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json b/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json new file mode 100644 index 000000000..9bb888d92 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json @@ -0,0 +1,116 @@ +{ + "EditInfo": "Modifier les informations", + "RemoveFromPlaylist": "Supprimer de la liste de lecture", + "ValueSpecialEpisodeName": "Sp\u00e9cial - {0}", + "Share": "Partager", + "ServerUpdateNeeded": "Le serveur Emby doit \u00eatre mis \u00e0 jour. Pour t\u00e9l\u00e9charger la derni\u00e8re version, veuillez visiter {0}", + "LiveTvGuideRequiresUnlock": "Le Guide TV en direct est actuellement limit\u00e9 \u00e0 {0} cha\u00eenes. Cliquez sur le bouton d\u00e9verrouiller pour d\u00e9couvrir comment profiter de l'ensemble.", + "AttributeNew": "Nouveau", + "AttributePremiere": "Premiere", + "AttributeLive": "Direct", + "TrackCount": "{0} pistes", + "ItemCount": "{0} \u00e9l\u00e9ments", + "ValueSeriesYearToPresent": "{0}-Pr\u00e9sent", + "ReleaseYearValue": "Ann\u00e9e de sortie: {0}", + "OriginalAirDateValue": "Date de diffusion originale: {0}", + "EndsAtValue": "Se termine \u00e0 {0}", + "OptionSundayShort": "Dim", + "OptionMondayShort": "Lun", + "OptionTuesdayShort": "Mar", + "OptionWednesdayShort": "Mer", + "OptionThursdayShort": "Jeu", + "OptionFridayShort": "Ven", + "OptionSaturdayShort": "Sam", + "HeaderSelectDate": "S\u00e9lectionnez la date", + "ButtonOk": "Ok", + "ButtonCancel": "Annuler", + "ButtonGotIt": "Compris", + "RecordingCancelled": "Enregistrement annul\u00e9.", + "RecordingScheduled": "Enregistrement planifi\u00e9.", + "SeriesRecordingScheduled": "Enregistrement de la s\u00e9rie pr\u00e9vue.", + "HeaderNewRecording": "Nouvel enregistrement", + "Sunday": "Dimanche", + "Monday": "Lundi", + "Tuesday": "Mardi", + "Wednesday": "Mercredi", + "Thursday": "Jeudi", + "Friday": "Vendredi", + "Saturday": "Samedi", + "Days": "Jours", + "RecordSeries": "Enregistrer s\u00e9ries", + "LabelPrePaddingMinutes": "D\u00e9lai avant l'enregistrement en minutes:", + "LabelPostPaddingMinutes": "D\u00e9lai apr\u00e8s l'enregistrement en minutes:", + "RecordOnAllChannels": "Enregistrer sur toutes les cha\u00eenes", + "RecordAnytime": "Enregistrer \u00e0 n'importe quelle heure\/journ\u00e9e", + "RecordOnlyNewEpisodes": "Enregistrer seulement les nouveaux \u00e9pisodes", + "HeaderBecomeProjectSupporter": "Obtenez Emby Premiere", + "HeaderEnjoyDayTrial": "Profitez d'une p\u00e9riode d'essai de 14 jours", + "MessageActiveSubscriptionRequiredSeriesRecordings": "Une souscription Emby Premiere active est n\u00e9cessaire pour cr\u00e9er des enregistrements automatiques de s\u00e9ries.", + "OptionConvertRecordingsToStreamingFormat": "Convertir automatiquement les enregistrements a un format facilement diffusable.", + "OptionConvertRecordingsToStreamingFormatHelp": "Les enregistrements seront convertis \u00e0 la vol\u00e9e en MP4 afin faciliter la lecture sur tous vos appareils.", + "FeatureRequiresEmbyPremiere": "Cette fonctionnalit\u00e9 requiert un compte Emby Premiere.", + "Record": "Enregistrer", + "Save": "Sauvegarder", + "Edit": "Modifier", + "Download": "T\u00e9l\u00e9chargement", + "Advanced": "Avanc\u00e9", + "Delete": "Supprimer", + "HeaderDeleteItem": "Supprimer l'\u00e9l\u00e9ment", + "ConfirmDeleteItem": "Supprimer cet \u00e9l\u00e9ment l'effacera \u00e0 la fois du syst\u00e8me de fichiers et de votre biblioth\u00e8que de medias. Etes-vous s\u00fbr de vouloir continuer ?", + "Refresh": "Actualiser", + "RefreshQueued": "Demande d'actualisation en file d'attente.", + "AddToCollection": "Ajouter \u00e0 la collection", + "NewCollection": "Nouvelle collection", + "LabelCollection": "Collection:", + "Help": "Aide", + "NewCollectionHelp": "Les Collections vous permettent de cr\u00e9er des groupes personnalis\u00e9s de films et autres contenus.", + "SearchForCollectionInternetMetadata": "Rechercher sur Internet les images et m\u00e9tadonn\u00e9es", + "LabelName": "Nom:", + "NewCollectionNameExample": "Exemple: Collection Star Wars", + "MessageItemsAdded": " \u00c9l\u00e9ments ajout\u00e9s.", + "OptionNew": "Nouveau...", + "LabelPlaylist": "Liste de lecture:", + "AddToPlaylist": "Ajouter \u00e0 la liste de lecture", + "Subtitles": "Sous-titres", + "SearchForSubtitles": "Rechercher des sous-titres", + "LabelLanguage": "Langue:", + "Search": "Recherche", + "NoSubtitleSearchResultsFound": "Aucun appareil trouv\u00e9", + "File": "Fichier", + "MessageAreYouSureDeleteSubtitles": "\u00cates-vous s\u00fbr de vouloir supprimer ce fichier sous-titres ?", + "ConfirmDeletion": "Confirmer la suppression", + "MySubtitles": "Mes Sous-titres", + "MessageDownloadQueued": "T\u00e9l\u00e9charger en file d'attente.", + "EditSubtitles": "Modifier les sous-titres", + "UnlockGuide": "D\u00e9verrouiller le Guide", + "RefreshMetadata": "Actualiser les m\u00e9tadonn\u00e9es", + "ReplaceExistingImages": "Remplacer les images existantes", + "ReplaceAllMetadata": "Remplacer toutes les m\u00e9tadonn\u00e9es", + "SearchForMissingMetadata": "Rechercher les m\u00e9tadonn\u00e9es manquantes", + "LabelRefreshMode": "Mode de rafra\u00eechissement:", + "NoItemsFound": "Aucun \u00e9l\u00e9ment trouv\u00e9.", + "HeaderSaySomethingLike": "Dites quelque chose...", + "ButtonTryAgain": "Veuillez r\u00e9essayer", + "HeaderYouSaid": "Vous avez dit...", + "MessageWeDidntRecognizeCommand": "D\u00e9sol\u00e9, cette commande n'a pas \u00e9t\u00e9 reconnue.", + "MessageIfYouBlockedVoice": "Si vous avez supprim\u00e9 l'acc\u00e8s par commande vocale \u00e0 l'application, vous devrez reconfigurer avant de r\u00e9essayer.", + "ValueDiscNumber": "Disque {0}", + "Unrated": "Non not\u00e9", + "Favorite": "Favoris", + "Like": "J'aime", + "Dislike": "Je n'aime pas", + "Played": "Lu", + "RefreshDialogHelp": "Les m\u00e9tadonn\u00e9es sont actualis\u00e9es en fonction des param\u00e8tres et des services internet qui sont activ\u00e9s dans le tableau de bord Emby Server.", + "Open": "Ouvrir", + "Play": "Lire", + "Queue": "File d'attente", + "Shuffle": "Lecture al\u00e9atoire", + "Identify": "Identifier", + "EditImages": "Modifier les images", + "Sync": "Sync", + "InstantMix": "Mix instantan\u00e9", + "ViewAlbum": "Voir l'album", + "ViewArtist": "Voir l'artiste", + "QueueAllFromHere": "Tout mette en file d'attente \u00e0 partir d'ici", + "PlayAllFromHere": "Tout lire \u00e0 partir d'ici" +} \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json b/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json index da34f0b3d..0c31cf557 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "\u0410\u0440\u043d\u0430\u0439\u044b - {0}", "Share": "\u041e\u0440\u0442\u0430\u049b\u0442\u0430\u0441\u0443", "ServerUpdateNeeded": "\u041e\u0441\u044b Emby Server \u0436\u0430\u04a3\u0430\u0440\u0442\u044b\u043b\u0443\u044b \u049b\u0430\u0436\u0435\u0442. \u0421\u043e\u04a3\u0493\u044b \u043d\u04b1\u0441\u049b\u0430\u0441\u044b\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443 \u04af\u0448\u0456\u043d, {0} \u043a\u0456\u0440\u0456\u04a3\u0456\u0437", @@ -92,23 +94,23 @@ "HeaderYouSaid": "\u0421\u0456\u0437 \u0430\u0439\u0442\u049b\u0430\u043d\u044b\u04a3\u044b\u0437...", "MessageWeDidntRecognizeCommand": "\u041e\u0441\u044b\u043d\u0434\u0430\u0439 \u043f\u04d9\u0440\u043c\u0435\u043d\u0434\u0456 \u0442\u0430\u043d\u044b\u043f \u0430\u0439\u044b\u0440\u043c\u0430\u0434\u044b\u049b.", "MessageIfYouBlockedVoice": "\u0415\u0433\u0435\u0440 \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u0493\u0430 \u0434\u0430\u0443\u044b\u0441\u0442\u044b\u049b \u049b\u0430\u0442\u044b\u043d\u0430\u0443\u044b\u04a3\u044b\u0437 \u0431\u0430\u0441 \u0442\u0430\u0440\u0442\u044b\u043b\u0441\u0430, \u049b\u0430\u0439\u0442\u0430 \u04d9\u0440\u0435\u043a\u0435\u0442\u0442\u0435\u043d\u0443\u0456\u04a3\u0456\u0437\u0434\u0435\u043d \u0430\u043b\u0434\u044b\u043d\u0430\u043d \u049b\u0430\u0439\u0442\u0430 \u0442\u0435\u04a3\u0448\u0435\u0443\u0456\u04a3\u0456\u0437 \u049b\u0430\u0436\u0435\u0442 \u0431\u043e\u043b\u0430\u0434\u044b.", - "ValueDiscNumber": "Disc {0}", - "Unrated": "Unrated", - "Favorite": "Favorite", - "Like": "Like", - "Dislike": "Dislike", - "Played": "Played", + "ValueDiscNumber": "{0}-\u0434\u0438\u0441\u043a\u0456", + "Unrated": "\u0411\u0430\u0493\u0430\u043b\u0430\u043d\u0431\u0430\u0493\u0430\u043d", + "Favorite": "\u0422\u0430\u04a3\u0434\u0430\u0443\u043b\u044b", + "Like": "\u04b0\u043d\u0430\u0439\u0434\u044b", + "Dislike": "\u04b0\u043d\u0430\u043c\u0430\u0439\u0434\u044b", + "Played": "\u041e\u0439\u043d\u0430\u0442\u044b\u043b\u0493\u0430\u043d", "RefreshDialogHelp": "\u041c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440 \u043c\u0435\u043d Emby Server \u0431\u0430\u049b\u044b\u043b\u0430\u0443 \u0442\u0430\u049b\u0442\u0430\u0441\u044b\u043d\u0434\u0430 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u049b\u044b\u0437\u043c\u0435\u0442\u0442\u0435\u0440\u0456 \u043d\u0435\u0433\u0456\u0437\u0456\u043d\u0434\u0435 \u0436\u0430\u04a3\u0493\u044b\u0440\u0442\u044b\u043b\u0430\u0434\u044b.", - "Open": "Open", - "Play": "Play", - "Queue": "Queue", - "Shuffle": "Shuffle", - "Identify": "Identify", - "EditImages": "Edit Images", - "Sync": "Sync", - "InstantMix": "Instant Mix", - "ViewAlbum": "View Album", - "ViewArtist": "View Artist", - "QueueAllFromHere": "Queue All from Here", - "PlayAllFromHere": "Play All from Here" + "Open": "\u0410\u0448\u0443", + "Play": "\u041e\u0439\u043d\u0430\u0442\u0443", + "Queue": "\u041a\u0435\u0437\u0435\u043a", + "Shuffle": "\u0410\u0440\u0430\u043b\u0430\u0441\u0442\u044b\u0440\u0443", + "Identify": "\u0410\u043d\u044b\u049b\u0442\u0430\u0443", + "EditImages": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u0440\u0434\u0456 \u04e9\u04a3\u0434\u0435\u0443", + "Sync": "\u04ae\u043d\u0434\u0435\u0441\u0442\u0456\u0440\u0443", + "InstantMix": "\u041b\u0435\u0437\u0434\u0456\u043a \u049b\u043e\u0441\u043f\u0430", + "ViewAlbum": "\u0410\u043b\u044c\u0431\u043e\u043c\u0434\u044b \u049b\u0430\u0440\u0430\u0443", + "ViewArtist": "\u041e\u0440\u044b\u043d\u0434\u0430\u0443\u0448\u044b\u043d\u044b \u049b\u0430\u0440\u0430\u0443", + "QueueAllFromHere": "\u0411\u04b1\u043b \u0430\u0440\u0430\u0434\u0430\u043d \u0431\u04d9\u0440\u0456\u043d \u043a\u0435\u0437\u0435\u043a\u043a\u0435", + "PlayAllFromHere": "\u0411\u04b1\u043b \u0430\u0440\u0430\u0434\u0430\u043d \u0431\u04d9\u0440\u0456\u043d \u043e\u0439\u043d\u0430\u0442\u0443" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json b/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json index 4f250fabd..72f9bc396 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Spesial - {0}", "Share": "Del", "ServerUpdateNeeded": "Denne Emby serveren trenger en oppdatering. For \u00e5 laste ned nyeste versjon, vennligst bes\u00f8k: {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json b/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json index 2724e702d..4a47303eb 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Speciaal - {0}", "Share": "Delen", "ServerUpdateNeeded": "Deze Emby Server moet worden bijgewerkt. Om de laatste versie te downloaden, gaat u naar {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json index e658df31c..ba4c52271 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Compartilhar", "ServerUpdateNeeded": "Este servidor Emby precisa ser atualizado. Para baixar a \u00faltima vers\u00e3o, por favor visite {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json index 96464ac69..1d2dbd582 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Partilhar", "ServerUpdateNeeded": "Este Servidor Emby precisa ser atualizado. Para fazer download da vers\u00e3o mais recente, por favor visite {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json b/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json index 4c9e62a2c..7996aa017 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "\u0421\u043f\u0435\u0446\u044d\u043f\u0438\u0437\u043e\u0434 - {0}", "Share": "\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f", "ServerUpdateNeeded": "\u0414\u0430\u043d\u043d\u044b\u0439 Emby Server \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 {0}", @@ -92,23 +94,23 @@ "HeaderYouSaid": "\u0412\u044b \u0441\u043a\u0430\u0437\u0430\u043b\u0438...", "MessageWeDidntRecognizeCommand": "\u0414\u0430\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u0430.", "MessageIfYouBlockedVoice": "\u0415\u0441\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u043f\u0435\u0440\u0435\u0434 \u043d\u043e\u0432\u043e\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u043e\u0439 \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430.", - "ValueDiscNumber": "Disc {0}", - "Unrated": "Unrated", - "Favorite": "Favorite", - "Like": "Like", - "Dislike": "Dislike", - "Played": "Played", + "ValueDiscNumber": "\u0414\u0438\u0441\u043a {0}", + "Unrated": "\u0411\u0435\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438", + "Favorite": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435", + "Like": "\u041d\u0440\u0430\u0432\u0438\u0442\u0441\u044f", + "Dislike": "\u041d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f", + "Played": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435", "RefreshDialogHelp": "\u041f\u043e\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u0438\u043d\u0444\u043e\u043f\u0430\u043d\u0435\u043b\u0438 Emby Server \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0443\u0441\u043b\u0443\u0433\u0430\u043c\u0438.", - "Open": "Open", - "Play": "Play", - "Queue": "Queue", - "Shuffle": "Shuffle", - "Identify": "Identify", - "EditImages": "Edit Images", - "Sync": "Sync", - "InstantMix": "Instant Mix", - "ViewAlbum": "View Album", - "ViewArtist": "View Artist", - "QueueAllFromHere": "Queue All from Here", - "PlayAllFromHere": "Play All from Here" + "Open": "\u041e\u0442\u043a\u0440\u044b\u0442\u044c", + "Play": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438", + "Queue": "\u041e\u0447\u0435\u0440\u0435\u0434\u044c", + "Shuffle": "\u041f\u0435\u0440\u0435\u043c\u0435\u0448\u0430\u0442\u044c", + "Identify": "\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c", + "EditImages": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043a\u0438", + "Sync": "\u0421\u0438\u043d\u0445\u0440\u043e", + "InstantMix": "\u0410\u0432\u0442\u043e\u043c\u0438\u043a\u0441", + "ViewAlbum": "\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0430\u043b\u044c\u0431\u043e\u043c", + "ViewArtist": "\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f", + "QueueAllFromHere": "\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432\u0441\u0435 \u043e\u0442\u0441\u044e\u0434\u0430", + "PlayAllFromHere": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043e\u0442\u0441\u044e\u0434\u0430" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json b/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json index 8242707c4..be0c522e8 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Specialavsnitt - {0}", "Share": "Dela", "ServerUpdateNeeded": "Den h\u00e4r Emby servern beh\u00f6ver uppdateras. F\u00f6r att ladda ner senaste versionen, g\u00e5 till {0}", @@ -92,23 +94,23 @@ "HeaderYouSaid": "Du sa...", "MessageWeDidntRecognizeCommand": "Ledsen, men vi k\u00e4nner inte igen det kommandot.", "MessageIfYouBlockedVoice": "Om du nekade tillg\u00e5ng f\u00f6r r\u00f6st\u00e5tkomst till appen s\u00e5 beh\u00f6ver du konfigurera om innan du f\u00f6rs\u00f6ker igen.", - "ValueDiscNumber": "Disc {0}", - "Unrated": "Unrated", - "Favorite": "Favorite", - "Like": "Like", - "Dislike": "Dislike", - "Played": "Played", + "ValueDiscNumber": "Skiva {0}", + "Unrated": "Ej klassad", + "Favorite": "Favorit", + "Like": "Gilla", + "Dislike": "Ogilla", + "Played": "Visad", "RefreshDialogHelp": "Metadata uppdateras baserat p\u00e5 inst\u00e4llningar och internettj\u00e4nster som har aktiverats under Emby servers kontrollpanel.", - "Open": "Open", - "Play": "Play", - "Queue": "Queue", - "Shuffle": "Shuffle", - "Identify": "Identify", - "EditImages": "Edit Images", - "Sync": "Sync", - "InstantMix": "Instant Mix", - "ViewAlbum": "View Album", - "ViewArtist": "View Artist", - "QueueAllFromHere": "Queue All from Here", - "PlayAllFromHere": "Play All from Here" + "Open": "\u00d6ppna", + "Play": "Spela", + "Queue": "K\u00f6a", + "Shuffle": "Blanda", + "Identify": "Identifiera", + "EditImages": "\u00c4ndra bilder", + "Sync": "Synk", + "InstantMix": "Instant mix", + "ViewAlbum": "Bl\u00e4ddra album", + "ViewArtist": "Bl\u00e4ddra artist", + "QueueAllFromHere": "K\u00f6a alla h\u00e4rifr\u00e5n", + "PlayAllFromHere": "Spela upp alla h\u00e4rifr\u00e5n" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json b/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json index 2b90b06e1..6db832b5a 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json @@ -1,4 +1,6 @@ { + "EditInfo": "Edit Info", + "RemoveFromPlaylist": "Remove from Playlist", "ValueSpecialEpisodeName": "Special - {0}", "Share": "\u5206\u4eab", "ServerUpdateNeeded": "\u6b64Emby\u4f3a\u670d\u5668\u9700\u8981\u66f4\u65b0\uff0c\u8acb\u81f3{0}\u53d6\u5f97\u6700\u65b0\u7248\u672c", diff --git a/dashboard-ui/channelitems.html b/dashboard-ui/channelitems.html index 208f1e5f8..0627264b3 100644 --- a/dashboard-ui/channelitems.html +++ b/dashboard-ui/channelitems.html @@ -6,6 +6,6 @@
-
+
\ No newline at end of file diff --git a/dashboard-ui/channels.html b/dashboard-ui/channels.html index 8a4bd375f..77dbcaf66 100644 --- a/dashboard-ui/channels.html +++ b/dashboard-ui/channels.html @@ -10,7 +10,7 @@
-
+
diff --git a/dashboard-ui/components/favoriteitems.js b/dashboard-ui/components/favoriteitems.js index 2da73aeb7..c65c5b8a7 100644 --- a/dashboard-ui/components/favoriteitems.js +++ b/dashboard-ui/components/favoriteitems.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'scrollStyles'], function (libraryBrowser) { +define(['libraryBrowser', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser) { function enableScrollX() { return browserInfo.mobile && AppInfo.enableAppLayouts; @@ -83,9 +83,9 @@ html += '
'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += libraryBrowser.getPosterViewHtml({ @@ -109,7 +109,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - libraryBrowser.createCardMenus(elem); }); } diff --git a/dashboard-ui/components/metadataeditor/metadataeditor.js b/dashboard-ui/components/metadataeditor/metadataeditor.js index 3b9a5b0ea..29f098714 100644 --- a/dashboard-ui/components/metadataeditor/metadataeditor.js +++ b/dashboard-ui/components/metadataeditor/metadataeditor.js @@ -285,6 +285,8 @@ item: currentItem, positionTo: button, edit: false, + editImages: true, + editSubtitles: true, sync: false, share: false diff --git a/dashboard-ui/components/remotecontrol.js b/dashboard-ui/components/remotecontrol.js index 9f9fff146..b71c4745a 100644 --- a/dashboard-ui/components/remotecontrol.js +++ b/dashboard-ui/components/remotecontrol.js @@ -769,9 +769,6 @@ }); Events.on(MediaController, 'playerchange', onPlayerChange); - - libraryBrowser.createCardMenus(context.querySelector('.itemsContainer')); - } function onDialogClosed(e) { diff --git a/dashboard-ui/home.html b/dashboard-ui/home.html index 76edae258..b98d8b664 100644 --- a/dashboard-ui/home.html +++ b/dashboard-ui/home.html @@ -25,7 +25,7 @@ ${ButtonSync}
-
+

${NoNextUpItemsMessage}

diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index 77e9e867f..97ad467dd 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -74,14 +74,14 @@

${HeaderNextUp}

-
+

-
+
diff --git a/dashboard-ui/livetv.html b/dashboard-ui/livetv.html index 579c04634..7657a4675 100644 --- a/dashboard-ui/livetv.html +++ b/dashboard-ui/livetv.html @@ -12,12 +12,12 @@

${HeaderWhatsOnTV}

-
+

${HeaderUpcomingPrograms}

-
+

@@ -25,7 +25,7 @@

${HeaderUpcomingMovies}

-
+

@@ -33,7 +33,7 @@

${HeaderUpcomingSports}

-
+

@@ -41,7 +41,7 @@

${HeaderUpcomingForKids}

-
+

@@ -52,12 +52,12 @@
-
+

${HeaderActiveRecordings}

-
+

@@ -68,7 +68,7 @@ ${ButtonSync}
-
+

diff --git a/dashboard-ui/livetvitems.html b/dashboard-ui/livetvitems.html index 7cf9a2b0b..342c626d1 100644 --- a/dashboard-ui/livetvitems.html +++ b/dashboard-ui/livetvitems.html @@ -4,7 +4,7 @@
-
+
\ No newline at end of file diff --git a/dashboard-ui/movies.html b/dashboard-ui/movies.html index 29069b1d1..7710a3ffd 100644 --- a/dashboard-ui/movies.html +++ b/dashboard-ui/movies.html @@ -20,7 +20,7 @@ -
+
@@ -33,7 +33,7 @@ -
+
@@ -98,14 +98,14 @@
-
+
-
+
diff --git a/dashboard-ui/music.html b/dashboard-ui/music.html index 5cd8b0147..f4eaa2b22 100644 --- a/dashboard-ui/music.html +++ b/dashboard-ui/music.html @@ -15,28 +15,28 @@

${HeaderLatestMusic}

-
+

${HeaderPlaylists}

-
+

${HeaderRecentlyPlayed}

-
+

${HeaderFrequentlyPlayed}

-
+
@@ -108,14 +108,14 @@
-
+
-
+
diff --git a/dashboard-ui/scripts/channelitems.js b/dashboard-ui/scripts/channelitems.js index 7838d3ddf..7aa2100d1 100644 --- a/dashboard-ui/scripts/channelitems.js +++ b/dashboard-ui/scripts/channelitems.js @@ -1,4 +1,4 @@ -define(['jQuery'], function ($) { +define(['jQuery', 'emby-itemscontainer'], function ($) { var data = {}; diff --git a/dashboard-ui/scripts/channels.js b/dashboard-ui/scripts/channels.js index 8ecf9cf1b..6fea82dc1 100644 --- a/dashboard-ui/scripts/channels.js +++ b/dashboard-ui/scripts/channels.js @@ -1,4 +1,4 @@ -define(['libraryBrowser'], function (libraryBrowser) { +define(['libraryBrowser', 'emby-itemscontainer'], function (libraryBrowser) { // The base query options var query = { diff --git a/dashboard-ui/scripts/homenextup.js b/dashboard-ui/scripts/homenextup.js index 8f0ce8fbe..15884146f 100644 --- a/dashboard-ui/scripts/homenextup.js +++ b/dashboard-ui/scripts/homenextup.js @@ -1,4 +1,4 @@ -define([], function () { +define(['emby-itemscontainer'], function () { function getNextUpPromise() { diff --git a/dashboard-ui/scripts/homeupcoming.js b/dashboard-ui/scripts/homeupcoming.js index 2dc187319..e116fa727 100644 --- a/dashboard-ui/scripts/homeupcoming.js +++ b/dashboard-ui/scripts/homeupcoming.js @@ -1,4 +1,4 @@ -define(['datetime', 'scrollStyles'], function (datetime) { +define(['datetime', 'emby-itemscontainer', 'scrollStyles'], function (datetime) { function getUpcomingPromise() { @@ -100,9 +100,9 @@ html += '

' + group.name + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ @@ -124,7 +124,6 @@ } elem.innerHTML = html; - LibraryBrowser.createCardMenus(elem); ImageLoader.lazyChildren(elem); } return function (view, params, tabContent) { diff --git a/dashboard-ui/scripts/itembynamedetailpage.js b/dashboard-ui/scripts/itembynamedetailpage.js index 9c71adc77..0a7b4cd02 100644 --- a/dashboard-ui/scripts/itembynamedetailpage.js +++ b/dashboard-ui/scripts/itembynamedetailpage.js @@ -256,7 +256,6 @@ var itemsContainer = element.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; - LibraryBrowser.createCardMenus(itemsContainer); ImageLoader.lazyChildren(itemsContainer); }); } diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index 810ff0b21..4115ff973 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -345,7 +345,6 @@ itemsContainer.innerHTML = html; ImageLoader.lazyChildren(itemsContainer); - LibraryBrowser.createCardMenus(itemsContainer); }); } @@ -765,9 +764,9 @@ var html = ''; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -787,7 +786,6 @@ var similarContent = page.querySelector('#similarContent'); similarContent.innerHTML = html; ImageLoader.lazyChildren(similarContent); - LibraryBrowser.createCardMenus(similarContent); }); } @@ -1006,8 +1004,6 @@ elem.classList.remove('hiddenScrollX'); } - LibraryBrowser.createCardMenus(elem); - if (item.Type == "BoxSet") { var collectionItemTypes = [ @@ -1112,11 +1108,6 @@ if (!items.length) { renderCollectionItemType(page, parentItem, { name: Globalize.translate('HeaderItems') }, items); } - - var containers = page.querySelectorAll('.collectionItems .itemsContainer'); - for (i = 0, length = containers.length; i < length; i++) { - LibraryBrowser.createCardMenus(containers[i]); - } } function renderCollectionItemType(page, parentItem, type, items) { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index ba382daa9..85bea7d71 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -903,7 +903,7 @@ atts.push({ name: 'serverid', - value: item.ServerId + value: item.ServerId || options.serverId }); atts.push({ @@ -1546,7 +1546,7 @@ anchorCssClass += ' mediaItem'; if (options.defaultAction) { - anchorCssClass += ' itemWithAction'; + anchorCssClass += ' itemAction'; } var transition = options.transition === false || !AppInfo.enableSectionTransitions ? '' : ' data-transition="slide"'; diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 5d3a78a32..6f8201ceb 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -216,45 +216,6 @@ return false; } - function onContextMenu(e) { - - var card = parentWithClass(e.target, 'card'); - - if (card) { - var itemSelectionPanel = card.querySelector('.itemSelectionPanel'); - - if (!itemSelectionPanel) { - showContextMenu(card, {}); - } - - e.preventDefault(); - return false; - } - } - - function deleteTimer(id, itemsContainer) { - - require(['confirm'], function (confirm) { - - confirm(Globalize.translate('MessageConfirmRecordingCancellation'), Globalize.translate('HeaderConfirmRecordingCancellation')).then(function () { - - Dashboard.showLoadingMsg(); - - ApiClient.cancelLiveTvTimer(id).then(function () { - - require(['toast'], function (toast) { - toast(Globalize.translate('MessageRecordingCancelled')); - }); - - Dashboard.hideLoadingMsg(); - itemsContainer.dispatchEvent(new CustomEvent('timercancelled', { - bubbles: true - })); - }); - }); - }); - } - function showContextMenu(card, options) { var displayContextItem = card; @@ -525,14 +486,7 @@ curr.removeEventListener('click', onCardClick); curr.addEventListener('click', onCardClick); - if (AppInfo.isTouchPreferred) { - - curr.removeEventListener('contextmenu', disableEvent); - curr.addEventListener('contextmenu', disableEvent); - } - else { - curr.removeEventListener('contextmenu', onContextMenu); - curr.addEventListener('contextmenu', onContextMenu); + if (!AppInfo.isTouchPreferred) { curr.removeEventListener('mouseenter', onHoverIn); curr.addEventListener('mouseenter', onHoverIn, true); @@ -544,7 +498,7 @@ curr.addEventListener("touchstart", preventTouchHover); } - initTapHoldMenus(curr); + //initTapHoldMenus(curr); }; function initTapHoldMenus(elem) { @@ -616,12 +570,6 @@ }); } - function disableEvent(e) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - function onTapHold(e) { var card = parentWithClass(e.target, 'card'); @@ -989,80 +937,6 @@ }); } - function onItemWithActionClick(e) { - - var elem = parentWithClass(e.target, 'itemWithAction'); - - if (!elem) { - return; - } - - var action = elem.getAttribute('data-action'); - var elemWithAttributes = elem; - - if (action) { - while (!elemWithAttributes.getAttribute('data-itemid')) { - elemWithAttributes = elemWithAttributes.parentNode; - } - } - - var index; - var itemsContainer; - - var itemId = elemWithAttributes.getAttribute('data-itemid'); - - if (action == 'play') { - MediaController.play(itemId); - } - else if (action == 'playallfromhere') { - - index = elemWithAttributes.getAttribute('data-index'); - - itemsContainer = parentWithClass(elem, 'itemsContainer'); - - playAllFromHere(index, itemsContainer, 'play'); - } - else if (action == 'instantmix') { - - MediaController.instantMix(itemId); - } - - e.stopPropagation(); - e.preventDefault(); - return false; - } - - function playAllFromHere(index, itemsContainer, method) { - - var ids = []; - - var mediaItems = itemsContainer.querySelectorAll('.mediaItem'); - for (var i = 0, length = mediaItems.length; i < length; i++) { - var node = mediaItems[i]; - var id = node.getAttribute('data-itemid'); - while (!id) { - node = node.parentNode; - id = node.getAttribute('data-itemid'); - } - ids.push(id); - } - - ids = ids.slice(index); - - ApiClient.getItems(Dashboard.getCurrentUserId(), { - - Ids: ids.join(','), - Fields: 'MediaSources,Chapters', - Limit: 100 - - }).then(function (result) { - - MediaController[method]({ - items: result.Items - }); - }); - } - function showSyncButtonsPerUser(page) { var apiClient = window.ApiClient; @@ -1106,16 +980,8 @@ var page = this; - page.addEventListener('click', onItemWithActionClick); - - var itemsContainers = page.querySelectorAll('.itemsContainer:not(.noautoinit)'); - var i, length; - for (i = 0, length = itemsContainers.length; i < length; i++) { - LibraryBrowser.createCardMenus(itemsContainers[i]); - } - var categorySyncButtons = page.querySelectorAll('.categorySyncButton'); - for (i = 0, length = categorySyncButtons.length; i < length; i++) { + for (var i = 0, length = categorySyncButtons.length; i < length; i++) { categorySyncButtons[i].addEventListener('click', onCategorySyncButtonClick); } }); diff --git a/dashboard-ui/scripts/livetvchannels.js b/dashboard-ui/scripts/livetvchannels.js index 72da67bad..50785f927 100644 --- a/dashboard-ui/scripts/livetvchannels.js +++ b/dashboard-ui/scripts/livetvchannels.js @@ -1,4 +1,4 @@ -define([], function () { +define(['emby-itemscontainer'], function () { return function (view, params, tabContent) { diff --git a/dashboard-ui/scripts/livetvitems.js b/dashboard-ui/scripts/livetvitems.js index 71ce7d3d8..11be75fa0 100644 --- a/dashboard-ui/scripts/livetvitems.js +++ b/dashboard-ui/scripts/livetvitems.js @@ -1,4 +1,4 @@ -define([], function () { +define(['emby-itemscontainer'], function () { var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); diff --git a/dashboard-ui/scripts/livetvrecordings.js b/dashboard-ui/scripts/livetvrecordings.js index b3b7cfc38..73f0c877c 100644 --- a/dashboard-ui/scripts/livetvrecordings.js +++ b/dashboard-ui/scripts/livetvrecordings.js @@ -149,7 +149,6 @@ elem.querySelector('.recordingItems').innerHTML = html; ImageLoader.lazyChildren(elem); - LibraryBrowser.createCardMenus(elem); }); } diff --git a/dashboard-ui/scripts/livetvsuggested.js b/dashboard-ui/scripts/livetvsuggested.js index 6fe55a2be..902d3f536 100644 --- a/dashboard-ui/scripts/livetvsuggested.js +++ b/dashboard-ui/scripts/livetvsuggested.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'scrollStyles'], function (libraryBrowser) { +define(['libraryBrowser', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser) { function enableScrollX() { return browserInfo.mobile && AppInfo.enableAppLayouts; @@ -133,7 +133,6 @@ } else { containers[i].classList.remove('hiddenScrollX'); } - LibraryBrowser.createCardMenus(containers[i]); } }; diff --git a/dashboard-ui/scripts/moviesrecommended.js b/dashboard-ui/scripts/moviesrecommended.js index 9ceba4465..7fc2816eb 100644 --- a/dashboard-ui/scripts/moviesrecommended.js +++ b/dashboard-ui/scripts/moviesrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'scrollStyles'], function (libraryBrowser) { +define(['libraryBrowser', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser) { function getView() { @@ -167,9 +167,9 @@ html += '

' + title + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } var view = getView(); @@ -247,8 +247,6 @@ } else { containers[i].classList.remove('hiddenScrollX'); } - - libraryBrowser.createCardMenus(containers[i]); } } @@ -281,8 +279,6 @@ loadSuggestionsTab(view, params, tabContent); }; - libraryBrowser.createCardMenus(view.querySelector('.recommendations')); - var mdlTabs = view.querySelector('.libraryViewNav'); var baseUrl = 'movies.html'; diff --git a/dashboard-ui/scripts/musicrecommended.js b/dashboard-ui/scripts/musicrecommended.js index a8a64fa7f..f6a6d31f3 100644 --- a/dashboard-ui/scripts/musicrecommended.js +++ b/dashboard-ui/scripts/musicrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'scrollStyles'], function (libraryBrowser) { +define(['libraryBrowser', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser) { function itemsPerRow() { @@ -258,8 +258,6 @@ } else { containers[i].classList.remove('hiddenScrollX'); } - - LibraryBrowser.createCardMenus(containers[i]); } }; diff --git a/dashboard-ui/scripts/playlistedit.js b/dashboard-ui/scripts/playlistedit.js index f49376190..9ed5d0d85 100644 --- a/dashboard-ui/scripts/playlistedit.js +++ b/dashboard-ui/scripts/playlistedit.js @@ -93,7 +93,6 @@ }); }); ImageLoader.lazyChildren(elem); - LibraryBrowser.createCardMenus(elem); $('.btnNextPage', elem).on('click', function () { query.StartIndex += query.Limit; diff --git a/dashboard-ui/scripts/searchpage.js b/dashboard-ui/scripts/searchpage.js index 6df9d0b40..88ba3d8de 100644 --- a/dashboard-ui/scripts/searchpage.js +++ b/dashboard-ui/scripts/searchpage.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'focusManager', 'embyRouter', 'emby-input', 'paper-icon-button-light', 'material-icons'], function (libraryBrowser, focusManager, embyRouter) { +define(['libraryBrowser', 'focusManager', 'embyRouter', 'emby-input', 'paper-icon-button-light', 'material-icons', 'emby-itemscontainer'], function (libraryBrowser, focusManager, embyRouter) { function loadSuggestions(page) { @@ -121,7 +121,8 @@ centerImage: true, centerText: true, textLines: getAdditionalTextLines, - overlayPlayButton: true + overlayPlayButton: true, + serverId: ApiClient.serverInfo().Id }); var itemsContainer = searchResults; @@ -176,8 +177,6 @@ loadSuggestions(view); } - libraryBrowser.createCardMenus(searchResults); - view.querySelector('.txtSearch').addEventListener('input', function () { onSearchChange(this.value); }); diff --git a/dashboard-ui/scripts/sections.js b/dashboard-ui/scripts/sections.js index 4bf9d791e..dd18df413 100644 --- a/dashboard-ui/scripts/sections.js +++ b/dashboard-ui/scripts/sections.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'appSettings', 'scrollStyles', 'emby-button', 'paper-icon-button-light'], function (LibraryBrowser, appSettings) { +define(['libraryBrowser', 'appSettings', 'scrollStyles', 'emby-button', 'paper-icon-button-light', 'emby-itemscontainer'], function (LibraryBrowser, appSettings) { function getUserViews(userId) { @@ -302,7 +302,7 @@ html += '
'; - html += '
'; + html += '
'; html += LibraryBrowser.getPosterViewHtml({ items: items, @@ -322,8 +322,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem); }); } @@ -347,9 +345,9 @@ if (items.length) { html += '

' + Globalize.translate('HeaderLatestMovies') + '

'; if (scrollX) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: items, @@ -366,8 +364,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem); }); } @@ -391,9 +387,9 @@ if (items.length) { html += '

' + Globalize.translate('HeaderLatestEpisodes') + '

'; if (scrollX) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ @@ -411,8 +407,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem); }); } @@ -434,7 +428,7 @@ if (result.Items.length) { html += '

' + Globalize.translate('HeaderLatestChannelMedia') + '

'; - html += '
'; + html += '
'; html += LibraryBrowser.getPosterViewHtml({ items: result.Items, shape: 'auto', @@ -449,8 +443,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem); }); } @@ -478,9 +470,9 @@ var scrollX = enableScrollX() && browserInfo.safari && screenWidth > 800; if (scrollX) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: items, @@ -506,8 +498,6 @@ elem.innerHTML = html + infoHtml; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem, { showDetailsMenu: false }); }); }); } @@ -539,9 +529,9 @@ if (result.Items.length) { html += '

' + Globalize.translate('HeaderResume') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -562,7 +552,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - LibraryBrowser.createCardMenus(elem); }); } @@ -584,9 +573,9 @@ if (result.Items.length) { html += '

' + Globalize.translate('HeaderNextUp') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -606,7 +595,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - LibraryBrowser.createCardMenus(elem); }); } @@ -667,7 +655,7 @@ html += ''; html += '
'; - html += '
'; + html += '
'; html += LibraryBrowser.getPosterViewHtml({ items: result.Items, shape: 'autohome', @@ -685,8 +673,6 @@ var elem = page.querySelector('#channel' + channel.Id + ''); elem.innerHTML = html; ImageLoader.lazyChildren(elem); - - LibraryBrowser.createCardMenus(elem); }); } @@ -715,9 +701,9 @@ } if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -734,7 +720,6 @@ elem.innerHTML = html; ImageLoader.lazyChildren(elem); - LibraryBrowser.createCardMenus(elem); }); } diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 1646238ca..570b46e65 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -2035,6 +2035,9 @@ var AppInfo = {}; }, canPlay: function (item) { return MediaController.canPlay(item); + }, + instantMix: function (item) { + return MediaController.instantMix(item); } }; }); @@ -2287,7 +2290,7 @@ var AppInfo = {}; var baseUrl = 'bower_components/emby-webcomponents/strings/'; - var languages = ['da', 'de', 'en-US', 'es-MX', 'kk', 'nb', 'nl', 'pt-BR', 'pt-PT', 'ru', 'sv', 'zh-TW']; + var languages = ['da', 'de', 'en-US', 'es-MX', 'fr', 'kk', 'nb', 'nl', 'pt-BR', 'pt-PT', 'ru', 'sv', 'zh-TW']; var translations = languages.map(function (i) { return { @@ -3248,7 +3251,7 @@ var AppInfo = {}; } function upgradeLayouts() { - if (!AppInfo.enableAppLayouts && browserInfo.mobile) { + if (!AppInfo.enableAppLayouts) { Dashboard.getPluginSecurityInfo().then(function (info) { if (info.IsMBSupporter) { AppInfo.enableAppLayouts = true; diff --git a/dashboard-ui/scripts/tvrecommended.js b/dashboard-ui/scripts/tvrecommended.js index fa2f23132..605f789ee 100644 --- a/dashboard-ui/scripts/tvrecommended.js +++ b/dashboard-ui/scripts/tvrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'scrollStyles'], function (libraryBrowser) { +define(['libraryBrowser', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser) { return function (view, params) { @@ -165,7 +165,6 @@ } else { tabContent.querySelector('#resumableItems').classList.remove('hiddenScrollX'); } - libraryBrowser.createCardMenus(tabContent.querySelector('#resumableItems')); }; self.renderTab = function () { @@ -273,7 +272,6 @@ } else { view.querySelector('#resumableItems').classList.remove('hiddenScrollX'); } - libraryBrowser.createCardMenus(view.querySelector('#resumableItems')); libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 1, 2, 4, 5, 6]); mdlTabs.addEventListener('beforetabchange', function (e) { diff --git a/dashboard-ui/scripts/tvupcoming.js b/dashboard-ui/scripts/tvupcoming.js index 6d6d79df2..b9534c463 100644 --- a/dashboard-ui/scripts/tvupcoming.js +++ b/dashboard-ui/scripts/tvupcoming.js @@ -1,4 +1,4 @@ -define(['datetime', 'scrollStyles'], function (datetime) { +define(['datetime', 'scrollStyles', 'emby-itemscontainer'], function (datetime) { function getUpcomingPromise(context, params) { @@ -102,9 +102,9 @@ html += '

' + group.name + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { - html += '
'; + html += '
'; } html += LibraryBrowser.getPosterViewHtml({ @@ -125,7 +125,6 @@ } elem.innerHTML = html; - LibraryBrowser.createCardMenus(elem); ImageLoader.lazyChildren(elem); } return function (view, params, tabContent) { diff --git a/dashboard-ui/search.html b/dashboard-ui/search.html index fb60807bf..071f8ae07 100644 --- a/dashboard-ui/search.html +++ b/dashboard-ui/search.html @@ -43,6 +43,6 @@
-
+
\ No newline at end of file diff --git a/dashboard-ui/tv.html b/dashboard-ui/tv.html index 56c82f229..443a8d3ab 100644 --- a/dashboard-ui/tv.html +++ b/dashboard-ui/tv.html @@ -22,7 +22,7 @@
-
+
@@ -34,7 +34,7 @@ ${ButtonSync}
-
+
@@ -48,7 +48,7 @@ ${ButtonSync}
-
+
@@ -96,14 +96,14 @@
-
+
-
+
From 83adc06fa2e49e6de65b7de02b1bce8cfe686e1f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:08:04 -0400 Subject: [PATCH 02/10] use shared play menu --- .../emby-webcomponents/.bower.json | 8 +- .../emby-itemscontainer.js | 105 +----------------- .../emby-webcomponents/listview/listview.js | 2 +- .../mediainfo/mediainfo.css | 2 +- .../emby-webcomponents/playmenu.js | 100 +++++++++++++++++ .../emby-webcomponents/shortcuts.js | 98 ++++++++++++++-- .../emby-webcomponents/strings/en-US.json | 2 + .../fingerprintjs2/.bower.json | 11 +- .../fingerprintjs2/dist/fingerprint2.min.js | 4 +- .../fingerprintjs2/fingerprint2.js | 9 +- .../fingerprintjs2/package.json | 2 +- .../bower_components/polymer/.bower.json | 2 +- dashboard-ui/scripts/librarybrowser.js | 6 +- dashboard-ui/scripts/librarylist.js | 34 ------ dashboard-ui/scripts/site.js | 1 + 15 files changed, 222 insertions(+), 164 deletions(-) create mode 100644 dashboard-ui/bower_components/emby-webcomponents/playmenu.js diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index e9c2692cc..f08a23588 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -15,12 +15,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.93", - "_release": "1.4.93", + "version": "1.4.94", + "_release": "1.4.94", "_resolution": { "type": "version", - "tag": "1.4.93", - "commit": "8b6b445547b02a088fbafed08120ed87c4004df5" + "tag": "1.4.94", + "commit": "1914cf851948d6f4f5e730c5e831e5e604fe3c9e" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.0", diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js index 356375824..7b6285f8a 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js @@ -2,19 +2,6 @@ var ItemsContainerProtoType = Object.create(HTMLDivElement.prototype); - function parentWithClass(elem, className) { - - while (!elem.classList || !elem.classList.contains(className)) { - elem = elem.parentNode; - - if (!elem) { - return null; - } - } - - return elem; - } - function parentWithAttribute(elem, name) { while (!elem.getAttribute(name)) { @@ -28,75 +15,11 @@ return elem; } - function getItem(button) { - - button = parentWithAttribute(button, 'data-id'); - var serverId = button.getAttribute('data-serverid'); - var id = button.getAttribute('data-id'); - var type = button.getAttribute('data-type'); - - var apiClient = connectionManager.getApiClient(serverId); - - return apiClient.getItem(apiClient.getCurrentUserId(), id); - } - - function showContextMenu(button, itemsContainer) { - - getItem(button).then(function (item) { - - var playlistId = itemsContainer.getAttribute('data-playlistid'); - var collectionId = itemsContainer.getAttribute('data-collectionid'); - - if (playlistId) { - var elem = parentWithAttribute(button, 'data-playlistitemid'); - item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null; - } - - require(['itemContextMenu'], function (itemContextMenu) { - itemContextMenu.show({ - positionTo: button, - item: item, - play: true, - queue: true, - playAllFromHere: !item.IsFolder, - queueAllFromHere: !item.IsFolder, - identify: false, - playlistId: playlistId, - collectionId: collectionId - - }).then(function (result) { - - if (result.command == 'playallfromhere' || result.command == 'queueallfromhere') { - itemShortcuts.execute(button, result.command); - } - else if (result.command == 'removefromplaylist' || result.command == 'removefromcollection') { - - itemsContainer.dispatchEvent(new CustomEvent('needsrefresh', { - detail: {}, - cancelable: false, - bubbles: true - })); - } - }); - }); - }); - } - function onClick(e) { var itemsContainer = this; var target = e.target; - var menuButton = parentWithClass(target, 'menuButton'); - if (menuButton) { - var card = parentWithAttribute(target, 'data-id'); - if (card) { - showContextMenu(card, target); - e.stopPropagation(); - return false; - } - } - itemShortcuts.onClick.call(this, e); } @@ -107,28 +30,6 @@ return false; } - function showContextMenu(card, target, options) { - - var itemId = card.getAttribute('data-id'); - var serverId = card.getAttribute('data-serverid'); - var type = card.getAttribute('data-type'); - - var apiClient = connectionManager.getApiClient(serverId); - - var promise = type == 'Timer' ? apiClient.getLiveTvTimer(itemId) : apiClient.getItem(apiClient.getCurrentUserId(), itemId); - - promise.then(function (item) { - - require(['itemContextMenu'], function (itemContextMenu) { - - itemContextMenu.show(Object.assign(options || {}, { - item: item, - positionTo: target - })); - }); - }); - } - function onContextMenu(e) { var itemsContainer = this; @@ -143,8 +44,10 @@ // showContextMenu(card, {}); //} - showContextMenu(card, target, { - identify: false + itemShortcuts.showContextMenu(card, { + identify: false, + positionTo: target, + itemsContainer: itemsContainer }); } diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js index 947959be6..baf251fd9 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js @@ -291,7 +291,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } if (!clickEntireItem) { - html += ''; + html += ''; html += ''; html += userdataButtons.getIconsHtml(item, false); html += ''; diff --git a/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.css b/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.css index d0868c7da..dc1c4cdf8 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.css +++ b/dashboard-ui/bower_components/emby-webcomponents/mediainfo/mediainfo.css @@ -26,7 +26,7 @@ i.mediaInfoItem { color: #CB272A; width: auto !important; height: auto !important; - font-size: 120%; + font-size: 1.4em; } .mediaInfoItem.criticRating { diff --git a/dashboard-ui/bower_components/emby-webcomponents/playmenu.js b/dashboard-ui/bower_components/emby-webcomponents/playmenu.js new file mode 100644 index 000000000..eca1a1d58 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/playmenu.js @@ -0,0 +1,100 @@ +define(['actionsheet', 'datetime', 'playbackManager', 'globalize'], function (actionsheet, datetime, playbackManager, globalize) { + + function show(options) { + + var item = options.item; + + var itemType = item.Type; + var mediaType = item.MediaType; + var isFolder = item.IsFolder; + var itemId = item.Id; + var serverId = item.ServerId; + var resumePositionTicks = item.UserData ? item.UserData.PlaybackPositionTicks : null; + + if (!resumePositionTicks && mediaType != "Audio" && !isFolder) { + playbackManager.play({ + items: [item] + }); + return; + } + + var menuItems = []; + + if (resumePositionTicks) { + menuItems.push({ + name: globalize.translate('sharedcomponents#ResumeAt', datetime.getDisplayRunningTime(resumePositionTicks)), + id: 'resume' + }); + + menuItems.push({ + name: globalize.translate('sharedcomponents#PlayFromBeginning'), + id: 'play' + }); + } else { + menuItems.push({ + name: globalize.translate('sharedcomponents#Play'), + id: 'play' + }); + } + + if (playbackManager.canQueueMediaType(mediaType)) { + menuItems.push({ + name: globalize.translate('sharedcomponents#Queue'), + id: 'queue' + }); + } + + if (itemType == "Audio" || itemType == "MusicAlbum" || itemType == "MusicArtist" || itemType == "MusicGenre") { + menuItems.push({ + name: globalize.translate('sharedcomponents#InstantMix'), + id: 'instantmix' + }); + } + + if (isFolder || itemType == "MusicArtist" || itemType == "MusicGenre") { + menuItems.push({ + name: globalize.translate('sharedcomponents#Shuffle'), + id: 'shuffle' + }); + } + + actionsheet.show({ + + items: menuItems, + positionTo: options.positionTo + + }).then(function (id) { + switch (id) { + + case 'play': + playbackManager.play({ + ids: [itemId], + serverId: item.ServerId + }); + break; + case 'resume': + playbackManager.play({ + ids: [itemId], + startPositionTicks: resumePositionTicks, + serverId: item.ServerId + }); + break; + case 'queue': + playbackManager.queue(item); + break; + case 'instantmix': + playbackManager.instantMix(item); + break; + case 'shuffle': + playbackManager.shuffle(item); + break; + default: + break; + } + }); + } + + return { + show: show + }; +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js index 6b9fc7a74..9edfdeca6 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js +++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js @@ -90,7 +90,80 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g embyRouter.showItem(options); } - function executeAction(card, action) { + function getItem(button) { + + button = parentWithAttribute(button, 'data-id'); + var serverId = button.getAttribute('data-serverid'); + var id = button.getAttribute('data-id'); + var type = button.getAttribute('data-type'); + + var apiClient = connectionManager.getApiClient(serverId); + + return apiClient.getItem(apiClient.getCurrentUserId(), id); + } + + function showContextMenu(card, options) { + + getItem(card).then(function (item) { + + var itemsContainer = options.itemsContainer || parentWithAttribute(card, 'is', 'emby-itemscontainer'); + + var playlistId = itemsContainer ? itemsContainer.getAttribute('data-playlistid') : null; + var collectionId = itemsContainer ? itemsContainer.getAttribute('data-collectionid') : null; + + if (playlistId) { + var elem = parentWithAttribute(card, 'data-playlistitemid'); + item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null; + } + + require(['itemContextMenu'], function (itemContextMenu) { + + itemContextMenu.show(Object.assign({ + item: item, + play: true, + queue: true, + playAllFromHere: !item.IsFolder, + queueAllFromHere: !item.IsFolder, + identify: false, + playlistId: playlistId, + collectionId: collectionId + + }, options || {})).then(function (result) { + + if (result.command == 'playallfromhere' || result.command == 'queueallfromhere') { + executeAction(card, options.positionTo, result.command); + } + else if (result.command == 'removefromplaylist' || result.command == 'removefromcollection') { + + if (itemsContainer) { + itemsContainer.dispatchEvent(new CustomEvent('needsrefresh', { + detail: {}, + cancelable: false, + bubbles: true + })); + } + } + }); + }); + }); + } + + function showPlayMenu(card, target) { + + getItem(card).then(function (item) { + + require(['playMenu'], function (playMenu) { + + playMenu.show({ + + item: item, + positionTo: target + }); + }); + }); + } + + function executeAction(card, target, action) { var id = card.getAttribute('data-id'); @@ -142,6 +215,17 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g else if (action == 'record') { onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid')); } + + else if (action == 'menu') { + showContextMenu(card, { + identify: false, + positionTo: target || card + }); + } + + else if (action == 'playmenu') { + showPlayMenu(card, target || card); + } } function onRecordCommand(serverId, id, type, timerId, seriesTimerId) { @@ -234,7 +318,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } if (action) { - executeAction(card, action); + executeAction(card, e.target, action); e.preventDefault(); e.stopPropagation(); @@ -243,9 +327,9 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } } - function parentWithAttribute(elem, name) { + function parentWithAttribute(elem, name, value) { - while (!elem.getAttribute(name)) { + while ((value ? elem.getAttribute(name) != value : !elem.getAttribute(name))) { elem = elem.parentNode; if (!elem) { @@ -276,7 +360,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g var card = parentWithClass(e.target, 'itemAction'); if (card) { - executeAction(card, cmd); + executeAction(card, card, cmd); } } } @@ -307,8 +391,8 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g return { on: on, off: off, - execute: executeAction, - onClick: onClick + onClick: onClick, + showContextMenu: showContextMenu }; }); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json index 3078e9bbe..301adb112 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json @@ -112,5 +112,7 @@ "ViewArtist": "View Artist", "QueueAllFromHere": "Queue All from Here", "PlayAllFromHere": "Play All from Here", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume at {0}", "RemoveFromPlaylist": "Remove from Playlist" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/fingerprintjs2/.bower.json b/dashboard-ui/bower_components/fingerprintjs2/.bower.json index e0b82179f..114aad232 100644 --- a/dashboard-ui/bower_components/fingerprintjs2/.bower.json +++ b/dashboard-ui/bower_components/fingerprintjs2/.bower.json @@ -23,15 +23,14 @@ "spec" ], "homepage": "https://github.com/Valve/fingerprintjs2", - "version": "1.4.0", - "_release": "1.4.0", + "version": "1.4.1", + "_release": "1.4.1", "_resolution": { "type": "version", - "tag": "1.4.0", - "commit": "75cbd474158f8ecce43e00f198c76e486b896937" + "tag": "1.4.1", + "commit": "6320cfa19c89aca0eb39e811d101336a2812ad61" }, "_source": "https://github.com/Valve/fingerprintjs2.git", "_target": "^1.4.0", - "_originalSource": "fingerprintjs2", - "_direct": true + "_originalSource": "fingerprintjs2" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/fingerprintjs2/dist/fingerprint2.min.js b/dashboard-ui/bower_components/fingerprintjs2/dist/fingerprint2.min.js index 3d5aafd2e..02965f600 100644 --- a/dashboard-ui/bower_components/fingerprintjs2/dist/fingerprint2.min.js +++ b/dashboard-ui/bower_components/fingerprintjs2/dist/fingerprint2.min.js @@ -1,2 +1,2 @@ -!function(e,t,i){"use strict";"undefined"!=typeof module&&module.exports?module.exports=i():"function"==typeof define&&define.amd?define(i):t[e]=i()}("Fingerprint2",this,function(){"use strict";Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){var i;if(null==this)throw new TypeError("'this' is null or undefined");var a=Object(this),r=a.length>>>0;if(0===r)return-1;var n=+t||0;if(Math.abs(n)===1/0&&(n=0),n>=r)return-1;for(i=Math.max(n>=0?n:r-Math.abs(n),0);r>i;){if(i in a&&a[i]===e)return i;i++}return-1});var e=function(e){var t={swfContainerId:"fingerprintjs2",swfPath:"flash/compiled/FontList.swf",detectScreenOrientation:!0,sortPluginsFor:[/palemoon/i]};this.options=this.extend(e,t),this.nativeForEach=Array.prototype.forEach,this.nativeMap=Array.prototype.map};return e.prototype={extend:function(e,t){if(null==e)return t;for(var i in e)null!=e[i]&&t[i]!==e[i]&&(t[i]=e[i]);return t},log:function(e){window.console&&console.log(e)},get:function(e){var t=[];t=this.userAgentKey(t),t=this.languageKey(t),t=this.colorDepthKey(t),t=this.pixelRatioKey(t),t=this.screenResolutionKey(t),t=this.availableScreenResolutionKey(t),t=this.timezoneOffsetKey(t),t=this.sessionStorageKey(t),t=this.localStorageKey(t),t=this.indexedDbKey(t),t=this.addBehaviorKey(t),t=this.openDatabaseKey(t),t=this.cpuClassKey(t),t=this.platformKey(t),t=this.doNotTrackKey(t),t=this.pluginsKey(t),t=this.canvasKey(t),t=this.webglKey(t),t=this.adBlockKey(t),t=this.hasLiedLanguagesKey(t),t=this.hasLiedResolutionKey(t),t=this.hasLiedOsKey(t),t=this.hasLiedBrowserKey(t),t=this.touchSupportKey(t);var i=this;this.fontsKey(t,function(t){var a=[];i.each(t,function(e){var t=e.value;"undefined"!=typeof e.value.join&&(t=e.value.join(";")),a.push(t)});var r=i.x64hash128(a.join("~~~"),31);return e(r,t)})},userAgentKey:function(e){return this.options.excludeUserAgent||e.push({key:"user_agent",value:this.getUserAgent()}),e},getUserAgent:function(){return navigator.userAgent},languageKey:function(e){return this.options.excludeLanguage||e.push({key:"language",value:navigator.language||navigator.userLanguage||navigator.browserLanguage||navigator.systemLanguage||""}),e},colorDepthKey:function(e){return this.options.excludeColorDepth||e.push({key:"color_depth",value:screen.colorDepth}),e},pixelRatioKey:function(e){return this.options.excludePixelRatio||e.push({key:"pixel_ratio",value:this.getPixelRatio()}),e},getPixelRatio:function(){return window.devicePixelRatio||""},screenResolutionKey:function(e){return this.options.excludeScreenResolution?e:this.getScreenResolution(e)},getScreenResolution:function(e){var t;return t=this.options.detectScreenOrientation&&screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height],"undefined"!=typeof t&&e.push({key:"resolution",value:t}),e},availableScreenResolutionKey:function(e){return this.options.excludeAvailableScreenResolution?e:this.getAvailableScreenResolution(e)},getAvailableScreenResolution:function(e){var t;return screen.availWidth&&screen.availHeight&&(t=this.options.detectScreenOrientation?screen.availHeight>screen.availWidth?[screen.availHeight,screen.availWidth]:[screen.availWidth,screen.availHeight]:[screen.availHeight,screen.availWidth]),"undefined"!=typeof t&&e.push({key:"available_resolution",value:t}),e},timezoneOffsetKey:function(e){return this.options.excludeTimezoneOffset||e.push({key:"timezone_offset",value:(new Date).getTimezoneOffset()}),e},sessionStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasSessionStorage()&&e.push({key:"session_storage",value:1}),e},localStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasLocalStorage()&&e.push({key:"local_storage",value:1}),e},indexedDbKey:function(e){return!this.options.excludeIndexedDB&&this.hasIndexedDB()&&e.push({key:"indexed_db",value:1}),e},addBehaviorKey:function(e){return document.body&&!this.options.excludeAddBehavior&&document.body.addBehavior&&e.push({key:"add_behavior",value:1}),e},openDatabaseKey:function(e){return!this.options.excludeOpenDatabase&&window.openDatabase&&e.push({key:"open_database",value:1}),e},cpuClassKey:function(e){return this.options.excludeCpuClass||e.push({key:"cpu_class",value:this.getNavigatorCpuClass()}),e},platformKey:function(e){return this.options.excludePlatform||e.push({key:"navigator_platform",value:this.getNavigatorPlatform()}),e},doNotTrackKey:function(e){return this.options.excludeDoNotTrack||e.push({key:"do_not_track",value:this.getDoNotTrack()}),e},canvasKey:function(e){return!this.options.excludeCanvas&&this.isCanvasSupported()&&e.push({key:"canvas",value:this.getCanvasFp()}),e},webglKey:function(e){return this.options.excludeWebGL?e:this.isWebGlSupported()?(e.push({key:"webgl",value:this.getWebglFp()}),e):e},adBlockKey:function(e){return this.options.excludeAdBlock||e.push({key:"adblock",value:this.getAdBlock()}),e},hasLiedLanguagesKey:function(e){return this.options.excludeHasLiedLanguages||e.push({key:"has_lied_languages",value:this.getHasLiedLanguages()}),e},hasLiedResolutionKey:function(e){return this.options.excludeHasLiedResolution||e.push({key:"has_lied_resolution",value:this.getHasLiedResolution()}),e},hasLiedOsKey:function(e){return this.options.excludeHasLiedOs||e.push({key:"has_lied_os",value:this.getHasLiedOs()}),e},hasLiedBrowserKey:function(e){return this.options.excludeHasLiedBrowser||e.push({key:"has_lied_browser",value:this.getHasLiedBrowser()}),e},fontsKey:function(e,t){return this.options.excludeJsFonts?this.flashFontsKey(e,t):this.jsFontsKey(e,t)},flashFontsKey:function(e,t){return this.options.excludeFlashFonts?t(e):this.hasSwfObjectLoaded()&&this.hasMinFlashInstalled()?"undefined"==typeof this.options.swfPath?t(e):void this.loadSwfAndDetectFonts(function(i){e.push({key:"swf_fonts",value:i.join(";")}),t(e)}):t(e)},jsFontsKey:function(e,t){var i=this;return setTimeout(function(){var a=["monospace","sans-serif","serif"],r=["Andale Mono","Arial","Arial Black","Arial Hebrew","Arial MT","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS","Bitstream Vera Sans Mono","Book Antiqua","Bookman Old Style","Calibri","Cambria","Cambria Math","Century","Century Gothic","Century Schoolbook","Comic Sans","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Helvetica","Helvetica Neue","Impact","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","LUCIDA GRANDE","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Monotype Corsiva","MS Gothic","MS Outlook","MS PGothic","MS Reference Sans Serif","MS Sans Serif","MS Serif","MYRIAD","MYRIAD PRO","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Segoe UI Light","Segoe UI Semibold","Segoe UI Symbol","Tahoma","Times","Times New Roman","Times New Roman PS","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3"],n=["Abadi MT Condensed Light","Academy Engraved LET","ADOBE CASLON PRO","Adobe Garamond","ADOBE GARAMOND PRO","Agency FB","Aharoni","Albertus Extra Bold","Albertus Medium","Algerian","Amazone BT","American Typewriter","American Typewriter Condensed","AmerType Md BT","Andalus","Angsana New","AngsanaUPC","Antique Olive","Aparajita","Apple Chancery","Apple Color Emoji","Apple SD Gothic Neo","Arabic Typesetting","ARCHER","ARNO PRO","Arrus BT","Aurora Cn BT","AvantGarde Bk BT","AvantGarde Md BT","AVENIR","Ayuthaya","Bandy","Bangla Sangam MN","Bank Gothic","BankGothic Md BT","Baskerville","Baskerville Old Face","Batang","BatangChe","Bauer Bodoni","Bauhaus 93","Bazooka","Bell MT","Bembo","Benguiat Bk BT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","BernhardFashion BT","BernhardMod BT","Big Caslon","BinnerD","Blackadder ITC","BlairMdITC TT","Bodoni 72","Bodoni 72 Oldstyle","Bodoni 72 Smallcaps","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Bookshelf Symbol 7","Boulder","Bradley Hand","Bradley Hand ITC","Bremen Bd BT","Britannic Bold","Broadway","Browallia New","BrowalliaUPC","Brush Script MT","Californian FB","Calisto MT","Calligrapher","Candara","CaslonOpnface BT","Castellar","Centaur","Cezanne","CG Omega","CG Times","Chalkboard","Chalkboard SE","Chalkduster","Charlesworth","Charter Bd BT","Charter BT","Chaucer","ChelthmITC Bk BT","Chiller","Clarendon","Clarendon Condensed","CloisterBlack BT","Cochin","Colonna MT","Constantia","Cooper Black","Copperplate","Copperplate Gothic","Copperplate Gothic Bold","Copperplate Gothic Light","CopperplGoth Bd BT","Corbel","Cordia New","CordiaUPC","Cornerstone","Coronet","Cuckoo","Curlz MT","DaunPenh","Dauphin","David","DB LCD Temp","DELICIOUS","Denmark","DFKai-SB","Didot","DilleniaUPC","DIN","DokChampa","Dotum","DotumChe","Ebrima","Edwardian Script ITC","Elephant","English 111 Vivace BT","Engravers MT","EngraversGothic BT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","EucrosiaUPC","Euphemia","Euphemia UCAS","EUROSTILE","Exotc350 Bd BT","FangSong","Felix Titling","Fixedsys","FONTIN","Footlight MT Light","Forte","FrankRuehl","Fransiscan","Freefrm721 Blk BT","FreesiaUPC","Freestyle Script","French Script MT","FrnkGothITC Bk BT","Fruitger","FRUTIGER","Futura","Futura Bk BT","Futura Lt BT","Futura Md BT","Futura ZBlk BT","FuturaBlack BT","Gabriola","Galliard BT","Gautami","Geeza Pro","Geometr231 BT","Geometr231 Hv BT","Geometr231 Lt BT","GeoSlab 703 Lt BT","GeoSlab 703 XBd BT","Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed","Gisha","Gloucester MT Extra Condensed","GOTHAM","GOTHAM BOLD","Goudy Old Style","Goudy Stout","GoudyHandtooled BT","GoudyOLSt BT","Gujarati Sangam MN","Gulim","GulimChe","Gungsuh","GungsuhChe","Gurmukhi MN","Haettenschweiler","Harlow Solid Italic","Harrington","Heather","Heiti SC","Heiti TC","HELV","Herald","High Tower Text","Hiragino Kaku Gothic ProN","Hiragino Mincho ProN","Hoefler Text","Humanst 521 Cn BT","Humanst521 BT","Humanst521 Lt BT","Imprint MT Shadow","Incised901 Bd BT","Incised901 BT","Incised901 Lt BT","INCONSOLATA","Informal Roman","Informal011 BT","INTERSTATE","IrisUPC","Iskoola Pota","JasmineUPC","Jazz LET","Jenson","Jester","Jokerman","Juice ITC","Kabel Bk BT","Kabel Ult BT","Kailasa","KaiTi","Kalinga","Kannada Sangam MN","Kartika","Kaufmann Bd BT","Kaufmann BT","Khmer UI","KodchiangUPC","Kokila","Korinna BT","Kristen ITC","Krungthep","Kunstler Script","Lao UI","Latha","Leelawadee","Letter Gothic","Levenim MT","LilyUPC","Lithograph","Lithograph Light","Long Island","Lydian BT","Magneto","Maiandra GD","Malayalam Sangam MN","Malgun Gothic","Mangal","Marigold","Marion","Marker Felt","Market","Marlett","Matisse ITC","Matura MT Script Capitals","Meiryo","Meiryo UI","Microsoft Himalaya","Microsoft JhengHei","Microsoft New Tai Lue","Microsoft PhagsPa","Microsoft Tai Le","Microsoft Uighur","Microsoft YaHei","Microsoft Yi Baiti","MingLiU","MingLiU_HKSCS","MingLiU_HKSCS-ExtB","MingLiU-ExtB","Minion","Minion Pro","Miriam","Miriam Fixed","Mistral","Modern","Modern No. 20","Mona Lisa Solid ITC TT","Mongolian Baiti","MONO","MoolBoran","Mrs Eaves","MS LineDraw","MS Mincho","MS PMincho","MS Reference Specialty","MS UI Gothic","MT Extra","MUSEO","MV Boli","Nadeem","Narkisim","NEVIS","News Gothic","News GothicMT","NewsGoth BT","Niagara Engraved","Niagara Solid","Noteworthy","NSimSun","Nyala","OCR A Extended","Old Century","Old English Text MT","Onyx","Onyx BT","OPTIMA","Oriya Sangam MN","OSAKA","OzHandicraft BT","Palace Script MT","Papyrus","Parchment","Party LET","Pegasus","Perpetua","Perpetua Titling MT","PetitaBold","Pickwick","Plantagenet Cherokee","Playbill","PMingLiU","PMingLiU-ExtB","Poor Richard","Poster","PosterBodoni BT","PRINCETOWN LET","Pristina","PTBarnum BT","Pythagoras","Raavi","Rage Italic","Ravie","Ribbon131 Bd BT","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Rod","Roman","Sakkal Majalla","Santa Fe LET","Savoye LET","Sceptre","Script","Script MT Bold","SCRIPTINA","Serifa","Serifa BT","Serifa Th BT","ShelleyVolante BT","Sherwood","Shonar Bangla","Showcard Gothic","Shruti","Signboard","SILKSCREEN","SimHei","Simplified Arabic","Simplified Arabic Fixed","SimSun","SimSun-ExtB","Sinhala Sangam MN","Sketch Rockwell","Skia","Small Fonts","Snap ITC","Snell Roundhand","Socket","Souvenir Lt BT","Staccato222 BT","Steamer","Stencil","Storybook","Styllo","Subway","Swis721 BlkEx BT","Swiss911 XCm BT","Sylfaen","Synchro LET","System","Tamil Sangam MN","Technical","Teletype","Telugu Sangam MN","Tempus Sans ITC","Terminal","Thonburi","Traditional Arabic","Trajan","TRAJAN PRO","Tristan","Tubular","Tunga","Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","TypoUpright BT","Unicorn","Univers","Univers CE 55 Medium","Univers Condensed","Utsaah","Vagabond","Vani","Vijaya","Viner Hand ITC","VisualUI","Vivaldi","Vladimir Script","Vrinda","Westminster","WHITNEY","Wide Latin","ZapfEllipt BT","ZapfHumnst BT","ZapfHumnst Dm BT","Zapfino","Zurich BlkEx BT","Zurich Ex BT","ZWAdobeF"];i.options.extendedJsFonts&&(r=r.concat(n));var o="mmmmmmmmmmlli",s="72px",l=document.getElementsByTagName("body")[0],h=document.createElement("div"),u=document.createElement("div"),d={},c={},g=function(){var e=document.createElement("span");return e.style.position="absolute",e.style.left="-9999px",e.style.fontSize=s,e.innerHTML=o,e},p=function(e,t){var i=g();return i.style.fontFamily="'"+e+"',"+t,i},f=function(){for(var e=[],t=0,i=a.length;i>t;t++){var r=g();r.style.fontFamily=a[t],h.appendChild(r),e.push(r)}return e},m=function(){for(var e={},t=0,i=r.length;i>t;t++){for(var n=[],o=0,s=a.length;s>o;o++){var l=p(r[t],a[o]);u.appendChild(l),n.push(l)}e[r[t]]=n}return e},S=function(e){for(var t=!1,i=0;ix;x++)d[a[x]]=T[x].offsetWidth,c[a[x]]=T[x].offsetHeight;var M=m();l.appendChild(u);for(var A=[],E=0,y=r.length;y>E;E++)S(M[r[E]])&&A.push(r[E]);l.removeChild(u),l.removeChild(h),e.push({key:"js_fonts",value:A}),t(e)},1)},pluginsKey:function(e){return this.options.excludePlugins||(this.isIE()?this.options.excludeIEPlugins||e.push({key:"ie_plugins",value:this.getIEPlugins()}):e.push({key:"regular_plugins",value:this.getRegularPlugins()})),e},getRegularPlugins:function(){for(var e=[],t=0,i=navigator.plugins.length;i>t;t++)e.push(navigator.plugins[t]);return this.pluginsShouldBeSorted()&&(e=e.sort(function(e,t){return e.name>t.name?1:e.namet;t++){var a=this.options.sortPluginsFor[t];if(navigator.userAgent.match(a)){e=!0;break}}return e},touchSupportKey:function(e){return this.options.excludeTouchSupport||e.push({key:"touch_support",value:this.getTouchSupport()}),e},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return!0}},hasIndexedDB:function(){return!!window.indexedDB},getNavigatorCpuClass:function(){return navigator.cpuClass?navigator.cpuClass:"unknown"},getNavigatorPlatform:function(){return navigator.platform?navigator.platform:"unknown"},getDoNotTrack:function(){return navigator.doNotTrack?navigator.doNotTrack:"unknown"},getTouchSupport:function(){var e=0,t=!1;"undefined"!=typeof navigator.maxTouchPoints?e=navigator.maxTouchPoints:"undefined"!=typeof navigator.msMaxTouchPoints&&(e=navigator.msMaxTouchPoints);try{document.createEvent("TouchEvent"),t=!0}catch(i){}var a="ontouchstart"in window;return[e,t,a]},getCanvasFp:function(){var e=[],t=document.createElement("canvas");t.width=2e3,t.height=200,t.style.display="inline";var i=t.getContext("2d");return i.rect(0,0,10,10),i.rect(2,2,6,6),e.push("canvas winding:"+(i.isPointInPath(5,5,"evenodd")===!1?"yes":"no")),i.textBaseline="alphabetic",i.fillStyle="#f60",i.fillRect(125,1,62,20),i.fillStyle="#069",this.options.dontUseFakeFontInCanvas?i.font="11pt Arial":i.font="11pt no-real-font-123",i.fillText("Cwm fjordbank glyphs vext quiz, 😃",2,15),i.fillStyle="rgba(102, 204, 0, 0.2)",i.font="18pt Arial",i.fillText("Cwm fjordbank glyphs vext quiz, 😃",4,45),i.globalCompositeOperation="multiply",i.fillStyle="rgb(255,0,255)",i.beginPath(),i.arc(50,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(0,255,255)",i.beginPath(),i.arc(100,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,255,0)",i.beginPath(),i.arc(75,100,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,0,255)",i.arc(75,75,75,0,2*Math.PI,!0),i.arc(75,75,25,0,2*Math.PI,!0),i.fill("evenodd"),e.push("canvas fp:"+t.toDataURL()),e.join("~")},getWebglFp:function(){var e,t=function(t){return e.clearColor(0,0,0,1),e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),"["+t[0]+", "+t[1]+"]"},i=function(e){var t,i=e.getExtension("EXT_texture_filter_anisotropic")||e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||e.getExtension("MOZ_EXT_texture_filter_anisotropic");return i?(t=e.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT),0===t&&(t=2),t):null};if(e=this.getWebglCanvas(),!e)return null;var a=[],r="attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}",n="precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}",o=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,o);var s=new Float32Array([-.2,-.9,0,.4,-.26,0,0,.732134444,0]);e.bufferData(e.ARRAY_BUFFER,s,e.STATIC_DRAW),o.itemSize=3,o.numItems=3;var l=e.createProgram(),h=e.createShader(e.VERTEX_SHADER);e.shaderSource(h,r),e.compileShader(h);var u=e.createShader(e.FRAGMENT_SHADER);return e.shaderSource(u,n),e.compileShader(u),e.attachShader(l,h),e.attachShader(l,u),e.linkProgram(l),e.useProgram(l),l.vertexPosAttrib=e.getAttribLocation(l,"attrVertex"),l.offsetUniform=e.getUniformLocation(l,"uniformOffset"),e.enableVertexAttribArray(l.vertexPosArray),e.vertexAttribPointer(l.vertexPosAttrib,o.itemSize,e.FLOAT,!1,0,0),e.uniform2f(l.offsetUniform,1,1),e.drawArrays(e.TRIANGLE_STRIP,0,o.numItems),null!=e.canvas&&a.push(e.canvas.toDataURL()),a.push("extensions:"+e.getSupportedExtensions().join(";")),a.push("webgl aliased line width range:"+t(e.getParameter(e.ALIASED_LINE_WIDTH_RANGE))),a.push("webgl aliased point size range:"+t(e.getParameter(e.ALIASED_POINT_SIZE_RANGE))),a.push("webgl alpha bits:"+e.getParameter(e.ALPHA_BITS)),a.push("webgl antialiasing:"+(e.getContextAttributes().antialias?"yes":"no")),a.push("webgl blue bits:"+e.getParameter(e.BLUE_BITS)),a.push("webgl depth bits:"+e.getParameter(e.DEPTH_BITS)),a.push("webgl green bits:"+e.getParameter(e.GREEN_BITS)),a.push("webgl max anisotropy:"+i(e)),a.push("webgl max combined texture image units:"+e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS)),a.push("webgl max cube map texture size:"+e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE)),a.push("webgl max fragment uniform vectors:"+e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS)),a.push("webgl max render buffer size:"+e.getParameter(e.MAX_RENDERBUFFER_SIZE)),a.push("webgl max texture image units:"+e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)),a.push("webgl max texture size:"+e.getParameter(e.MAX_TEXTURE_SIZE)),a.push("webgl max varying vectors:"+e.getParameter(e.MAX_VARYING_VECTORS)),a.push("webgl max vertex attribs:"+e.getParameter(e.MAX_VERTEX_ATTRIBS)),a.push("webgl max vertex texture image units:"+e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS)),a.push("webgl max vertex uniform vectors:"+e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS)),a.push("webgl max viewport dims:"+t(e.getParameter(e.MAX_VIEWPORT_DIMS))),a.push("webgl red bits:"+e.getParameter(e.RED_BITS)),a.push("webgl renderer:"+e.getParameter(e.RENDERER)),a.push("webgl shading language version:"+e.getParameter(e.SHADING_LANGUAGE_VERSION)),a.push("webgl stencil bits:"+e.getParameter(e.STENCIL_BITS)),a.push("webgl vendor:"+e.getParameter(e.VENDOR)),a.push("webgl version:"+e.getParameter(e.VERSION)),e.getShaderPrecisionFormat?(a.push("webgl vertex shader high float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).precision),a.push("webgl vertex shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMin),a.push("webgl vertex shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMax),a.push("webgl vertex shader medium float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision),a.push("webgl vertex shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMin),a.push("webgl vertex shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMax),a.push("webgl vertex shader low float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).precision),a.push("webgl vertex shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMin),a.push("webgl vertex shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMax),a.push("webgl fragment shader high float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision),a.push("webgl fragment shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMin),a.push("webgl fragment shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMax),a.push("webgl fragment shader medium float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision),a.push("webgl fragment shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMin),a.push("webgl fragment shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMax),a.push("webgl fragment shader low float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).precision),a.push("webgl fragment shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMin),a.push("webgl fragment shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMax),a.push("webgl vertex shader high int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).precision),a.push("webgl vertex shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMin),a.push("webgl vertex shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMax),a.push("webgl vertex shader medium int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).precision),a.push("webgl vertex shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMin),a.push("webgl vertex shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMax),a.push("webgl vertex shader low int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).precision),a.push("webgl vertex shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMin),a.push("webgl vertex shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMax),a.push("webgl fragment shader high int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).precision),a.push("webgl fragment shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMin),a.push("webgl fragment shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMax),a.push("webgl fragment shader medium int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).precision),a.push("webgl fragment shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMin),a.push("webgl fragment shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMax),a.push("webgl fragment shader low int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).precision),a.push("webgl fragment shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMin),a.push("webgl fragment shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMax),a.join("~")):a.join("~")},getAdBlock:function(){var e=document.createElement("div");e.innerHTML=" ",e.className="adsbox";var t=!1;try{document.body.appendChild(e),t=0===document.getElementsByClassName("adsbox")[0].offsetHeight,document.body.removeChild(e)}catch(i){t=!1}return t},getHasLiedLanguages:function(){if("undefined"!=typeof navigator.languages)try{var e=navigator.languages[0].substr(0,2);if(e!==navigator.language.substr(0,2))return!0}catch(t){return!0}return!1},getHasLiedResolution:function(){return screen.width=0?"Windows Phone":t.indexOf("win")>=0?"Windows":t.indexOf("android")>=0?"Android":t.indexOf("linux")>=0?"Linux":t.indexOf("iphone")>=0||t.indexOf("ipad")>=0?"iOS":t.indexOf("mac")>=0?"Mac":"Other";var r;if(r="ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0,r&&"Windows Phone"!==e&&"Android"!==e&&"iOS"!==e&&"Other"!==e)return!0;if("undefined"!=typeof i){if(i=i.toLowerCase(),i.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e)return!0;if(i.indexOf("linux")>=0&&"Linux"!==e&&"Android"!==e)return!0;if(i.indexOf("mac")>=0&&"Mac"!==e&&"iOS"!==e)return!0;if(0===i.indexOf("win")&&0===i.indexOf("linux")&&i.indexOf("mac")>=0&&"other"!==e)return!0}return a.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e?!0:(a.indexOf("linux")>=0||a.indexOf("android")>=0||a.indexOf("pike")>=0)&&"Linux"!==e&&"Android"!==e?!0:(a.indexOf("mac")>=0||a.indexOf("ipad")>=0||a.indexOf("ipod")>=0||a.indexOf("iphone")>=0)&&"Mac"!==e&&"iOS"!==e?!0:0===a.indexOf("win")&&0===a.indexOf("linux")&&a.indexOf("mac")>=0&&"other"!==e?!0:"undefined"==typeof navigator.plugins&&"Windows"!==e&&"Windows Phone"!==e},getHasLiedBrowser:function(){var e,t=navigator.userAgent.toLowerCase(),i=navigator.productSub;if(e=t.indexOf("firefox")>=0?"Firefox":t.indexOf("opera")>=0||t.indexOf("opr")>=0?"Opera":t.indexOf("chrome")>=0?"Chrome":t.indexOf("safari")>=0?"Safari":t.indexOf("trident")>=0?"Internet Explorer":"Other",("Chrome"===e||"Safari"===e||"Opera"===e)&&"20030107"!==i)return!0;var a=eval.toString().length;if(37===a&&"Safari"!==e&&"Firefox"!==e&&"Other"!==e)return!0;if(39===a&&"Internet Explorer"!==e&&"Other"!==e)return!0;if(33===a&&"Chrome"!==e&&"Opera"!==e&&"Other"!==e)return!0;var r;try{throw"a"}catch(n){try{n.toSource(),r=!0}catch(o){r=!1}}return!(!r||"Firefox"===e||"Other"===e)},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isWebGlSupported:function(){if(!this.isCanvasSupported())return!1;var e,t=document.createElement("canvas");try{e=t.getContext&&(t.getContext("webgl")||t.getContext("experimental-webgl"))}catch(i){e=!1}return!!window.WebGLRenderingContext&&!!e},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName?!0:!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},hasSwfObjectLoaded:function(){return"undefined"!=typeof window.swfobject},hasMinFlashInstalled:function(){return swfobject.hasFlashPlayerVersion("9.0.0")},addFlashDivNode:function(){var e=document.createElement("div");e.setAttribute("id",this.options.swfContainerId),document.body.appendChild(e)},loadSwfAndDetectFonts:function(e){var t="___fp_swf_loaded";window[t]=function(t){e(t)};var i=this.options.swfContainerId;this.addFlashDivNode();var a={onReady:t},r={allowScriptAccess:"always",menu:"false"};swfobject.embedSWF(this.options.swfPath,i,"1","1","9.0.0",!1,a,r,{})},getWebglCanvas:function(){var e=document.createElement("canvas"),t=null;try{t=e.getContext("webgl")||e.getContext("experimental-webgl")}catch(i){}return t||(t=null),t},each:function(e,t,i){if(null!==e)if(this.nativeForEach&&e.forEach===this.nativeForEach)e.forEach(t,i);else if(e.length===+e.length){for(var a=0,r=e.length;r>a;a++)if(t.call(i,e[a],a,e)==={})return}else for(var n in e)if(e.hasOwnProperty(n)&&t.call(i,e[n],n,e)==={})return},map:function(e,t,i){var a=[];return null==e?a:this.nativeMap&&e.map===this.nativeMap?e.map(t,i):(this.each(e,function(e,r,n){a[a.length]=t.call(i,e,r,n)}),a)},x64Add:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]+t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]+t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]+t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]+t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Multiply:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]*t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]*t[3],i[1]+=i[2]>>>16,i[2]&=65535,i[2]+=e[3]*t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]*t[3],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[2]*t[2],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[3]*t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Rotl:function(e,t){return t%=64,32===t?[e[1],e[0]]:32>t?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])},x64LeftShift:function(e,t){return t%=64,0===t?e:32>t?[e[0]<>>32-t,e[1]<>>1]),e=this.x64Multiply(e,[4283543511,3981806797]),e=this.x64Xor(e,[0,e[0]>>>1]),e=this.x64Multiply(e,[3301882366,444984403]),e=this.x64Xor(e,[0,e[0]>>>1])},x64hash128:function(e,t){e=e||"",t=t||0;for(var i=e.length%16,a=e.length-i,r=[0,t],n=[0,t],o=[0,0],s=[0,0],l=[2277735313,289559509],h=[1291169091,658871167],u=0;a>u;u+=16)o=[255&e.charCodeAt(u+4)|(255&e.charCodeAt(u+5))<<8|(255&e.charCodeAt(u+6))<<16|(255&e.charCodeAt(u+7))<<24,255&e.charCodeAt(u)|(255&e.charCodeAt(u+1))<<8|(255&e.charCodeAt(u+2))<<16|(255&e.charCodeAt(u+3))<<24],s=[255&e.charCodeAt(u+12)|(255&e.charCodeAt(u+13))<<8|(255&e.charCodeAt(u+14))<<16|(255&e.charCodeAt(u+15))<<24,255&e.charCodeAt(u+8)|(255&e.charCodeAt(u+9))<<8|(255&e.charCodeAt(u+10))<<16|(255&e.charCodeAt(u+11))<<24],o=this.x64Multiply(o,l),o=this.x64Rotl(o,31),o=this.x64Multiply(o,h),r=this.x64Xor(r,o),r=this.x64Rotl(r,27),r=this.x64Add(r,n),r=this.x64Add(this.x64Multiply(r,[0,5]),[0,1390208809]), -s=this.x64Multiply(s,h),s=this.x64Rotl(s,33),s=this.x64Multiply(s,l),n=this.x64Xor(n,s),n=this.x64Rotl(n,31),n=this.x64Add(n,r),n=this.x64Add(this.x64Multiply(n,[0,5]),[0,944331445]);switch(o=[0,0],s=[0,0],i){case 15:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+14)],48));case 14:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+13)],40));case 13:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+12)],32));case 12:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+11)],24));case 11:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+10)],16));case 10:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+9)],8));case 9:s=this.x64Xor(s,[0,e.charCodeAt(u+8)]),s=this.x64Multiply(s,h),s=this.x64Rotl(s,33),s=this.x64Multiply(s,l),n=this.x64Xor(n,s);case 8:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+7)],56));case 7:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+6)],48));case 6:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+5)],40));case 5:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+4)],32));case 4:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+3)],24));case 3:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+2)],16));case 2:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+1)],8));case 1:o=this.x64Xor(o,[0,e.charCodeAt(u)]),o=this.x64Multiply(o,l),o=this.x64Rotl(o,31),o=this.x64Multiply(o,h),r=this.x64Xor(r,o)}return r=this.x64Xor(r,[0,e.length]),n=this.x64Xor(n,[0,e.length]),r=this.x64Add(r,n),n=this.x64Add(n,r),r=this.x64Fmix(r),n=this.x64Fmix(n),r=this.x64Add(r,n),n=this.x64Add(n,r),("00000000"+(r[0]>>>0).toString(16)).slice(-8)+("00000000"+(r[1]>>>0).toString(16)).slice(-8)+("00000000"+(n[0]>>>0).toString(16)).slice(-8)+("00000000"+(n[1]>>>0).toString(16)).slice(-8)}},e.VERSION="1.4.0",e}); \ No newline at end of file +!function(e,t,i){"use strict";"undefined"!=typeof module&&module.exports?module.exports=i():"function"==typeof define&&define.amd?define(i):t[e]=i()}("Fingerprint2",this,function(){"use strict";Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){var i;if(null==this)throw new TypeError("'this' is null or undefined");var a=Object(this),r=a.length>>>0;if(0===r)return-1;var n=+t||0;if(Math.abs(n)===1/0&&(n=0),n>=r)return-1;for(i=Math.max(n>=0?n:r-Math.abs(n),0);r>i;){if(i in a&&a[i]===e)return i;i++}return-1});var e=function(e){var t={swfContainerId:"fingerprintjs2",swfPath:"flash/compiled/FontList.swf",detectScreenOrientation:!0,sortPluginsFor:[/palemoon/i],userDefinedFonts:[]};this.options=this.extend(e,t),this.nativeForEach=Array.prototype.forEach,this.nativeMap=Array.prototype.map};return e.prototype={extend:function(e,t){if(null==e)return t;for(var i in e)null!=e[i]&&t[i]!==e[i]&&(t[i]=e[i]);return t},log:function(e){window.console&&console.log(e)},get:function(e){var t=[];t=this.userAgentKey(t),t=this.languageKey(t),t=this.colorDepthKey(t),t=this.pixelRatioKey(t),t=this.screenResolutionKey(t),t=this.availableScreenResolutionKey(t),t=this.timezoneOffsetKey(t),t=this.sessionStorageKey(t),t=this.localStorageKey(t),t=this.indexedDbKey(t),t=this.addBehaviorKey(t),t=this.openDatabaseKey(t),t=this.cpuClassKey(t),t=this.platformKey(t),t=this.doNotTrackKey(t),t=this.pluginsKey(t),t=this.canvasKey(t),t=this.webglKey(t),t=this.adBlockKey(t),t=this.hasLiedLanguagesKey(t),t=this.hasLiedResolutionKey(t),t=this.hasLiedOsKey(t),t=this.hasLiedBrowserKey(t),t=this.touchSupportKey(t);var i=this;this.fontsKey(t,function(t){var a=[];i.each(t,function(e){var t=e.value;"undefined"!=typeof e.value.join&&(t=e.value.join(";")),a.push(t)});var r=i.x64hash128(a.join("~~~"),31);return e(r,t)})},userAgentKey:function(e){return this.options.excludeUserAgent||e.push({key:"user_agent",value:this.getUserAgent()}),e},getUserAgent:function(){return navigator.userAgent},languageKey:function(e){return this.options.excludeLanguage||e.push({key:"language",value:navigator.language||navigator.userLanguage||navigator.browserLanguage||navigator.systemLanguage||""}),e},colorDepthKey:function(e){return this.options.excludeColorDepth||e.push({key:"color_depth",value:screen.colorDepth}),e},pixelRatioKey:function(e){return this.options.excludePixelRatio||e.push({key:"pixel_ratio",value:this.getPixelRatio()}),e},getPixelRatio:function(){return window.devicePixelRatio||""},screenResolutionKey:function(e){return this.options.excludeScreenResolution?e:this.getScreenResolution(e)},getScreenResolution:function(e){var t;return t=this.options.detectScreenOrientation&&screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height],"undefined"!=typeof t&&e.push({key:"resolution",value:t}),e},availableScreenResolutionKey:function(e){return this.options.excludeAvailableScreenResolution?e:this.getAvailableScreenResolution(e)},getAvailableScreenResolution:function(e){var t;return screen.availWidth&&screen.availHeight&&(t=this.options.detectScreenOrientation?screen.availHeight>screen.availWidth?[screen.availHeight,screen.availWidth]:[screen.availWidth,screen.availHeight]:[screen.availHeight,screen.availWidth]),"undefined"!=typeof t&&e.push({key:"available_resolution",value:t}),e},timezoneOffsetKey:function(e){return this.options.excludeTimezoneOffset||e.push({key:"timezone_offset",value:(new Date).getTimezoneOffset()}),e},sessionStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasSessionStorage()&&e.push({key:"session_storage",value:1}),e},localStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasLocalStorage()&&e.push({key:"local_storage",value:1}),e},indexedDbKey:function(e){return!this.options.excludeIndexedDB&&this.hasIndexedDB()&&e.push({key:"indexed_db",value:1}),e},addBehaviorKey:function(e){return document.body&&!this.options.excludeAddBehavior&&document.body.addBehavior&&e.push({key:"add_behavior",value:1}),e},openDatabaseKey:function(e){return!this.options.excludeOpenDatabase&&window.openDatabase&&e.push({key:"open_database",value:1}),e},cpuClassKey:function(e){return this.options.excludeCpuClass||e.push({key:"cpu_class",value:this.getNavigatorCpuClass()}),e},platformKey:function(e){return this.options.excludePlatform||e.push({key:"navigator_platform",value:this.getNavigatorPlatform()}),e},doNotTrackKey:function(e){return this.options.excludeDoNotTrack||e.push({key:"do_not_track",value:this.getDoNotTrack()}),e},canvasKey:function(e){return!this.options.excludeCanvas&&this.isCanvasSupported()&&e.push({key:"canvas",value:this.getCanvasFp()}),e},webglKey:function(e){return this.options.excludeWebGL?e:this.isWebGlSupported()?(e.push({key:"webgl",value:this.getWebglFp()}),e):e},adBlockKey:function(e){return this.options.excludeAdBlock||e.push({key:"adblock",value:this.getAdBlock()}),e},hasLiedLanguagesKey:function(e){return this.options.excludeHasLiedLanguages||e.push({key:"has_lied_languages",value:this.getHasLiedLanguages()}),e},hasLiedResolutionKey:function(e){return this.options.excludeHasLiedResolution||e.push({key:"has_lied_resolution",value:this.getHasLiedResolution()}),e},hasLiedOsKey:function(e){return this.options.excludeHasLiedOs||e.push({key:"has_lied_os",value:this.getHasLiedOs()}),e},hasLiedBrowserKey:function(e){return this.options.excludeHasLiedBrowser||e.push({key:"has_lied_browser",value:this.getHasLiedBrowser()}),e},fontsKey:function(e,t){return this.options.excludeJsFonts?this.flashFontsKey(e,t):this.jsFontsKey(e,t)},flashFontsKey:function(e,t){return this.options.excludeFlashFonts?t(e):this.hasSwfObjectLoaded()&&this.hasMinFlashInstalled()?"undefined"==typeof this.options.swfPath?t(e):void this.loadSwfAndDetectFonts(function(i){e.push({key:"swf_fonts",value:i.join(";")}),t(e)}):t(e)},jsFontsKey:function(e,t){var i=this;return setTimeout(function(){var a=["monospace","sans-serif","serif"],r=["Andale Mono","Arial","Arial Black","Arial Hebrew","Arial MT","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS","Bitstream Vera Sans Mono","Book Antiqua","Bookman Old Style","Calibri","Cambria","Cambria Math","Century","Century Gothic","Century Schoolbook","Comic Sans","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Helvetica","Helvetica Neue","Impact","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","LUCIDA GRANDE","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Monotype Corsiva","MS Gothic","MS Outlook","MS PGothic","MS Reference Sans Serif","MS Sans Serif","MS Serif","MYRIAD","MYRIAD PRO","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Segoe UI Light","Segoe UI Semibold","Segoe UI Symbol","Tahoma","Times","Times New Roman","Times New Roman PS","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3"],n=["Abadi MT Condensed Light","Academy Engraved LET","ADOBE CASLON PRO","Adobe Garamond","ADOBE GARAMOND PRO","Agency FB","Aharoni","Albertus Extra Bold","Albertus Medium","Algerian","Amazone BT","American Typewriter","American Typewriter Condensed","AmerType Md BT","Andalus","Angsana New","AngsanaUPC","Antique Olive","Aparajita","Apple Chancery","Apple Color Emoji","Apple SD Gothic Neo","Arabic Typesetting","ARCHER","ARNO PRO","Arrus BT","Aurora Cn BT","AvantGarde Bk BT","AvantGarde Md BT","AVENIR","Ayuthaya","Bandy","Bangla Sangam MN","Bank Gothic","BankGothic Md BT","Baskerville","Baskerville Old Face","Batang","BatangChe","Bauer Bodoni","Bauhaus 93","Bazooka","Bell MT","Bembo","Benguiat Bk BT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","BernhardFashion BT","BernhardMod BT","Big Caslon","BinnerD","Blackadder ITC","BlairMdITC TT","Bodoni 72","Bodoni 72 Oldstyle","Bodoni 72 Smallcaps","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Bookshelf Symbol 7","Boulder","Bradley Hand","Bradley Hand ITC","Bremen Bd BT","Britannic Bold","Broadway","Browallia New","BrowalliaUPC","Brush Script MT","Californian FB","Calisto MT","Calligrapher","Candara","CaslonOpnface BT","Castellar","Centaur","Cezanne","CG Omega","CG Times","Chalkboard","Chalkboard SE","Chalkduster","Charlesworth","Charter Bd BT","Charter BT","Chaucer","ChelthmITC Bk BT","Chiller","Clarendon","Clarendon Condensed","CloisterBlack BT","Cochin","Colonna MT","Constantia","Cooper Black","Copperplate","Copperplate Gothic","Copperplate Gothic Bold","Copperplate Gothic Light","CopperplGoth Bd BT","Corbel","Cordia New","CordiaUPC","Cornerstone","Coronet","Cuckoo","Curlz MT","DaunPenh","Dauphin","David","DB LCD Temp","DELICIOUS","Denmark","DFKai-SB","Didot","DilleniaUPC","DIN","DokChampa","Dotum","DotumChe","Ebrima","Edwardian Script ITC","Elephant","English 111 Vivace BT","Engravers MT","EngraversGothic BT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","EucrosiaUPC","Euphemia","Euphemia UCAS","EUROSTILE","Exotc350 Bd BT","FangSong","Felix Titling","Fixedsys","FONTIN","Footlight MT Light","Forte","FrankRuehl","Fransiscan","Freefrm721 Blk BT","FreesiaUPC","Freestyle Script","French Script MT","FrnkGothITC Bk BT","Fruitger","FRUTIGER","Futura","Futura Bk BT","Futura Lt BT","Futura Md BT","Futura ZBlk BT","FuturaBlack BT","Gabriola","Galliard BT","Gautami","Geeza Pro","Geometr231 BT","Geometr231 Hv BT","Geometr231 Lt BT","GeoSlab 703 Lt BT","GeoSlab 703 XBd BT","Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed","Gisha","Gloucester MT Extra Condensed","GOTHAM","GOTHAM BOLD","Goudy Old Style","Goudy Stout","GoudyHandtooled BT","GoudyOLSt BT","Gujarati Sangam MN","Gulim","GulimChe","Gungsuh","GungsuhChe","Gurmukhi MN","Haettenschweiler","Harlow Solid Italic","Harrington","Heather","Heiti SC","Heiti TC","HELV","Herald","High Tower Text","Hiragino Kaku Gothic ProN","Hiragino Mincho ProN","Hoefler Text","Humanst 521 Cn BT","Humanst521 BT","Humanst521 Lt BT","Imprint MT Shadow","Incised901 Bd BT","Incised901 BT","Incised901 Lt BT","INCONSOLATA","Informal Roman","Informal011 BT","INTERSTATE","IrisUPC","Iskoola Pota","JasmineUPC","Jazz LET","Jenson","Jester","Jokerman","Juice ITC","Kabel Bk BT","Kabel Ult BT","Kailasa","KaiTi","Kalinga","Kannada Sangam MN","Kartika","Kaufmann Bd BT","Kaufmann BT","Khmer UI","KodchiangUPC","Kokila","Korinna BT","Kristen ITC","Krungthep","Kunstler Script","Lao UI","Latha","Leelawadee","Letter Gothic","Levenim MT","LilyUPC","Lithograph","Lithograph Light","Long Island","Lydian BT","Magneto","Maiandra GD","Malayalam Sangam MN","Malgun Gothic","Mangal","Marigold","Marion","Marker Felt","Market","Marlett","Matisse ITC","Matura MT Script Capitals","Meiryo","Meiryo UI","Microsoft Himalaya","Microsoft JhengHei","Microsoft New Tai Lue","Microsoft PhagsPa","Microsoft Tai Le","Microsoft Uighur","Microsoft YaHei","Microsoft Yi Baiti","MingLiU","MingLiU_HKSCS","MingLiU_HKSCS-ExtB","MingLiU-ExtB","Minion","Minion Pro","Miriam","Miriam Fixed","Mistral","Modern","Modern No. 20","Mona Lisa Solid ITC TT","Mongolian Baiti","MONO","MoolBoran","Mrs Eaves","MS LineDraw","MS Mincho","MS PMincho","MS Reference Specialty","MS UI Gothic","MT Extra","MUSEO","MV Boli","Nadeem","Narkisim","NEVIS","News Gothic","News GothicMT","NewsGoth BT","Niagara Engraved","Niagara Solid","Noteworthy","NSimSun","Nyala","OCR A Extended","Old Century","Old English Text MT","Onyx","Onyx BT","OPTIMA","Oriya Sangam MN","OSAKA","OzHandicraft BT","Palace Script MT","Papyrus","Parchment","Party LET","Pegasus","Perpetua","Perpetua Titling MT","PetitaBold","Pickwick","Plantagenet Cherokee","Playbill","PMingLiU","PMingLiU-ExtB","Poor Richard","Poster","PosterBodoni BT","PRINCETOWN LET","Pristina","PTBarnum BT","Pythagoras","Raavi","Rage Italic","Ravie","Ribbon131 Bd BT","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Rod","Roman","Sakkal Majalla","Santa Fe LET","Savoye LET","Sceptre","Script","Script MT Bold","SCRIPTINA","Serifa","Serifa BT","Serifa Th BT","ShelleyVolante BT","Sherwood","Shonar Bangla","Showcard Gothic","Shruti","Signboard","SILKSCREEN","SimHei","Simplified Arabic","Simplified Arabic Fixed","SimSun","SimSun-ExtB","Sinhala Sangam MN","Sketch Rockwell","Skia","Small Fonts","Snap ITC","Snell Roundhand","Socket","Souvenir Lt BT","Staccato222 BT","Steamer","Stencil","Storybook","Styllo","Subway","Swis721 BlkEx BT","Swiss911 XCm BT","Sylfaen","Synchro LET","System","Tamil Sangam MN","Technical","Teletype","Telugu Sangam MN","Tempus Sans ITC","Terminal","Thonburi","Traditional Arabic","Trajan","TRAJAN PRO","Tristan","Tubular","Tunga","Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","TypoUpright BT","Unicorn","Univers","Univers CE 55 Medium","Univers Condensed","Utsaah","Vagabond","Vani","Vijaya","Viner Hand ITC","VisualUI","Vivaldi","Vladimir Script","Vrinda","Westminster","WHITNEY","Wide Latin","ZapfEllipt BT","ZapfHumnst BT","ZapfHumnst Dm BT","Zapfino","Zurich BlkEx BT","Zurich Ex BT","ZWAdobeF"];i.options.extendedJsFonts&&(r=r.concat(n)),r=r.concat(i.options.userDefinedFonts);var o="mmmmmmmmmmlli",s="72px",l=document.getElementsByTagName("body")[0],h=document.createElement("div"),u=document.createElement("div"),d={},c={},g=function(){var e=document.createElement("span");return e.style.position="absolute",e.style.left="-9999px",e.style.fontSize=s,e.innerHTML=o,e},p=function(e,t){var i=g();return i.style.fontFamily="'"+e+"',"+t,i},f=function(){for(var e=[],t=0,i=a.length;i>t;t++){var r=g();r.style.fontFamily=a[t],h.appendChild(r),e.push(r)}return e},m=function(){for(var e={},t=0,i=r.length;i>t;t++){for(var n=[],o=0,s=a.length;s>o;o++){var l=p(r[t],a[o]);u.appendChild(l),n.push(l)}e[r[t]]=n}return e},S=function(e){for(var t=!1,i=0;ix;x++)d[a[x]]=T[x].offsetWidth,c[a[x]]=T[x].offsetHeight;var M=m();l.appendChild(u);for(var A=[],E=0,y=r.length;y>E;E++)S(M[r[E]])&&A.push(r[E]);l.removeChild(u),l.removeChild(h),e.push({key:"js_fonts",value:A}),t(e)},1)},pluginsKey:function(e){return this.options.excludePlugins||(this.isIE()?this.options.excludeIEPlugins||e.push({key:"ie_plugins",value:this.getIEPlugins()}):e.push({key:"regular_plugins",value:this.getRegularPlugins()})),e},getRegularPlugins:function(){for(var e=[],t=0,i=navigator.plugins.length;i>t;t++)e.push(navigator.plugins[t]);return this.pluginsShouldBeSorted()&&(e=e.sort(function(e,t){return e.name>t.name?1:e.namet;t++){var a=this.options.sortPluginsFor[t];if(navigator.userAgent.match(a)){e=!0;break}}return e},touchSupportKey:function(e){return this.options.excludeTouchSupport||e.push({key:"touch_support",value:this.getTouchSupport()}),e},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return!0}},hasIndexedDB:function(){return!!window.indexedDB},getNavigatorCpuClass:function(){return navigator.cpuClass?navigator.cpuClass:"unknown"},getNavigatorPlatform:function(){return navigator.platform?navigator.platform:"unknown"},getDoNotTrack:function(){return navigator.doNotTrack?navigator.doNotTrack:"unknown"},getTouchSupport:function(){var e=0,t=!1;"undefined"!=typeof navigator.maxTouchPoints?e=navigator.maxTouchPoints:"undefined"!=typeof navigator.msMaxTouchPoints&&(e=navigator.msMaxTouchPoints);try{document.createEvent("TouchEvent"),t=!0}catch(i){}var a="ontouchstart"in window;return[e,t,a]},getCanvasFp:function(){var e=[],t=document.createElement("canvas");t.width=2e3,t.height=200,t.style.display="inline";var i=t.getContext("2d");return i.rect(0,0,10,10),i.rect(2,2,6,6),e.push("canvas winding:"+(i.isPointInPath(5,5,"evenodd")===!1?"yes":"no")),i.textBaseline="alphabetic",i.fillStyle="#f60",i.fillRect(125,1,62,20),i.fillStyle="#069",this.options.dontUseFakeFontInCanvas?i.font="11pt Arial":i.font="11pt no-real-font-123",i.fillText("Cwm fjordbank glyphs vext quiz, 😃",2,15),i.fillStyle="rgba(102, 204, 0, 0.2)",i.font="18pt Arial",i.fillText("Cwm fjordbank glyphs vext quiz, 😃",4,45),i.globalCompositeOperation="multiply",i.fillStyle="rgb(255,0,255)",i.beginPath(),i.arc(50,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(0,255,255)",i.beginPath(),i.arc(100,50,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,255,0)",i.beginPath(),i.arc(75,100,50,0,2*Math.PI,!0),i.closePath(),i.fill(),i.fillStyle="rgb(255,0,255)",i.arc(75,75,75,0,2*Math.PI,!0),i.arc(75,75,25,0,2*Math.PI,!0),i.fill("evenodd"),e.push("canvas fp:"+t.toDataURL()),e.join("~")},getWebglFp:function(){var e,t=function(t){return e.clearColor(0,0,0,1),e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),"["+t[0]+", "+t[1]+"]"},i=function(e){var t,i=e.getExtension("EXT_texture_filter_anisotropic")||e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||e.getExtension("MOZ_EXT_texture_filter_anisotropic");return i?(t=e.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT),0===t&&(t=2),t):null};if(e=this.getWebglCanvas(),!e)return null;var a=[],r="attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}",n="precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}",o=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,o);var s=new Float32Array([-.2,-.9,0,.4,-.26,0,0,.732134444,0]);e.bufferData(e.ARRAY_BUFFER,s,e.STATIC_DRAW),o.itemSize=3,o.numItems=3;var l=e.createProgram(),h=e.createShader(e.VERTEX_SHADER);e.shaderSource(h,r),e.compileShader(h);var u=e.createShader(e.FRAGMENT_SHADER);return e.shaderSource(u,n),e.compileShader(u),e.attachShader(l,h),e.attachShader(l,u),e.linkProgram(l),e.useProgram(l),l.vertexPosAttrib=e.getAttribLocation(l,"attrVertex"),l.offsetUniform=e.getUniformLocation(l,"uniformOffset"),e.enableVertexAttribArray(l.vertexPosArray),e.vertexAttribPointer(l.vertexPosAttrib,o.itemSize,e.FLOAT,!1,0,0),e.uniform2f(l.offsetUniform,1,1),e.drawArrays(e.TRIANGLE_STRIP,0,o.numItems),null!=e.canvas&&a.push(e.canvas.toDataURL()),a.push("extensions:"+e.getSupportedExtensions().join(";")),a.push("webgl aliased line width range:"+t(e.getParameter(e.ALIASED_LINE_WIDTH_RANGE))),a.push("webgl aliased point size range:"+t(e.getParameter(e.ALIASED_POINT_SIZE_RANGE))),a.push("webgl alpha bits:"+e.getParameter(e.ALPHA_BITS)),a.push("webgl antialiasing:"+(e.getContextAttributes().antialias?"yes":"no")),a.push("webgl blue bits:"+e.getParameter(e.BLUE_BITS)),a.push("webgl depth bits:"+e.getParameter(e.DEPTH_BITS)),a.push("webgl green bits:"+e.getParameter(e.GREEN_BITS)),a.push("webgl max anisotropy:"+i(e)),a.push("webgl max combined texture image units:"+e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS)),a.push("webgl max cube map texture size:"+e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE)),a.push("webgl max fragment uniform vectors:"+e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS)),a.push("webgl max render buffer size:"+e.getParameter(e.MAX_RENDERBUFFER_SIZE)),a.push("webgl max texture image units:"+e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)),a.push("webgl max texture size:"+e.getParameter(e.MAX_TEXTURE_SIZE)),a.push("webgl max varying vectors:"+e.getParameter(e.MAX_VARYING_VECTORS)),a.push("webgl max vertex attribs:"+e.getParameter(e.MAX_VERTEX_ATTRIBS)),a.push("webgl max vertex texture image units:"+e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS)),a.push("webgl max vertex uniform vectors:"+e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS)),a.push("webgl max viewport dims:"+t(e.getParameter(e.MAX_VIEWPORT_DIMS))),a.push("webgl red bits:"+e.getParameter(e.RED_BITS)),a.push("webgl renderer:"+e.getParameter(e.RENDERER)),a.push("webgl shading language version:"+e.getParameter(e.SHADING_LANGUAGE_VERSION)),a.push("webgl stencil bits:"+e.getParameter(e.STENCIL_BITS)),a.push("webgl vendor:"+e.getParameter(e.VENDOR)),a.push("webgl version:"+e.getParameter(e.VERSION)),e.getShaderPrecisionFormat?(a.push("webgl vertex shader high float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).precision),a.push("webgl vertex shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMin),a.push("webgl vertex shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_FLOAT).rangeMax),a.push("webgl vertex shader medium float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision),a.push("webgl vertex shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMin),a.push("webgl vertex shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).rangeMax),a.push("webgl vertex shader low float precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).precision),a.push("webgl vertex shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMin),a.push("webgl vertex shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_FLOAT).rangeMax),a.push("webgl fragment shader high float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision),a.push("webgl fragment shader high float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMin),a.push("webgl fragment shader high float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).rangeMax),a.push("webgl fragment shader medium float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision),a.push("webgl fragment shader medium float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMin),a.push("webgl fragment shader medium float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).rangeMax),a.push("webgl fragment shader low float precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).precision),a.push("webgl fragment shader low float precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMin),a.push("webgl fragment shader low float precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT).rangeMax),a.push("webgl vertex shader high int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).precision),a.push("webgl vertex shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMin),a.push("webgl vertex shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.HIGH_INT).rangeMax),a.push("webgl vertex shader medium int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).precision),a.push("webgl vertex shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMin),a.push("webgl vertex shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_INT).rangeMax),a.push("webgl vertex shader low int precision:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).precision),a.push("webgl vertex shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMin),a.push("webgl vertex shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.LOW_INT).rangeMax),a.push("webgl fragment shader high int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).precision),a.push("webgl fragment shader high int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMin),a.push("webgl fragment shader high int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT).rangeMax),a.push("webgl fragment shader medium int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).precision),a.push("webgl fragment shader medium int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMin),a.push("webgl fragment shader medium int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT).rangeMax),a.push("webgl fragment shader low int precision:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).precision),a.push("webgl fragment shader low int precision rangeMin:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMin),a.push("webgl fragment shader low int precision rangeMax:"+e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT).rangeMax),a.join("~")):a.join("~")},getAdBlock:function(){var e=document.createElement("div");e.innerHTML=" ",e.className="adsbox";var t=!1;try{document.body.appendChild(e),t=0===document.getElementsByClassName("adsbox")[0].offsetHeight,document.body.removeChild(e)}catch(i){t=!1}return t},getHasLiedLanguages:function(){if("undefined"!=typeof navigator.languages)try{var e=navigator.languages[0].substr(0,2);if(e!==navigator.language.substr(0,2))return!0}catch(t){return!0}return!1},getHasLiedResolution:function(){return screen.width=0?"Windows Phone":t.indexOf("win")>=0?"Windows":t.indexOf("android")>=0?"Android":t.indexOf("linux")>=0?"Linux":t.indexOf("iphone")>=0||t.indexOf("ipad")>=0?"iOS":t.indexOf("mac")>=0?"Mac":"Other";var r;if(r="ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0,r&&"Windows Phone"!==e&&"Android"!==e&&"iOS"!==e&&"Other"!==e)return!0;if("undefined"!=typeof i){if(i=i.toLowerCase(),i.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e)return!0;if(i.indexOf("linux")>=0&&"Linux"!==e&&"Android"!==e)return!0;if(i.indexOf("mac")>=0&&"Mac"!==e&&"iOS"!==e)return!0;if(0===i.indexOf("win")&&0===i.indexOf("linux")&&i.indexOf("mac")>=0&&"other"!==e)return!0}return a.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e?!0:(a.indexOf("linux")>=0||a.indexOf("android")>=0||a.indexOf("pike")>=0)&&"Linux"!==e&&"Android"!==e?!0:(a.indexOf("mac")>=0||a.indexOf("ipad")>=0||a.indexOf("ipod")>=0||a.indexOf("iphone")>=0)&&"Mac"!==e&&"iOS"!==e?!0:0===a.indexOf("win")&&0===a.indexOf("linux")&&a.indexOf("mac")>=0&&"other"!==e?!0:"undefined"==typeof navigator.plugins&&"Windows"!==e&&"Windows Phone"!==e},getHasLiedBrowser:function(){var e,t=navigator.userAgent.toLowerCase(),i=navigator.productSub;if(e=t.indexOf("firefox")>=0?"Firefox":t.indexOf("opera")>=0||t.indexOf("opr")>=0?"Opera":t.indexOf("chrome")>=0?"Chrome":t.indexOf("safari")>=0?"Safari":t.indexOf("trident")>=0?"Internet Explorer":"Other",("Chrome"===e||"Safari"===e||"Opera"===e)&&"20030107"!==i)return!0;var a=eval.toString().length;if(37===a&&"Safari"!==e&&"Firefox"!==e&&"Other"!==e)return!0;if(39===a&&"Internet Explorer"!==e&&"Other"!==e)return!0;if(33===a&&"Chrome"!==e&&"Opera"!==e&&"Other"!==e)return!0;var r;try{throw"a"}catch(n){try{n.toSource(),r=!0}catch(o){r=!1}}return!(!r||"Firefox"===e||"Other"===e)},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isWebGlSupported:function(){if(!this.isCanvasSupported())return!1;var e,t=document.createElement("canvas");try{e=t.getContext&&(t.getContext("webgl")||t.getContext("experimental-webgl"))}catch(i){e=!1}return!!window.WebGLRenderingContext&&!!e},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName?!0:!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},hasSwfObjectLoaded:function(){return"undefined"!=typeof window.swfobject},hasMinFlashInstalled:function(){return swfobject.hasFlashPlayerVersion("9.0.0")},addFlashDivNode:function(){var e=document.createElement("div");e.setAttribute("id",this.options.swfContainerId),document.body.appendChild(e)},loadSwfAndDetectFonts:function(e){var t="___fp_swf_loaded";window[t]=function(t){e(t)};var i=this.options.swfContainerId;this.addFlashDivNode();var a={onReady:t},r={allowScriptAccess:"always",menu:"false"};swfobject.embedSWF(this.options.swfPath,i,"1","1","9.0.0",!1,a,r,{})},getWebglCanvas:function(){var e=document.createElement("canvas"),t=null;try{t=e.getContext("webgl")||e.getContext("experimental-webgl")}catch(i){}return t||(t=null),t},each:function(e,t,i){if(null!==e)if(this.nativeForEach&&e.forEach===this.nativeForEach)e.forEach(t,i);else if(e.length===+e.length){for(var a=0,r=e.length;r>a;a++)if(t.call(i,e[a],a,e)==={})return}else for(var n in e)if(e.hasOwnProperty(n)&&t.call(i,e[n],n,e)==={})return},map:function(e,t,i){var a=[];return null==e?a:this.nativeMap&&e.map===this.nativeMap?e.map(t,i):(this.each(e,function(e,r,n){a[a.length]=t.call(i,e,r,n)}),a)},x64Add:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]+t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]+t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]+t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]+t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Multiply:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]*t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]*t[3],i[1]+=i[2]>>>16,i[2]&=65535,i[2]+=e[3]*t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]*t[3],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[2]*t[2],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[3]*t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Rotl:function(e,t){return t%=64,32===t?[e[1],e[0]]:32>t?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])},x64LeftShift:function(e,t){return t%=64,0===t?e:32>t?[e[0]<>>32-t,e[1]<>>1]),e=this.x64Multiply(e,[4283543511,3981806797]),e=this.x64Xor(e,[0,e[0]>>>1]),e=this.x64Multiply(e,[3301882366,444984403]),e=this.x64Xor(e,[0,e[0]>>>1])},x64hash128:function(e,t){e=e||"",t=t||0;for(var i=e.length%16,a=e.length-i,r=[0,t],n=[0,t],o=[0,0],s=[0,0],l=[2277735313,289559509],h=[1291169091,658871167],u=0;a>u;u+=16)o=[255&e.charCodeAt(u+4)|(255&e.charCodeAt(u+5))<<8|(255&e.charCodeAt(u+6))<<16|(255&e.charCodeAt(u+7))<<24,255&e.charCodeAt(u)|(255&e.charCodeAt(u+1))<<8|(255&e.charCodeAt(u+2))<<16|(255&e.charCodeAt(u+3))<<24],s=[255&e.charCodeAt(u+12)|(255&e.charCodeAt(u+13))<<8|(255&e.charCodeAt(u+14))<<16|(255&e.charCodeAt(u+15))<<24,255&e.charCodeAt(u+8)|(255&e.charCodeAt(u+9))<<8|(255&e.charCodeAt(u+10))<<16|(255&e.charCodeAt(u+11))<<24],o=this.x64Multiply(o,l),o=this.x64Rotl(o,31),o=this.x64Multiply(o,h),r=this.x64Xor(r,o),r=this.x64Rotl(r,27),r=this.x64Add(r,n), +r=this.x64Add(this.x64Multiply(r,[0,5]),[0,1390208809]),s=this.x64Multiply(s,h),s=this.x64Rotl(s,33),s=this.x64Multiply(s,l),n=this.x64Xor(n,s),n=this.x64Rotl(n,31),n=this.x64Add(n,r),n=this.x64Add(this.x64Multiply(n,[0,5]),[0,944331445]);switch(o=[0,0],s=[0,0],i){case 15:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+14)],48));case 14:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+13)],40));case 13:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+12)],32));case 12:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+11)],24));case 11:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+10)],16));case 10:s=this.x64Xor(s,this.x64LeftShift([0,e.charCodeAt(u+9)],8));case 9:s=this.x64Xor(s,[0,e.charCodeAt(u+8)]),s=this.x64Multiply(s,h),s=this.x64Rotl(s,33),s=this.x64Multiply(s,l),n=this.x64Xor(n,s);case 8:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+7)],56));case 7:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+6)],48));case 6:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+5)],40));case 5:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+4)],32));case 4:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+3)],24));case 3:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+2)],16));case 2:o=this.x64Xor(o,this.x64LeftShift([0,e.charCodeAt(u+1)],8));case 1:o=this.x64Xor(o,[0,e.charCodeAt(u)]),o=this.x64Multiply(o,l),o=this.x64Rotl(o,31),o=this.x64Multiply(o,h),r=this.x64Xor(r,o)}return r=this.x64Xor(r,[0,e.length]),n=this.x64Xor(n,[0,e.length]),r=this.x64Add(r,n),n=this.x64Add(n,r),r=this.x64Fmix(r),n=this.x64Fmix(n),r=this.x64Add(r,n),n=this.x64Add(n,r),("00000000"+(r[0]>>>0).toString(16)).slice(-8)+("00000000"+(r[1]>>>0).toString(16)).slice(-8)+("00000000"+(n[0]>>>0).toString(16)).slice(-8)+("00000000"+(n[1]>>>0).toString(16)).slice(-8)}},e.VERSION="1.4.1",e}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/fingerprintjs2/fingerprint2.js b/dashboard-ui/bower_components/fingerprintjs2/fingerprint2.js index 37a73ee7b..95d194bb1 100644 --- a/dashboard-ui/bower_components/fingerprintjs2/fingerprint2.js +++ b/dashboard-ui/bower_components/fingerprintjs2/fingerprint2.js @@ -1,5 +1,5 @@ /* -* Fingerprintjs2 1.4.0 - Modern & flexible browser fingerprint library v2 +* Fingerprintjs2 1.4.1 - Modern & flexible browser fingerprint library v2 * https://github.com/Valve/fingerprintjs2 * Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com) * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. @@ -58,7 +58,8 @@ swfContainerId: "fingerprintjs2", swfPath: "flash/compiled/FontList.swf", detectScreenOrientation: true, - sortPluginsFor: [/palemoon/i] + sortPluginsFor: [/palemoon/i], + userDefinedFonts: [] }; this.options = this.extend(options, defaultOptions); this.nativeForEach = Array.prototype.forEach; @@ -395,6 +396,8 @@ fontList = fontList.concat(extendedFontList); } + fontList = fontList.concat(that.options.userDefinedFonts); + //we use m or w because these two characters take up the maximum width. // And we use a LLi so that the same matching fonts can get separated var testString = "mmmmmmmmmmlli"; @@ -1283,6 +1286,6 @@ return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8); } }; - Fingerprint2.VERSION = "1.4.0"; + Fingerprint2.VERSION = "1.4.1"; return Fingerprint2; }); diff --git a/dashboard-ui/bower_components/fingerprintjs2/package.json b/dashboard-ui/bower_components/fingerprintjs2/package.json index d1acaecab..58c5c583a 100644 --- a/dashboard-ui/bower_components/fingerprintjs2/package.json +++ b/dashboard-ui/bower_components/fingerprintjs2/package.json @@ -1,6 +1,6 @@ { "name": "fingerprintjs2", - "version": "1.4.0", + "version": "1.4.1", "description": "Modern & flexible browser fingerprinting library", "main": "dist/fingerprint2.min.js", "devDependencies": { diff --git a/dashboard-ui/bower_components/polymer/.bower.json b/dashboard-ui/bower_components/polymer/.bower.json index 5320b592c..36ef2ed87 100644 --- a/dashboard-ui/bower_components/polymer/.bower.json +++ b/dashboard-ui/bower_components/polymer/.bower.json @@ -39,6 +39,6 @@ "commit": "8715c83bf04a228de00ec662ed43eb6141e61b91" }, "_source": "git://github.com/Polymer/polymer.git", - "_target": "^1.1.0", + "_target": "^1.0.0", "_originalSource": "Polymer/polymer" } \ No newline at end of file diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 85bea7d71..07d751aaa 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -1604,10 +1604,10 @@ html += ''; if (options.overlayPlayButton && !item.IsPlaceHolder && (item.LocationType != 'Virtual' || !item.MediaType || item.Type == 'Program') && item.Type != 'Person' && item.PlayAccess == 'Full') { - html += '
'; + html += '
'; } if (options.overlayMoreButton) { - html += '
'; + html += '
'; } // cardScalable @@ -1632,7 +1632,7 @@ if (options.cardLayout) { html += '
'; - html += ''; + html += ''; html += "
"; } diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 6f8201ceb..aef248e35 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -246,34 +246,6 @@ }); } - function onListViewPlayButtonClick(e, playButton) { - - var card = e.target; - - if (!card.classList.contains('card') && !card.classList.contains('listItem')) { - card = parentWithAnyClass(card, ['listItem', 'card']); - } - - var id = card.getAttribute('data-itemid'); - var type = card.getAttribute('data-itemtype'); - var isFolder = card.getAttribute('data-isfolder') == 'true'; - var mediaType = card.getAttribute('data-mediatype'); - var resumePosition = parseInt(card.getAttribute('data-positionticks')); - - if (type == 'MusicAlbum' || type == 'MusicArtist' || type == 'MusicGenre' || type == 'Playlist') { - isFolder = true; - } - - if (type == 'Program') { - id = card.getAttribute('data-channelid'); - } - - LibraryBrowser.showPlayMenu(playButton, id, type, isFolder, mediaType, resumePosition); - - e.preventDefault(); - return false; - } - function isClickable(target) { while (target != null) { @@ -291,12 +263,6 @@ function onCardClick(e) { - var playButton = parentWithClass(e.target, 'cardOverlayPlayButton'); - - if (playButton) { - return onListViewPlayButtonClick(e, playButton); - } - var card = parentWithClass(e.target, 'card'); if (card) { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 570b46e65..d30a20ad3 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1820,6 +1820,7 @@ var AppInfo = {}; define("subtitleEditor", [embyWebComponentsBowerPath + "/subtitleeditor/subtitleeditor"], returnFirstDependency); define("mediaInfo", [embyWebComponentsBowerPath + "/mediainfo/mediainfo"], returnFirstDependency); define("itemContextMenu", [embyWebComponentsBowerPath + "/itemcontextmenu"], returnFirstDependency); + define("playMenu", [embyWebComponentsBowerPath + "/playmenu"], returnFirstDependency); define("refreshDialog", [embyWebComponentsBowerPath + "/refreshdialog/refreshdialog"], returnFirstDependency); define("backdrop", [embyWebComponentsBowerPath + "/backdrop/backdrop"], returnFirstDependency); define("fetchHelper", [embyWebComponentsBowerPath + "/fetchhelper"], returnFirstDependency); From 8f05508ce9ea7d01fc37bb603dbc4059fd395669 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:10:31 -0400 Subject: [PATCH 03/10] removed dead code --- dashboard-ui/scripts/librarylist.js | 42 +---------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index aef248e35..8d570e4a4 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -149,7 +149,7 @@ var resumePosition = (item.UserData || {}).PlaybackPositionTicks || 0; - html += ''; + html += ''; buttonCount++; } @@ -181,23 +181,6 @@ return false; } - function onPlayItemButtonClick(e) { - - var target = this; - - var id = target.getAttribute('data-itemid'); - var type = target.getAttribute('data-itemtype'); - var isFolder = target.getAttribute('data-isfolder') == 'true'; - var mediaType = target.getAttribute('data-mediatype'); - var resumePosition = parseInt(target.getAttribute('data-resumeposition')); - - LibraryBrowser.showPlayMenu(this, id, type, isFolder, mediaType, resumePosition); - - e.preventDefault(); - e.stopPropagation(); - return false; - } - function onMoreButtonClick(e) { var card = parentWithClass(this, 'card'); @@ -319,25 +302,6 @@ return false; } - function hasAnyClass(elem, classNames) { - return classNames.filter(function (c) { - return elem.classList.contains(c); - }).length > 0; - } - - function parentWithAnyClass(elem, classNames) { - - while (!elem.classList || !hasAnyClass(elem, classNames)) { - elem = elem.parentNode; - - if (!elem) { - return null; - } - } - - return elem; - } - function parentWithClass(elem, className) { while (!elem.classList || !elem.classList.contains(className)) { @@ -400,10 +364,6 @@ innerElem.innerHTML = getOverlayHtml(item, user, card); - var btnPlayItem = innerElem.querySelector('.btnPlayItem'); - if (btnPlayItem) { - btnPlayItem.addEventListener('click', onPlayItemButtonClick); - } var btnPlayTrailer = innerElem.querySelector('.btnPlayTrailer'); if (btnPlayTrailer) { btnPlayTrailer.addEventListener('click', onTrailerButtonClick); From c46124641a6a9721558b711de5875d2ac9163228 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:11:42 -0400 Subject: [PATCH 04/10] removed dead code --- dashboard-ui/scripts/librarylist.js | 101 ---------------------------- 1 file changed, 101 deletions(-) diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 8d570e4a4..46aa7afe4 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -928,105 +928,4 @@ hideSelections(); }); - function renderUserDataChanges(card, userData) { - - if (userData.Played) { - - var playedIndicator = card.querySelector('.playedIndicator'); - - if (!playedIndicator) { - - playedIndicator = document.createElement('div'); - playedIndicator.classList.add('playedIndicator'); - card.querySelector('.cardContent').appendChild(playedIndicator); - } - playedIndicator.innerHTML = 'check'; - } - else if (userData.UnplayedItemCount) { - - var playedIndicator = card.querySelector('.playedIndicator'); - - if (!playedIndicator) { - - playedIndicator = document.createElement('div'); - playedIndicator.classList.add('playedIndicator'); - card.querySelector('.cardContent').appendChild(playedIndicator); - } - playedIndicator.innerHTML = userData.UnplayedItemCount; - } - - var progressHtml = LibraryBrowser.getItemProgressBarHtml(userData); - var cardProgress; - - if (progressHtml) { - cardProgress = card.querySelector('.cardProgress'); - - if (!cardProgress) { - cardProgress = document.createElement('div'); - cardProgress.classList.add('cardProgress'); - - var cardFooter = card.querySelector('.cardFooter'); - if (cardFooter) { - cardFooter.appendChild(cardProgress); - } - } - - cardProgress.innerHTML = progressHtml; - } - else { - cardProgress = card.querySelector('.cardProgress'); - if (cardProgress) { - cardProgress.parentNode.removeChild(cardProgress); - } - } - } - - function onUserDataChanged(userData) { - - var elems = document.querySelectorAll("*[data-itemid='" + userData.ItemId + "']"); - - for (var i = 0, length = elems.length; i < length; i++) { - - var elem = elems[i]; - var mediaType = elem.getAttribute('data-mediatype'); - - if (mediaType == 'Video') { - elem.setAttribute('data-positionticks', (userData.PlaybackPositionTicks || 0)); - - if (elem.classList.contains('card')) { - renderUserDataChanges(elem, userData); - } - } - } - } - - function onWebSocketMessage(e, data) { - - var msg = data; - - if (msg.MessageType === "UserDataChanged") { - - if (msg.Data.UserId == Dashboard.getCurrentUserId()) { - - for (var i = 0, length = msg.Data.UserDataList.length; i < length; i++) { - onUserDataChanged(msg.Data.UserDataList[i]); - } - } - } - - } - - function initializeApiClient(apiClient) { - Events.off(apiClient, "websocketmessage", onWebSocketMessage); - Events.on(apiClient, "websocketmessage", onWebSocketMessage); - } - - if (window.ApiClient) { - initializeApiClient(window.ApiClient); - } - - Events.on(ConnectionManager, 'apiclientcreated', function (e, apiClient) { - initializeApiClient(apiClient); - }); - }); \ No newline at end of file From c56e87cd6317e0837b2d3ade9700fdc0b5f91e7f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:14:18 -0400 Subject: [PATCH 05/10] removed dead code --- dashboard-ui/scripts/librarylist.js | 75 +---------------------------- 1 file changed, 2 insertions(+), 73 deletions(-) diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 46aa7afe4..d59c51de0 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -78,7 +78,6 @@ var isMiniItem = className.indexOf('mini') != -1; var isSmallItem = isMiniItem || className.indexOf('small') != -1; var isPortrait = className.indexOf('portrait') != -1; - var isSquare = className.indexOf('square') != -1; var parentName = isSmallItem || isMiniItem || isPortrait ? null : item.SeriesName; var name = itemHelper.getDisplayName(item); @@ -154,11 +153,11 @@ } if (item.LocalTrailerCount) { - html += ''; + html += ''; buttonCount++; } - html += ''; + html += ''; buttonCount++; html += '
'; @@ -168,67 +167,6 @@ return html; } - function onTrailerButtonClick(e) { - - var id = this.getAttribute('data-itemid'); - - ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), id).then(function (trailers) { - MediaController.play({ items: trailers }); - }); - - e.preventDefault(); - e.stopPropagation(); - return false; - } - - function onMoreButtonClick(e) { - - var card = parentWithClass(this, 'card'); - - showContextMenu(card, { - shuffle: false, - instantMix: false, - play: false, - playAllFromHere: false, - queue: false, - queueAllFromHere: false - }); - - e.preventDefault(); - e.stopPropagation(); - return false; - } - - function showContextMenu(card, options) { - - var displayContextItem = card; - - card = parentWithClass(card, 'card'); - - if (!card) { - return; - } - - var itemId = card.getAttribute('data-itemid'); - var serverId = ApiClient.serverInfo().Id; - var type = card.getAttribute('data-itemtype'); - - var apiClient = ConnectionManager.getApiClient(serverId); - - var promise = type == 'Timer' ? apiClient.getLiveTvTimer(itemId) : apiClient.getItem(apiClient.getCurrentUserId(), itemId); - - promise.then(function (item) { - - require(['itemContextMenu'], function (itemContextMenu) { - - itemContextMenu.show(Object.assign(options || {}, { - item: item, - positionTo: displayContextItem - })); - }); - }); - } - function isClickable(target) { while (target != null) { @@ -363,15 +301,6 @@ } innerElem.innerHTML = getOverlayHtml(item, user, card); - - var btnPlayTrailer = innerElem.querySelector('.btnPlayTrailer'); - if (btnPlayTrailer) { - btnPlayTrailer.addEventListener('click', onTrailerButtonClick); - } - var btnMoreCommands = innerElem.querySelector('.btnMoreCommands'); - if (btnMoreCommands) { - btnMoreCommands.addEventListener('click', onMoreButtonClick); - } }); slideUpToShow(innerElem); From c925a314cf3f1664433a0590a99a7adcedb42fae Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:30:14 -0400 Subject: [PATCH 06/10] switch to shared play menu --- dashboard-ui/scripts/itemdetailpage.js | 24 +++--- dashboard-ui/scripts/librarybrowser.js | 100 ------------------------- 2 files changed, 14 insertions(+), 110 deletions(-) diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index 4115ff973..41bcae218 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -1984,27 +1984,31 @@ } } + function showPlayMenu(item, target) { + + require(['playMenu'], function (playMenu) { + + playMenu.show({ + + item: item, + positionTo: target + }); + }); + } + function playCurrentItem(button) { if (currentItem.Type == 'Program') { ApiClient.getLiveTvChannel(currentItem.ChannelId, Dashboard.getCurrentUserId()).then(function (channel) { - LibraryBrowser.showPlayMenu(null, channel.Id, channel.Type, false, channel.MediaType, (channel.UserData || {}).PlaybackPositionTicks); + showPlayMenu(channel, button); }); return; } - var userdata = currentItem.UserData || {}; - - var mediaType = currentItem.MediaType; - - if (currentItem.Type == "MusicArtist" || currentItem.Type == "MusicAlbum") { - mediaType = "Audio"; - } - - LibraryBrowser.showPlayMenu(button, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks); + showPlayMenu(currentItem, button); } function deleteTimer(page, params, id) { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 07d751aaa..0feed45c0 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -577,106 +577,6 @@ }); }, - showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks) { - - var externalPlayers = AppInfo.supportsExternalPlayers && appSettings.enableExternalPlayers(); - - if (!resumePositionTicks && mediaType != "Audio" && !isFolder) { - - if (!externalPlayers || mediaType != "Video") { - - MediaController.play(itemId); - return; - } - } - - var menuItems = []; - - if (resumePositionTicks) { - menuItems.push({ - name: Globalize.translate('ButtonResume'), - id: 'resume', - ironIcon: 'play-arrow' - }); - } - - menuItems.push({ - name: Globalize.translate('ButtonPlay'), - id: 'play', - ironIcon: 'play-arrow' - }); - - if (!isFolder && externalPlayers && mediaType != "Audio") { - menuItems.push({ - name: Globalize.translate('ButtonPlayExternalPlayer'), - id: 'externalplayer', - ironIcon: 'airplay' - }); - } - - if (MediaController.canQueueMediaType(mediaType, itemType)) { - menuItems.push({ - name: Globalize.translate('ButtonQueue'), - id: 'queue', - ironIcon: 'playlist-add' - }); - } - - if (itemType == "Audio" || itemType == "MusicAlbum" || itemType == "MusicArtist" || itemType == "MusicGenre") { - menuItems.push({ - name: Globalize.translate('ButtonInstantMix'), - id: 'instantmix', - ironIcon: 'shuffle' - }); - } - - if (isFolder || itemType == "MusicArtist" || itemType == "MusicGenre") { - menuItems.push({ - name: Globalize.translate('ButtonShuffle'), - id: 'shuffle', - ironIcon: 'shuffle' - }); - } - - require(['actionsheet'], function (actionsheet) { - - actionsheet.show({ - items: menuItems, - positionTo: positionTo, - callback: function (id) { - - switch (id) { - - case 'play': - MediaController.play(itemId); - break; - case 'externalplayer': - LibraryBrowser.playInExternalPlayer(itemId); - break; - case 'resume': - MediaController.play({ - ids: [itemId], - startPositionTicks: resumePositionTicks - }); - break; - case 'queue': - MediaController.queue(itemId); - break; - case 'instantmix': - MediaController.instantMix(itemId); - break; - case 'shuffle': - MediaController.shuffle(itemId); - break; - default: - break; - } - } - }); - - }); - }, - deleteItems: function (itemIds) { return new Promise(function (resolve, reject) { From 7323e865f260f9795935ae4e93d2e49b06d6f658 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 16:38:05 -0400 Subject: [PATCH 07/10] fix shuffle/instant mix --- dashboard-ui/scripts/mediacontroller.js | 11 +++++++++++ dashboard-ui/scripts/site.js | 3 +++ 2 files changed, 14 insertions(+) diff --git a/dashboard-ui/scripts/mediacontroller.js b/dashboard-ui/scripts/mediacontroller.js index 547cdc777..a02cbc491 100644 --- a/dashboard-ui/scripts/mediacontroller.js +++ b/dashboard-ui/scripts/mediacontroller.js @@ -585,12 +585,23 @@ self.shuffle = function (id) { + // accept both id and item being passed in + if (id.Id) { + id = id.Id; + } + doWithPlaybackValidation(currentPlayer, function () { currentPlayer.shuffle(id); }); }; self.instantMix = function (id) { + + // accept both id and item being passed in + if (id.Id) { + id = id.Id; + } + doWithPlaybackValidation(currentPlayer, function () { currentPlayer.instantMix(id); }); diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index d30a20ad3..62ef9b284 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -2039,6 +2039,9 @@ var AppInfo = {}; }, instantMix: function (item) { return MediaController.instantMix(item); + }, + shuffle: function (item) { + return MediaController.shuffle(item); } }; }); From 63efbfc83844bde9f06f80ef849385e765dc5c97 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 22:55:07 -0400 Subject: [PATCH 08/10] rework slideup menus to use shared components --- .../emby-webcomponents/.bower.json | 8 +- .../emby-itemscontainer.js | 26 +- .../emby-webcomponents/itemcontextmenu.js | 15 +- .../emby-webcomponents/itemhelper.js | 27 +- .../itemhovermenu/itemhovermenu.css | 51 ++++ .../itemhovermenu/itemhovermenu.js | 280 ++++++++++++++++++ .../emby-webcomponents/listview/listview.js | 5 +- .../emby-webcomponents/shortcuts.js | 33 ++- .../emby-webcomponents/strings/da.json | 2 + .../emby-webcomponents/strings/de.json | 2 + .../emby-webcomponents/strings/en-US.json | 5 +- .../emby-webcomponents/strings/es-MX.json | 2 + .../emby-webcomponents/strings/fr.json | 2 + .../emby-webcomponents/strings/kk.json | 2 + .../emby-webcomponents/strings/nb.json | 2 + .../emby-webcomponents/strings/nl.json | 40 +-- .../emby-webcomponents/strings/pt-BR.json | 54 ++-- .../emby-webcomponents/strings/pt-PT.json | 2 + .../emby-webcomponents/strings/ru.json | 2 + .../emby-webcomponents/strings/sv.json | 2 + .../emby-webcomponents/strings/zh-TW.json | 2 + .../userdatabuttons/userdatabuttons.js | 22 +- .../bower_components/polymer/.bower.json | 2 +- dashboard-ui/css/card.css | 37 --- dashboard-ui/scripts/librarybrowser.js | 19 +- dashboard-ui/scripts/librarylist.js | 266 +---------------- dashboard-ui/scripts/sections.js | 2 +- dashboard-ui/scripts/site.js | 1 + 28 files changed, 521 insertions(+), 392 deletions(-) create mode 100644 dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css create mode 100644 dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index f08a23588..3f1d60e7f 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -15,12 +15,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.94", - "_release": "1.4.94", + "version": "1.4.96", + "_release": "1.4.96", "_resolution": { "type": "version", - "tag": "1.4.94", - "commit": "1914cf851948d6f4f5e730c5e831e5e604fe3c9e" + "tag": "1.4.96", + "commit": "4c9f9b8c4937da15ac8c81d554e768f0ef6e944e" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.0", diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js index 7b6285f8a..08e539395 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js @@ -7,7 +7,7 @@ while (!elem.getAttribute(name)) { elem = elem.parentNode; - if (!elem) { + if (!elem || !elem.getAttribute) { return null; } } @@ -62,6 +62,26 @@ }; } + ItemsContainerProtoType.enableHoverMenu = function (enabled) { + + var current = this.hoverMenu; + + if (!enabled && current) { + current.destroy(); + this.hoverMenu = null; + return; + } + + if (current) { + return; + } + + var self = this; + require(['itemHoverMenu'], function (ItemHoverMenu) { + self.hoverMenu = new ItemHoverMenu(self); + }); + }; + ItemsContainerProtoType.attachedCallback = function () { this.addEventListener('click', onClick); @@ -73,6 +93,10 @@ this.addEventListener('contextmenu', onContextMenu); } + if (layoutManager.desktop) { + this.enableHoverMenu(true); + } + itemShortcuts.on(this, getShortcutOptions()); }; diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js index a3e00bab2..0346d41bc 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js +++ b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js @@ -43,11 +43,20 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter', if (!isTheater) { if (options.edit !== false) { + + var text = item.Type == 'Timer' ? globalize.translate('sharedcomponents#Edit') : globalize.translate('sharedcomponents#EditInfo'); + commands.push({ - name: globalize.translate('sharedcomponents#EditInfo'), + name: text, id: 'edit' }); } + } + } + + if (itemHelper.canEditImages(user, item.Type)) { + + if (!isTheater) { if (options.editImages !== false) { commands.push({ name: globalize.translate('sharedcomponents#EditImages'), @@ -55,6 +64,10 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter', }); } } + } + + if (itemHelper.canEdit(user, item.Type)) { + if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual') { if (options.editSubtitles !== false) { commands.push({ diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemhelper.js b/dashboard-ui/bower_components/emby-webcomponents/itemhelper.js index 65bb91355..2ee4afcd1 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/itemhelper.js +++ b/dashboard-ui/bower_components/emby-webcomponents/itemhelper.js @@ -69,6 +69,20 @@ define(['apphost'], function (appHost) { return item.RunTimeTicks || item.IsFolder || item.Type == "Genre" || item.Type == "MusicGenre" || item.Type == "MusicArtist"; } + function canEdit(user, itemType) { + + if (itemType == "UserRootFolder" || /*itemType == "CollectionFolder" ||*/ itemType == "UserView") { + return false; + } + + if (user.Policy.IsAdministrator) { + + return true; + } + + return false; + } + return { getDisplayName: getDisplayName, supportsAddingToCollection: supportsAddingToCollection, @@ -95,18 +109,11 @@ define(['apphost'], function (appHost) { return false; }, - canEdit: function (user, itemType) { + canEdit: canEdit, - if (itemType == "UserRootFolder" || /*itemType == "CollectionFolder" ||*/ itemType == "UserView") { - return false; - } + canEditImages: function (user, itemType) { - if (user.Policy.IsAdministrator) { - - return true; - } - - return false; + return itemType != 'Timer' && canEdit(user, itemType); }, canSync: function (user, item) { diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css new file mode 100644 index 000000000..965a38acc --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css @@ -0,0 +1,51 @@ +.cardOverlayTarget { + position: absolute; + right: 0; + left: 0; + bottom: 0; + top: 0; + background-color: rgba(0, 0, 0, .85); + z-index: 998; + line-height: initial; +} + +.cardOverlayInner { + padding: 11px 12px 10px; + color: #fff; +} + + .cardOverlayInner button:last-child { + margin-right: 0 !important; + } + + .cardOverlayInner p { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + +.cardOverlayMediaInfo { + display: flex; + align-items: center; + flex-wrap: wrap; + margin: 1em 0; + color: #ddd; +} + +.cardOverlayButtons { + display: flex; + align-items: center; + flex-wrap: wrap; +} + + .cardOverlayButtons .fab { + background-color: #333; + } + +@media all and (max-width: 1200px) { + + .cardOverlayInner { + padding-left: 7px; + padding-right: 7px; + } +} diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js new file mode 100644 index 000000000..4b0ffa31f --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js @@ -0,0 +1,280 @@ +define(['connectionManager', 'itemHelper', 'mediaInfo', 'userdataButtons', 'playbackManager', 'globalize', 'css!./itemhovermenu', 'emby-button'], function (connectionManager, itemHelper, mediaInfo, userdataButtons, playbackManager, globalize) { + + var preventHover = false; + var showOverlayTimeout; + var hoveringElement; + + function parentWithAttribute(elem, name) { + + while (!elem.getAttribute(name)) { + elem = elem.parentNode; + + if (!elem || !elem.getAttribute) { + return null; + } + } + + return elem; + } + + function onHoverOut(e) { + + var elem = e.target; + + if (elem != hoveringElement) { + return; + } + + if (showOverlayTimeout) { + clearTimeout(showOverlayTimeout); + showOverlayTimeout = null; + } + + elem = elem.querySelector('.cardOverlayTarget'); + + if (elem) { + slideDownToHide(elem); + } + } + + function slideDownToHide(elem) { + + if (elem.classList.contains('hide')) { + return; + } + + if (!elem.animate) { + elem.classList.add('hide'); + return; + } + + requestAnimationFrame(function () { + var keyframes = [ + { transform: 'translateY(0)', offset: 0 }, + { transform: 'translateY(100%)', offset: 1 }]; + var timing = { duration: 300, iterations: 1, fill: 'forwards', easing: 'ease-out' }; + + elem.animate(keyframes, timing).onfinish = function () { + elem.classList.add('hide'); + }; + }); + } + + function slideUpToShow(elem) { + + if (!elem.classList.contains('hide')) { + return; + } + + elem.classList.remove('hide'); + + if (!elem.animate) { + return; + } + + requestAnimationFrame(function () { + + var keyframes = [ + { transform: 'translateY(100%)', offset: 0 }, + { transform: 'translateY(0)', offset: 1 }]; + var timing = { duration: 300, iterations: 1, fill: 'forwards', easing: 'ease-out' }; + elem.animate(keyframes, timing); + }); + } + + function getOverlayHtml(item, currentUser, card) { + + var html = ''; + + html += '
'; + + var className = card.className.toLowerCase(); + + var isMiniItem = className.indexOf('mini') != -1; + var isSmallItem = isMiniItem || className.indexOf('small') != -1; + var isPortrait = className.indexOf('portrait') != -1; + + var parentName = isSmallItem || isMiniItem || isPortrait ? null : item.SeriesName; + var name = itemHelper.getDisplayName(item); + + html += '
'; + var logoHeight = isSmallItem || isMiniItem ? 20 : 26; + var imgUrl; + + if (parentName && item.ParentLogoItemId) { + + imgUrl = ApiClient.getScaledImageUrl(item.ParentLogoItemId, { + maxHeight: logoHeight, + type: 'logo', + tag: item.ParentLogoImageTag + }); + + html += ''; + + } + else if (item.ImageTags.Logo) { + + imgUrl = ApiClient.getScaledImageUrl(item.Id, { + maxHeight: logoHeight, + type: 'logo', + tag: item.ImageTags.Logo + }); + + html += ''; + } + else { + html += parentName || name; + } + html += '
'; + + if (parentName) { + html += '

'; + html += name; + html += '

'; + } else if (!isSmallItem && !isMiniItem) { + html += '
'; + html += mediaInfo.getPrimaryMediaInfoHtml(item, { + endsAt: false + }); + html += '
'; + } + + html += '
'; + + var buttonCount = 0; + + if (playbackManager.canPlay(item)) { + + html += ''; + buttonCount++; + } + + if (item.LocalTrailerCount) { + html += ''; + buttonCount++; + } + + html += ''; + buttonCount++; + + html += userdataButtons.getIconsHtml({ + item: item, + style: 'fab-mini' + }); + + html += '
'; + + html += '
'; + + return html; + } + + function parentWithClass(elem, className) { + + while (!elem.classList || !elem.classList.contains(className)) { + elem = elem.parentNode; + + if (!elem) { + return null; + } + } + + return elem; + } + + function onShowTimerExpired(elem) { + + elem = elem.querySelector('a'); + + var innerElem = elem.querySelector('.cardOverlayTarget'); + + if (!innerElem) { + innerElem = document.createElement('div'); + innerElem.classList.add('hide'); + innerElem.classList.add('cardOverlayTarget'); + parentWithClass(elem, 'cardContent').appendChild(innerElem); + } + + var dataElement = parentWithAttribute(elem, 'data-id'); + + var id = dataElement.getAttribute('data-id'); + var type = dataElement.getAttribute('data-type'); + + if (type == 'Timer') { + return; + } + + var serverId = dataElement.getAttribute('data-serverid'); + + var apiClient = connectionManager.getApiClient(serverId); + var promise1 = apiClient.getItem(apiClient.getCurrentUserId(), id); + var promise2 = apiClient.getCurrentUser(); + + Promise.all([promise1, promise2]).then(function (responses) { + + var item = responses[0]; + var user = responses[1]; + + var card = elem; + + elem = parentWithAttribute(elem, 'data-id'); + + innerElem.innerHTML = getOverlayHtml(item, user, card); + }); + + slideUpToShow(innerElem); + } + + function onHoverIn(e) { + + var elem = e.target; + + if (!elem.classList.contains('cardImage')) { + return; + } + + if (preventHover === true) { + preventHover = false; + return; + } + + if (showOverlayTimeout) { + clearTimeout(showOverlayTimeout); + showOverlayTimeout = null; + } + + elem = parentWithAttribute(elem, 'data-id'); + hoveringElement = elem; + + showOverlayTimeout = setTimeout(function () { + onShowTimerExpired(elem); + + }, 1200); + } + + function preventTouchHover() { + preventHover = true; + } + + function ItemHoverMenu(parentElement) { + + this.parent = parentElement; + + this.parent.addEventListener('mouseenter', onHoverIn, true); + this.parent.addEventListener('mouseleave', onHoverOut, true); + this.parent.addEventListener("touchstart", preventTouchHover); + } + + ItemHoverMenu.prototype = { + + constructor: ItemHoverMenu, + + destroy: function () { + this.parent.removeEventListener('mouseenter', onHoverIn, true); + this.parent.removeEventListener('mouseleave', onHoverOut, true); + this.parent.removeEventListener("touchstart", preventTouchHover); + } + } + + return ItemHoverMenu; +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js index baf251fd9..cff8bb115 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js @@ -293,7 +293,10 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (!clickEntireItem) { html += ''; html += ''; - html += userdataButtons.getIconsHtml(item, false); + html += userdataButtons.getIconsHtml({ + item: item, + includePlayed: false + }); html += ''; } diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js index 9edfdeca6..a6a15f0da 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js +++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js @@ -99,6 +99,9 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g var apiClient = connectionManager.getApiClient(serverId); + if (type == 'Timer') { + return apiClient.getLiveTvTimer(id); + } return apiClient.getItem(apiClient.getCurrentUserId(), id); } @@ -165,6 +168,8 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g function executeAction(card, target, action) { + target = target || card; + var id = card.getAttribute('data-id'); if (!id) { @@ -217,14 +222,26 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } else if (action == 'menu') { - showContextMenu(card, { - identify: false, - positionTo: target || card - }); + + var options = target.getAttribute('data-playoptions') == 'false' ? + { + shuffle: false, + instantMix: false, + play: false, + playAllFromHere: false, + queue: false, + queueAllFromHere: false + } : + {}; + + options.identify = false; + options.positionTo = target; + + showContextMenu(card, options); } else if (action == 'playmenu') { - showPlayMenu(card, target || card); + showPlayMenu(card, target); } } @@ -318,7 +335,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } if (action) { - executeAction(card, e.target, action); + executeAction(card, actionElement, action); e.preventDefault(); e.stopPropagation(); @@ -332,7 +349,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g while ((value ? elem.getAttribute(name) != value : !elem.getAttribute(name))) { elem = elem.parentNode; - if (!elem) { + if (!elem || !elem.getAttribute) { return null; } } @@ -356,7 +373,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g function onCommand(e) { var cmd = e.detail.command; - if (cmd == 'play' || cmd == 'record') { + if (cmd == 'play' || cmd == 'record' || cmd == 'menu' || cmd == 'info') { var card = parentWithClass(e.target, 'itemAction'); if (card) { diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/da.json b/dashboard-ui/bower_components/emby-webcomponents/strings/da.json index 651c8b85f..95e8f67e5 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/da.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/da.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Special - {0}", "Share": "Del", "ServerUpdateNeeded": "Denne Emby server b\u00f8r opdateres. For at downloade den nyeste version bes\u00f8g venligst {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/de.json b/dashboard-ui/bower_components/emby-webcomponents/strings/de.json index 3ca2976be..a80c1856d 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/de.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/de.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Special - {0}", "Share": "Teilen", "ServerUpdateNeeded": "Dieser Emby Server sollte aktualisiert werden. Um die neueste Version zu laden, besuche bitte {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json index 301adb112..188d69b6e 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json @@ -113,6 +113,7 @@ "QueueAllFromHere": "Queue All from Here", "PlayAllFromHere": "Play All from Here", "PlayFromBeginning": "Play from beginning", - "ResumeAt": "Resume at {0}", - "RemoveFromPlaylist": "Remove from Playlist" + "ResumeAt": "Resume from {0}", + "RemoveFromPlaylist": "Remove from Playlist", + "Trailer": "Trailer" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json b/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json index e694d49f1..0ee9d004a 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/es-MX.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Compartir", "ServerUpdateNeeded": "Este Servidor Emby necesita ser actualizado. Para descargar la ultima versi\u00f3n, por favor visite {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json b/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json index 9bb888d92..6c1a881fb 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/fr.json @@ -1,6 +1,8 @@ { "EditInfo": "Modifier les informations", "RemoveFromPlaylist": "Supprimer de la liste de lecture", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Sp\u00e9cial - {0}", "Share": "Partager", "ServerUpdateNeeded": "Le serveur Emby doit \u00eatre mis \u00e0 jour. Pour t\u00e9l\u00e9charger la derni\u00e8re version, veuillez visiter {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json b/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json index 0c31cf557..ce865a8b6 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/kk.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "\u0410\u0440\u043d\u0430\u0439\u044b - {0}", "Share": "\u041e\u0440\u0442\u0430\u049b\u0442\u0430\u0441\u0443", "ServerUpdateNeeded": "\u041e\u0441\u044b Emby Server \u0436\u0430\u04a3\u0430\u0440\u0442\u044b\u043b\u0443\u044b \u049b\u0430\u0436\u0435\u0442. \u0421\u043e\u04a3\u0493\u044b \u043d\u04b1\u0441\u049b\u0430\u0441\u044b\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443 \u04af\u0448\u0456\u043d, {0} \u043a\u0456\u0440\u0456\u04a3\u0456\u0437", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json b/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json index 72f9bc396..ab43e5b39 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/nb.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Spesial - {0}", "Share": "Del", "ServerUpdateNeeded": "Denne Emby serveren trenger en oppdatering. For \u00e5 laste ned nyeste versjon, vennligst bes\u00f8k: {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json b/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json index 4a47303eb..9a34b2c12 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/nl.json @@ -1,6 +1,8 @@ { - "EditInfo": "Edit Info", - "RemoveFromPlaylist": "Remove from Playlist", + "EditInfo": "Info Bewerken", + "RemoveFromPlaylist": "Verwijderen uit afspeellijst", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Speciaal - {0}", "Share": "Delen", "ServerUpdateNeeded": "Deze Emby Server moet worden bijgewerkt. Om de laatste versie te downloaden, gaat u naar {0}", @@ -94,23 +96,23 @@ "HeaderYouSaid": "U zei...", "MessageWeDidntRecognizeCommand": "Sorry, dat commando herkennen we niet.", "MessageIfYouBlockedVoice": "Als u spraak toegang uitgeschakeld heeft moet u dit opnieuw configureren voordat u verder gaat.", - "ValueDiscNumber": "Disc {0}", - "Unrated": "Unrated", - "Favorite": "Favorite", - "Like": "Like", - "Dislike": "Dislike", - "Played": "Played", + "ValueDiscNumber": "Schijf {0}", + "Unrated": "Geen rating", + "Favorite": "Favoriet", + "Like": "Leuk", + "Dislike": "Niet leuk", + "Played": "Afgespeeld", "RefreshDialogHelp": "Metadata wordt vernieuwd op basis van de instellingen en internet diensten die zijn ingeschakeld in het dashboard van de Emby Server.", - "Open": "Open", - "Play": "Play", - "Queue": "Queue", - "Shuffle": "Shuffle", - "Identify": "Identify", - "EditImages": "Edit Images", - "Sync": "Sync", + "Open": "Openen", + "Play": "Afspelen", + "Queue": "Wachtrij", + "Shuffle": "Willekeurig", + "Identify": "Identificeer", + "EditImages": "Bewerk afbeeldingen", + "Sync": "Synchronisatie", "InstantMix": "Instant Mix", - "ViewAlbum": "View Album", - "ViewArtist": "View Artist", - "QueueAllFromHere": "Queue All from Here", - "PlayAllFromHere": "Play All from Here" + "ViewAlbum": "Bekijk album", + "ViewArtist": "Bekijk artiest", + "QueueAllFromHere": "Plaats alles in de wachtrij vanaf hier", + "PlayAllFromHere": "Speel alles vanaf hier" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json index ba4c52271..1724fccd3 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json @@ -1,6 +1,8 @@ { - "EditInfo": "Edit Info", - "RemoveFromPlaylist": "Remove from Playlist", + "EditInfo": "Editar Informa\u00e7\u00f5es", + "RemoveFromPlaylist": "Remover da Lista de Reprodu\u00e7\u00e3o", + "PlayFromBeginning": "Reproduzir do in\u00edcio", + "ResumeAt": "Retomar de {0}", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Compartilhar", "ServerUpdateNeeded": "Este servidor Emby precisa ser atualizado. Para baixar a \u00faltima vers\u00e3o, por favor visite {0}", @@ -88,29 +90,29 @@ "ReplaceAllMetadata": "Substituir todos os metadados", "SearchForMissingMetadata": "Buscar por metadados que faltam", "LabelRefreshMode": "Mode de atualiza\u00e7\u00e3o:", - "NoItemsFound": "No items found.", - "HeaderSaySomethingLike": "Say Something Like...", - "ButtonTryAgain": "Try Again", - "HeaderYouSaid": "You Said...", - "MessageWeDidntRecognizeCommand": "We're sorry, we didn't recognize that command.", - "MessageIfYouBlockedVoice": "If you denied voice access to the app you'll need to reconfigure before trying again.", - "ValueDiscNumber": "Disc {0}", - "Unrated": "Unrated", - "Favorite": "Favorite", - "Like": "Like", - "Dislike": "Dislike", - "Played": "Played", + "NoItemsFound": "Nenhum item encontrado.", + "HeaderSaySomethingLike": "Diga algo como...", + "ButtonTryAgain": "Tente Novamente", + "HeaderYouSaid": "Voc\u00ea disse...", + "MessageWeDidntRecognizeCommand": "Desculpe-nos, n\u00e3o foi poss\u00edvel reconhecer este comando.", + "MessageIfYouBlockedVoice": "Se voc\u00ea negou acessos de voz ao app voc\u00ea precisar\u00e1 reconfigurar antes de tentar novamente.", + "ValueDiscNumber": "Disco {0}", + "Unrated": "Sem classifica\u00e7\u00e3o", + "Favorite": "Favorito", + "Like": "Gostei", + "Dislike": "N\u00e3o Gostei", + "Played": "Reproduzido", "RefreshDialogHelp": "Os metadados s\u00e3o atualizados com bases nas defini\u00e7\u00f5es e nos servi\u00e7os de internet que est\u00e3o ativos no painel do Servidor Emby.", - "Open": "Open", - "Play": "Play", - "Queue": "Queue", - "Shuffle": "Shuffle", - "Identify": "Identify", - "EditImages": "Edit Images", - "Sync": "Sync", - "InstantMix": "Instant Mix", - "ViewAlbum": "View Album", - "ViewArtist": "View Artist", - "QueueAllFromHere": "Queue All from Here", - "PlayAllFromHere": "Play All from Here" + "Open": "Abrir", + "Play": "Reproduzir", + "Queue": "Enfileirar", + "Shuffle": "Embaralhar", + "Identify": "Identificar", + "EditImages": "Editar Imagens", + "Sync": "Sincronizar", + "InstantMix": "Mix Instant\u00e2neo", + "ViewAlbum": "Visualizar \u00c1lbum", + "ViewArtist": "Visualizar Artista", + "QueueAllFromHere": "Enfileirar todos daqui", + "PlayAllFromHere": "Reproduzir todos daqui" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json index 1d2dbd582..da2502987 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Especial - {0}", "Share": "Partilhar", "ServerUpdateNeeded": "Este Servidor Emby precisa ser atualizado. Para fazer download da vers\u00e3o mais recente, por favor visite {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json b/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json index 7996aa017..6028c6d6c 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/ru.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "\u0421\u043f\u0435\u0446\u044d\u043f\u0438\u0437\u043e\u0434 - {0}", "Share": "\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f", "ServerUpdateNeeded": "\u0414\u0430\u043d\u043d\u044b\u0439 Emby Server \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json b/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json index be0c522e8..aaa8b7ac2 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/sv.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Specialavsnitt - {0}", "Share": "Dela", "ServerUpdateNeeded": "Den h\u00e4r Emby servern beh\u00f6ver uppdateras. F\u00f6r att ladda ner senaste versionen, g\u00e5 till {0}", diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json b/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json index 6db832b5a..66c479212 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/zh-TW.json @@ -1,6 +1,8 @@ { "EditInfo": "Edit Info", "RemoveFromPlaylist": "Remove from Playlist", + "PlayFromBeginning": "Play from beginning", + "ResumeAt": "Resume from {0}", "ValueSpecialEpisodeName": "Special - {0}", "Share": "\u5206\u4eab", "ServerUpdateNeeded": "\u6b64Emby\u4f3a\u670d\u5668\u9700\u8981\u66f4\u65b0\uff0c\u8acb\u81f3{0}\u53d6\u5f97\u6700\u65b0\u7248\u672c", diff --git a/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js b/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js index f44875f51..66bc6a2de 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js +++ b/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js @@ -2,10 +2,17 @@ define(['connectionManager', 'globalize', 'paper-icon-button-light', 'material-i function getUserDataButtonHtml(method, itemId, iconCssClass, icon, tooltip, style) { + if (style == 'fab-mini') { + style = 'fab'; + iconCssClass = iconCssClass ? (iconCssClass + ' mini') : 'mini'; + } + var is = style == 'fab' ? 'emby-button' : 'paper-icon-button-light'; var className = style == 'fab' ? 'autoSize fab' : 'autoSize'; - className += ' ' + iconCssClass; + if (iconCssClass) { + className += ' ' + iconCssClass; + } return ''; + return ''; }, getUserDataIconsHtml: function (item, includePlayed, style) { @@ -2316,7 +2311,7 @@ markPlayed: function (link) { - var id = link.getAttribute('data-itemid'); + var id = link.getAttribute('data-id'); var markAsPlayed = !link.classList.contains('btnUserItemRatingOn'); @@ -2331,7 +2326,7 @@ markFavorite: function (link) { - var id = link.getAttribute('data-itemid'); + var id = link.getAttribute('data-id'); var markAsFavorite = !link.classList.contains('btnUserItemRatingOn'); diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index d59c51de0..3236b26da 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -1,172 +1,5 @@ define(['appSettings', 'appStorage', 'libraryBrowser', 'apphost', 'itemHelper', 'mediaInfo'], function (appSettings, appStorage, LibraryBrowser, appHost, itemHelper, mediaInfo) { - var showOverlayTimeout; - - function onHoverOut(e) { - - var elem = e.target; - - if (!elem.classList.contains('card')) { - return; - } - - if (showOverlayTimeout) { - clearTimeout(showOverlayTimeout); - showOverlayTimeout = null; - } - - elem = elem.querySelector('.cardOverlayTarget'); - - if (elem) { - slideDownToHide(elem); - } - } - - function slideDownToHide(elem) { - - if (elem.classList.contains('hide')) { - return; - } - - if (!elem.animate) { - elem.classList.add('hide'); - return; - } - - requestAnimationFrame(function () { - var keyframes = [ - { transform: 'translateY(0)', offset: 0 }, - { transform: 'translateY(100%)', offset: 1 }]; - var timing = { duration: 300, iterations: 1, fill: 'forwards', easing: 'ease-out' }; - - elem.animate(keyframes, timing).onfinish = function () { - elem.classList.add('hide'); - }; - }); - } - - function slideUpToShow(elem) { - - if (!elem.classList.contains('hide')) { - return; - } - - elem.classList.remove('hide'); - - if (!elem.animate) { - return; - } - - requestAnimationFrame(function () { - - var keyframes = [ - { transform: 'translateY(100%)', offset: 0 }, - { transform: 'translateY(0)', offset: 1 }]; - var timing = { duration: 300, iterations: 1, fill: 'forwards', easing: 'ease-out' }; - elem.animate(keyframes, timing); - }); - } - - function getOverlayHtml(item, currentUser, card) { - - var html = ''; - - html += '
'; - - var className = card.className.toLowerCase(); - - var isMiniItem = className.indexOf('mini') != -1; - var isSmallItem = isMiniItem || className.indexOf('small') != -1; - var isPortrait = className.indexOf('portrait') != -1; - - var parentName = isSmallItem || isMiniItem || isPortrait ? null : item.SeriesName; - var name = itemHelper.getDisplayName(item); - - html += '
'; - var logoHeight = isSmallItem || isMiniItem ? 20 : 26; - var imgUrl; - - if (parentName && item.ParentLogoItemId) { - - imgUrl = ApiClient.getScaledImageUrl(item.ParentLogoItemId, { - maxHeight: logoHeight, - type: 'logo', - tag: item.ParentLogoImageTag - }); - - html += ''; - - } - else if (item.ImageTags.Logo) { - - imgUrl = ApiClient.getScaledImageUrl(item.Id, { - maxHeight: logoHeight, - type: 'logo', - tag: item.ImageTags.Logo - }); - - html += ''; - } - else { - html += parentName || name; - } - html += '
'; - - if (parentName) { - html += '

'; - html += name; - html += '

'; - } else if (!isSmallItem && !isMiniItem) { - html += '
'; - html += mediaInfo.getPrimaryMediaInfoHtml(item, { - endsAt: false - }); - html += '
'; - } - - if (!isMiniItem) { - html += '
'; - - if (isPortrait) { - html += '
'; - html += LibraryBrowser.getUserDataIconsHtml(item); - html += '
'; - } else { - - html += ''; - html += LibraryBrowser.getUserDataIconsHtml(item); - html += ''; - } - html += '
'; - } - - html += '
'; - - var buttonCount = 0; - - if (MediaController.canPlay(item)) { - - var resumePosition = (item.UserData || {}).PlaybackPositionTicks || 0; - - html += ''; - buttonCount++; - } - - if (item.LocalTrailerCount) { - html += ''; - buttonCount++; - } - - html += ''; - buttonCount++; - - html += '
'; - - html += '
'; - - return html; - } - function isClickable(target) { while (target != null) { @@ -200,7 +33,7 @@ function onGroupedCardClick(e, card) { - var itemId = card.getAttribute('data-itemid'); + var itemId = card.getAttribute('data-id'); var context = card.getAttribute('data-context'); var userId = Dashboard.getCurrentUserId(); @@ -255,104 +88,9 @@ LibraryBrowser.createCardMenus = function (curr, options) { - var preventHover = false; - - function onShowTimerExpired(elem) { - - elem = elem.querySelector('a'); - - if (elem.querySelector('.itemSelectionPanel')) { - return; - } - - var innerElem = elem.querySelector('.cardOverlayTarget'); - - if (!innerElem) { - innerElem = document.createElement('div'); - innerElem.classList.add('hide'); - innerElem.classList.add('cardOverlayTarget'); - parentWithClass(elem, 'cardContent').appendChild(innerElem); - } - - var dataElement = elem; - while (dataElement && !dataElement.getAttribute('data-itemid')) { - dataElement = dataElement.parentNode; - } - - var id = dataElement.getAttribute('data-itemid'); - var type = dataElement.getAttribute('data-itemtype'); - - if (type == 'Timer') { - return; - } - - var promise1 = ApiClient.getItem(Dashboard.getCurrentUserId(), id); - var promise2 = Dashboard.getCurrentUser(); - - Promise.all([promise1, promise2]).then(function (responses) { - - var item = responses[0]; - var user = responses[1]; - - var card = elem; - - while (!card.classList.contains('card')) { - card = card.parentNode; - } - - innerElem.innerHTML = getOverlayHtml(item, user, card); - }); - - slideUpToShow(innerElem); - } - - function onHoverIn(e) { - - var elem = e.target; - - if (!elem.classList.contains('cardImage')) { - return; - } - - if (preventHover === true) { - preventHover = false; - return; - } - - if (showOverlayTimeout) { - clearTimeout(showOverlayTimeout); - showOverlayTimeout = null; - } - - while (!elem.classList.contains('card')) { - elem = elem.parentNode; - } - - showOverlayTimeout = setTimeout(function () { - onShowTimerExpired(elem); - - }, 1200); - } - - function preventTouchHover() { - preventHover = true; - } - curr.removeEventListener('click', onCardClick); curr.addEventListener('click', onCardClick); - if (!AppInfo.isTouchPreferred) { - - curr.removeEventListener('mouseenter', onHoverIn); - curr.addEventListener('mouseenter', onHoverIn, true); - - curr.removeEventListener('mouseleave', onHoverOut); - curr.addEventListener('mouseleave', onHoverOut, true); - - curr.removeEventListener("touchstart", preventTouchHover); - curr.addEventListener("touchstart", preventTouchHover); - } - //initTapHoldMenus(curr); }; @@ -584,7 +322,7 @@ var selectedItems = []; function updateItemSelection(chkItemSelect, selected) { - var id = parentWithClass(chkItemSelect, 'card').getAttribute('data-itemid'); + var id = parentWithClass(chkItemSelect, 'card').getAttribute('data-id'); if (selected) { diff --git a/dashboard-ui/scripts/sections.js b/dashboard-ui/scripts/sections.js index dd18df413..3d074002c 100644 --- a/dashboard-ui/scripts/sections.js +++ b/dashboard-ui/scripts/sections.js @@ -111,7 +111,7 @@ icon = item.icon || icon; - html += ''; + html += ''; html += '
'; html += "
"; diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 62ef9b284..14b1ff714 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1804,6 +1804,7 @@ var AppInfo = {}; define("emby-collapse", [embyWebComponentsBowerPath + "/emby-collapse/emby-collapse"], returnFirstDependency); define("emby-button", [embyWebComponentsBowerPath + "/emby-button/emby-button"], returnFirstDependency); define("emby-itemscontainer", [embyWebComponentsBowerPath + "/emby-itemscontainer/emby-itemscontainer"], returnFirstDependency); + define("itemHoverMenu", [embyWebComponentsBowerPath + "/itemhovermenu/itemhovermenu"], returnFirstDependency); define("alphaPicker", [embyWebComponentsBowerPath + "/alphapicker/alphapicker"], returnFirstDependency); define("paper-icon-button-light", [embyWebComponentsBowerPath + "/emby-button/paper-icon-button-light"]); From 674a50ac18e5093a8d9e084e7ccf081f5e19e90a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 17 Jul 2016 23:33:35 -0400 Subject: [PATCH 09/10] fix recordings default action --- .../emby-webcomponents/shortcuts.js | 28 +++++++++++++++++++ dashboard-ui/scripts/livetvcomponents.js | 1 - 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js index a6a15f0da..56aeb0d7f 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js +++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js @@ -243,6 +243,33 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g else if (action == 'playmenu') { showPlayMenu(card, target); } + + else if (action == 'edit') { + getItem(target).then(function (item) { + editItem(item, serverId); + }); + } + } + + function editItem(item, serverId) { + + var apiClient = connectionManager.getApiClient(serverId); + + return new Promise(function (resolve, reject) { + + if (item.Type == 'Timer') { + require(['recordingEditor'], function (recordingEditor) { + + var serverId = apiClient.serverInfo().Id; + recordingEditor.show(item.Id, serverId).then(resolve, reject); + }); + } else { + require(['components/metadataeditor/metadataeditor'], function (metadataeditor) { + + metadataeditor.show(item.Id).then(resolve, reject); + }); + } + }); } function onRecordCommand(serverId, id, type, timerId, seriesTimerId) { @@ -322,6 +349,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } function onClick(e) { + var card = parentWithClass(e.target, 'itemAction'); if (card) { diff --git a/dashboard-ui/scripts/livetvcomponents.js b/dashboard-ui/scripts/livetvcomponents.js index 593e772b3..a310a19f9 100644 --- a/dashboard-ui/scripts/livetvcomponents.js +++ b/dashboard-ui/scripts/livetvcomponents.js @@ -89,7 +89,6 @@ showChannelName: true, lazy: true, cardLayout: true, - showDetailsMenu: true, defaultAction: 'edit' }); From c216a7ecdca5b91ff001f523d01ae98a17335e4e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 18 Jul 2016 00:22:03 -0400 Subject: [PATCH 10/10] update RegisterItem --- .../emby-webcomponents/itemhovermenu/itemhovermenu.css | 1 + dashboard-ui/scripts/librarylist.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css index 965a38acc..656ea2327 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css +++ b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.css @@ -40,6 +40,7 @@ .cardOverlayButtons .fab { background-color: #333; + margin-right: .25em; } @media all and (max-width: 1200px) { diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 3236b26da..5934b796b 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -1,4 +1,4 @@ -define(['appSettings', 'appStorage', 'libraryBrowser', 'apphost', 'itemHelper', 'mediaInfo'], function (appSettings, appStorage, LibraryBrowser, appHost, itemHelper, mediaInfo) { +define(['appSettings', 'appStorage', 'libraryBrowser', 'apphost', 'itemHelper'], function (appSettings, appStorage, LibraryBrowser, appHost, itemHelper) { function isClickable(target) {